01:46
colomon joined
01:49
vendethiel joined
11:25
brrt joined
|
|||
brrt | good * | 11:25 | |
i have something approaching good news | 11:26 | ||
we're going to have a cool register allocation algorithm | |||
to be sure, the same register allocation algorithm as luajit has | |||
(linear scan register allocation. www.seas.gwu.edu/~hchoi/teaching/cs...arscan.pdf | 11:27 | ||
works Well Enough and is simple to implement, moreover can work inline | 11:28 | ||
all this comes for free with just one minor abstraction | |||
instead of the node number for first-and-last use, we assign compilation order numbers to DAG nodes | 11:29 | ||
the first and last compilation order number of the user forms a live range | |||
this also solves the problem of 'what values do we need to spill prior to a conditional or a function call' quite elegantly | 11:30 | ||
because the CALL or IF node is the last node to be numbered in this way | |||
and the answer to 'which values should be spilled' is simply 'all those values with a live range extending beyond the CALL node' | 11:32 | ||
clearly, that should happen in preorder order | |||
vendethiel | brrt++ :-) | 11:34 | |
brrt | there is one minor other problem.... i'm not 100% sure how up-propagate register requirements over conditionals | 11:35 | |
11:38
FROGGS_ joined
|
|||
masak | well, how does luajit do it? | 12:07 | |
brrt | actually, i don't know that for sure | 12:14 | |
what i do know is that luajit is not a good and easy source of inspiration | |||
luajit is quite convoluted code | |||
JimmyZ | you can't understand luajit well enough without debugging it ;) | 12:39 | |
brrt | i can imagine that | 12:40 | |
JimmyZ | well, the spesh stage of luajit is easier than jit stage | 12:43 | |
dalek | arVM/even-moar-jit: 2bcae41 | brrt++ | src/jit/ (8 files): WIP - Register allocation |
13:21 | |
13:21
brrt left
13:47
Ven joined
13:54
zakharyas joined
|
|||
FROGGS | o/ | 14:15 | |
timotimo | i might be able to turn at least half of graph.c into tree expression form today | 14:46 | |
14:59
colomon joined
16:19
colomon joined
17:38
zakharyas joined
18:28
Ven joined
18:31
TEttinger joined
18:50
Ven joined
19:05
Ven joined
19:10
Ven_ joined
19:14
brrt joined
|
|||
brrt | timotimo++ | 19:16 | |
19:27
brrt joined
19:50
ggoebel joined
|
|||
timotimo | brrt basically came over to ++ me? :S | 19:58 | |
brrt | yes | ||
because you said you could maybe convert the graph.c to exprlist format | 19:59 | ||
which tells me you've been busy with it | |||
which I greatly appreciate :-) | |||
timotimo | ah | 20:00 | |
oh, i didn't see you came back right after | |||
brrt | well, here i am | 20:01 | |
timotimo | right | 20:02 | |
my code structure is a bit weird, though | |||
brrt | as long as it works | 20:03 | |
20:03
Ven joined
|
|||
brrt | even if it'd worked only once | 20:03 | |
on a blue moon | 20:04 | ||
timotimo | yeah | ||
20:06
zakharyas joined
20:09
Ven joined
|
|||
timotimo | for making the resulting trees, i refer to a register with $operand-index-that-supplies-the-register? | 20:16 | |
20:16
brrt joined
|
|||
timotimo | seems right | 20:16 | |
brrt | my internet connection is extremely flaky today | 20:17 | |
timotimo | :( | ||
brrt | i probably missed something you just said :-) | ||
it's an effect of sitting in the train speeding home | 20:18 | ||
timotimo | 221518 timotimo ā for making the resulting trees, i refer to a register with | ||
ā $operand-index-that-supplies-the-register? | |||
brrt | therefore temporary | ||
yes, pretty much | |||
the idea is that those operands are marked as read-register usually | 20:19 | ||
typically | |||
timotimo | how do string indices look with regard to that? | ||
brrt | and in that case, the tree builder generates the load-register code for that operand | ||
well, a string index is a 32 bit constant, right? | |||
timotimo | what does our jit do with MVM_JIT_STR_IDX? | 20:20 | |
brrt | the tree builder also generates constant-value nodes for string index values | ||
timotimo | mhm | ||
brrt | lemmesee | ||
timotimo | right | ||
brrt | see src/jit/expr.c:L90 | 20:21 | |
timotimo | but how does it look in the expr template code i ought to emit? | 20:22 | |
brrt | the MVM_JIT_STR_IDX arg type loads the string literal pointer | ||
so we actually use a macro for that in core.expr | |||
timotimo | ah | ||
oh | |||
^cu_str | |||
^cu_string | |||
brrt | it'd look like (load (^cu_string $1) ptr_sz) | ||
timotimo | i missed that when i looked | ||
brrt | because the (^cu_string) gives you an address, not a value | 20:23 | |
basically exactly like the const_s template | |||
timotimo | right | ||
that makes sense | |||
brrt | :-) | 20:24 | |
timotimo | i was skipping almost all ops because i was expecting MVMint64 or MVMint32, but not MVMint16 | 20:40 | |
ugh | 20:43 | ||
since i can't keep this loop a postconditional, but i want to put "$line = @lines.shift" into the condition, i'm just going to unshift a copy of the last line i tried to match into the list before going on m) | 20:44 | ||
oh | 20:49 | ||
the carg for the end wants to know int vs ptr | |||
do i have an obligation to look at the instructions themselves to see what arguments are obj, str, num, int? | |||
i mean, num is signified with an _F always | 20:50 | ||
i hope brrt didn't fall off the 'net again :S | |||
brrt | still here | 20:51 | |
timotimo | great! | ||
brrt | no, you can infer it from the arg type | ||
num is indeed always signified by _F | |||
timotimo | oh, ptr is only for REG_ADDR? | 20:52 | |
brrt | no | ||
ptr is any ponter type, including strings | |||
timotimo | so obj and str registers? | ||
brrt | aye | ||
timotimo | how do i find out what it is? :) | 20:53 | |
brrt | REG_ADDR can only be compiled *iff* that argument is a write-to-register value, because only then does the tree builder generate the address rather than the load of the value | ||
you don't really have to worry about the difference tbh | 20:54 | ||
if you would really want to i guess you could parse oplist | |||
timotimo | OK, will i just always emit "int"? | ||
i don't have to parse oplint any more, we have a perl6 module that's generated from oplist | |||
brrt | that works for now. on x64, ints are always as large as ptrs | ||
oh, right | |||
well, that would be a good way to get the required information, methinks | 20:55 | ||
timotimo | mhm | ||
oh, look at that | |||
i already "use" that module anyway :) | |||
brrt | yeah, i think that may help | 20:57 | |
it's best practice to distinguish them. on ARM or other 32 bit archs, pointers are not 64 bits wide | |||
timotimo | thing is, i do multiple ops at the same time; let's just hope all ops that have the same piece of code have the same obj/str vs int vs num "form" :) | ||
brrt | hmm yes | 20:58 | |
timotimo | later on i want to have a distinguisher anyway to handle things like the ? : operator used in the array | ||
brrt | right | 21:00 | |
keep it simple for now | |||
it's not like i'm done with the register allocator anyway :-) | 21:01 | ||
timotimo | :) | 21:02 | |
brrt | although it's not that far off, either | ||
i'm wondering if using a heap actually makes sense | |||
it's elegant, but we have so few registers at any one time | |||
timotimo | ugh | 21:04 | |
my parser routine for the opcode to cfunc function seems broken | |||
brrt | :-( | 21:09 | |
c is maybe a bit hard to parse | |||
isn't there perhaps a cpan module for that | |||
timotimo | hah | 21:12 | |
i was going with a very naive approach | |||
it seemed to work well a few days ago | |||
oh, haha | |||
brrt | naive is ok | 21:14 | |
but i wonder how much memory you're currently using :-P | |||
timotimo | haha | 21:15 | |
Grammar::Tracer needs an "ignored_by_tracer" trait :S | 21:17 | ||
it's basically only lines of matched whitespace | |||
21:19
brrt1 joined
|
|||
brrt1 | very connect | 21:19 | |
many reliable | |||
grammar::tracer is a perl6 module? | 21:20 | ||
timotimo | yes | ||
now i've removed sigspace for a little bit of my grammar and the trace output became much more useful | 21:21 | ||
but only very slightly so :( | |||
i'll probably turn the whole-file grammar into a line-by-line thing instead | |||
brrt1 | hmmm | 21:22 | |
maybe that's a good idea | |||
good old fashioned perl5-style-parsing with regexes ^^ | |||
timotimo | ack! | 21:25 | |
someone must have changed the code to remove the '&' before all the function names | |||
that's what broke my naive grammar %) | |||
brrt1 | wait, what, why is there no ampersand? | 21:26 | |
timotimo | no need | 21:27 | |
brrt1 | really? | ||
and that's not a compiler warning on clang? | |||
timotimo | don't think so? | ||
i dunno | |||
[...]trify("MVM_coerce_smart_stringify"), :MVM_OP_sp_boolify_iter("MVM_iter_istrue"), :MVM_OP_splice("MVM_repr_pos_splice"), :MVM_OP_split("MVM_string_split"), :MVM_OP_sqrt_n("sqrt"), :MVM_OP_sub_I("MVM_bigint_sub"), :MVM_OP_substr_s("MVM_string_substring"), :MVM_OP_takeclosure("MVM_frame_takeclosure"), :MVM_OP_tan_n("tan"), :MVM_OP_tc("MVM_string_tc"), :MVM_OP_throwcatdyn("MVM_exception_throwcat"), | 21:28 | ||
:MVM_OP_throwcatlex("MVM_exception_throwcat"), :MVM_OP_throwcatlexotic("MVM_exception_throwcat"), :MVM_OP_throwdyn("MVM_exception_throwobj"), :MVM_OP_throwlex("MVM_exception_throwobj"), :MVM_OP_throwlexotic("MVM_exception_throwobj"), :MVM_OP_time_n("MVM_proc_time_n"), :MVM_OP_uc("MVM_string_uc"), :MVM_OP_unbox_i("MVM_repr_get_int"), :MVM_OP_unbox_n("MVM_repr_get_num"), :MVM_OP_unbox_s("MVM_repr_get_str"), | |||
:MVM_OP_unshift_i("MVM_repr_unshift_i"), :MVM_OP_unshift_n("MVM_repr_unshift_n"), :MVM_OP_unshift_o("MVM_repr_unshift_o"), :MVM_OP_unshift_s("MVM_repr_unshift_s"), :MVM_OP_usecapture("MVM_args_use_capture"), :MVM_OP_write_fhs("MVM_io_write_string"), :MVM_OP_wval("MVM_sc_get_sc_object"), :MVM_OP_wval_wide("MVM_sc_get_sc_object")}<> | |||
that looks better | |||
brrt1 | oh, nice! | ||
timotimo | (template: MVM_OP_prof_allocated | 21:29 | |
(call (^func MVM_profile_log_allocated) | |||
(arglist 2 | |||
(carg (tc) ptr) | |||
(carg $0 int) | |||
) ) ) | |||
(template: MVM_OP_radix_I | |||
(call (^func MVM_bigint_radix) | |||
(arglist 6 | |||
(carg (tc) ptr) | |||
(carg $1 int) | |||
(carg $2 int) | |||
(carg $3 int) | 21:30 | ||
(carg $4 int) | |||
(carg $5 int) | |||
) ) ) | |||
sometimes we don't seem to have an entry in the op_to_func, it seems | 21:31 | ||
brrt1 | hmm.. it may be that the & is not *really* necessary, but i do prefer it | 21:33 | |
maybe it's defined inline? | |||
timotimo | right | ||
hm? | |||
Use of uninitialized value %opcode_to_cfunc of type Any in string context in block at tools/parse_jitgraph.p6:177 | |||
this seems kinda wrong | |||
brrt1 | huh, yeah | 21:34 | |
timotimo | ah, i know | 21:35 | |
i had an array as the key and value of a Pair object | |||
only .list'd the value, not the key | 21:36 | ||
so i was looking for ops called, for example, "MVM_OP_foo_bar MVM_OP_bar_baz" | |||
brrt1 | right | 21:37 | |
brrt1 will disconnect in a few minutes | |||
21:38
brrt1 left
|
|||
timotimo | gist.github.com/timo/afb0413f1aead980a275 - you may like what you see here; sadly, gist put the interesting file last, the error output file first | 21:44 | |
hm, i may have to resend this when brrt comes back | |||
ah, "uint" trips it up currently | 21:49 | ||
i don't think it makes any difference, though | |||
huh | 21:55 | ||
sometimes the MVMJitCallArgs array starts like MVMJitCallArg args[] = { { MVM_JIT_INTERP_VAR, MVM_JIT_INTERP_TC }, | |||
MVMJitCallArg args[] = { { MVM_JIT_INTERP_VAR, { MVM_JIT_INTERP_TC } }, | |||
^- this is the format i expect | |||
timotimo uploads a new version | 21:59 | ||
gist.github.com/timo/afb0413f1aead980a275 - same url, but i thought i'd repost | 22:00 | ||
it doesn't handle adding a "void" at the end yet if the return value is void | 22:11 | ||
i surely need to care about num return types, too | 22:20 | ||
updated yet again | 22:33 | ||
where is brrt to cheer? :S | |||
i'm right in assuming that the rest of the jit compiler handles what the return value's destination register is supposed to be, yeah? | 22:38 | ||
dalek | arVM: 5011c98 | timotimo++ | src/jit/graph.c: make jit/graph.c a tiny bit more regular for the parser |
22:40 | |
arVM: 7dea708 | timotimo++ | tools/parse_jitgraph.p6: at long last, turn jit/grap.c into an expr tree (for the most part) |
|||
timotimo | in the end it was quite a bit easier than i had feared | 22:41 | |
dalek | arVM: 8d5ec6a | timotimo++ | tools/parse_jitgraph.p6: record more skips from different bail modes |
22:45 | |
timotimo | when there's a lit_i16, i'd use (const $1234 16), right? because int_sz is too big? | 23:06 | |
on the other hand, if it's a constant, doesn't make a difference if int_sz is bigger than what the const needs to get stored | 23:07 | ||
especially when we pass it as an arg to a c function | 23:08 | ||
hm. or maybe i have to use (copy $123)? probably. | |||
hm, but it is important for reading from the opcode, which is done before templates are interesting at all, right? | 23:10 | ||
so probably nothing to worry about when i'm already matching a template onto the tiled tree | |||
i'm apparently confused about what things are | 23:14 | ||
yeah, it'll be just like const_i16, which does a copy on the $123, so that's what i'll have to do, too | 23:15 | ||
dalek | arVM: 27dbca3 | timotimo++ | tools/parse_jitgraph.p6: tally succ/fail, factor out report_unhandled, ... ... handle literals, be more careful about INTERP_VAR (used to treat every INTERP_VAR like TC before), don't be flabbergasted when the jgb_append_call_c is spread across two lines. |
23:48 | |
arVM: ed6dda3 | timotimo++ | tools/parse_jitgraph.p6: handle the CU interp var, too. |
23:52 | ||
timotimo | i think i need a little macro for "args", which would be quite a bit like ^parg, but without the (idx ... ,a reg_sz) i imagine | 23:54 | |
oh, and also without the "load", because it wants to pass the pointer to the args object | |||
dalek | arVM/even-moar-jit: 598cd62 | timo++ | src/jit/core.expr: add ^args macro some C functions we may want to call will want a pointer to the args object of the current frame. |
23:56 | |
timotimo | oh, i think i want to get rid of the .params, too | 23:57 | |
and call it ^params instead of ^args |