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