| IRC logs at
Set by AlexDaniel on 12 June 2018.
Geth MoarVM: Kaiepi++ created pull request #881:
Fix tools/ on *BSD
Kaiepi MasterDuke how can i tell if the ops were jitted? 00:33
MasterDuke did you see BAILs because of them in the jit log before? 00:48
Kaiepi: if they were jitted, then there shouldn't be those BAILs after 00:49
Kaiepi ok 00:50
MasterDuke Kaiepi: what are you trying to jit? 00:51
Kaiepi i wanted to see if some of the io and file ops were jitable 00:59
it doesn't look like i can since none of the ops i used BAILed, but i found some other ones i can in the meantime 01:04
MasterDuke you can also look in src/jit/graph.c, if the op is listed somewhere in there it's probably already jitted 01:23
01:32 reportable6 left, reportable6 joined
Kaiepi how does it decide which ops can or can't be jitted? 01:45
MasterDuke if there's a case for them in src/jit/graph.c 01:59
Kaiepi: btw, you might find this useful
Kaiepi thanks 02:00
timotimo MasterDuke, Kaiepi, if you're talking primarily about exprjit templates, you'll want to search for "Cannot get template for:" 02:02
file i/o ops are a bit more interesting than others, because they are reprops, i.e. what code they end up calling depends on the REPR in question. jit/graph.c has code for that case that checks to see if the type of the target object is known to spesh and then you can get the function pointer directly from the REPR and emit a call to that 02:04
ah, actually, just looking at write_fhb, the file i/o ops do a bunch more stuff before they call into the virtual part 02:15
Geth MoarVM: 821cfd52b5 | (Ben Davies)++ | tools/
Fix tools/ on *BSD

  \s and \S aren't tokens in BSD regex.
MoarVM: 10f915d436 | (Samantha McVey)++ (committed using GitHub Web editor) | tools/
Merge pull request #881 from Kaiepi/tools

Fix tools/ on *BSD
04:53 timotimo left 05:36 lizmat joined 06:49 lizmat left 07:10 domidumont joined 07:17 domidumont left, domidumont joined 08:00 lizmat joined 08:27 Kaiepi left 08:30 Kaiepi joined 09:22 lizmat left 09:37 robertle left 09:45 domidumont left 11:34 stmuk joined
stmuk has anyone tried windows/clang? 11:35
12:05 zakharyas joined 12:29 zakharyas left 12:31 domidumont joined 13:08 timo joined 13:21 domidumont left 13:36 timo is now known as timotimo 14:03 lizmat joined 16:02 brrt joined
brrt good * #moarvm 16:02
timotimo sup brrt 16:05
brrt i'm going to merge samcvs jit templates in abit 16:06
Geth MoarVM/jit-moar-ops: f14f023044 | (Bart Wiegmans)++ | 2 files
[JIT] Implement ctxouter
MoarVM/jit-moar-ops: aa3c625b9b | (Bart Wiegmans)++ | src/jit/graph.c
Revert "Revert "[JIT] Implement throwpayloadlexcaller""

This reverts commit a607c42f1bbb4136b6c7c4c328f73ebe897fd9d8.
MoarVM/jit-moar-ops: eeb5228be5 | (Bart Wiegmans)++ | src/core/exceptions.c
[JIT] Change handler search to pass all handlers

I'll grumble about the logic another day, but I think there was a discrepancy with how the JIT did it, and how spesh did it, and that discrepancy should no longer exist now.
Does not fix the Inline::Perl5 bug though :-(
MoarVM/add-more-expr-ops: 6 commits pushed by (Samantha McVey)++ 16:15
16:38 brrt left 16:45 Kaiepi left 16:46 Kaiepi joined 16:47 brrt joined
brrt anyway, not sure if this has been discussed, but.. 16:58
we can potentially inline a tiny string (as in, 8 ascii bytes) into the space that points to a pointer in an MVMString
maybe even more if we count the coutners 16:59
timotimo yep! 17:00
i've thought about that in the past, i might even have a branch up that has an initial attempt
"in-situ-strings" 17:01
oh, only 7 month old 17:02
there's also mvmarray_in_situ_storage
brrt that would be pretty cool, actually 17:03
i mean, i could argue for allocating up to 16 chars in-situ easy 17:04
timotimo how'd you get the second 8 bytes? 17:06
you mean num_graphs will be subsumed by having the storage type be "in situ" and then we make it null-terminated? perhaps?
unless there's a null in the actual string, in which case we can't do that and fall back to a pointer? 17:07
brrt no, much simpler than that 17:08
if you're in-situ, num_strands is 0
and num_graphs fits in a byte
well, in 4 bits, even
timotimo ah, right 17:09
17:10 domidumont joined
timotimo feel free to steal the beginning of my branch and expand it a bit 17:11
it wasn't usable when i left it
at least i think it wasn't
brrt furthermore, even with in-situ strings (for byte-sized characters), we only have 5 (or 6?) string types anyway
so using a MVMuint16 for it is wasteful 17:12
timotimo yeah, the type fits into a few bits easy
well, if we used something else, it'd just be padding there instead
brrt depends on how you order things, but yes
timotimo also, in situ will still have to decide between 8bit signed/unsigned and 32bit
brrt i'm thinking of restricting it to ascii only 17:13
timotimo hmm
brrt with the hypothesis that even today ascii will be much more common than others
timotimo if we have 32bit in situ, we could store the result of chr for every value in an in-situ string. not sure how much that is worth
btw should we maybe rename ASCII to LATIN1 there? because i do believe we accept the first 255 unicode chars rather than just the first 127 17:14
brrt also, you can union the array with more than just the pointer size; if you do an in-situ allocation, you're also saving on the call for malloc() and free(), and you're saving the metadata that glibc uses for maintaining malloc() and free() 17:16
or whatever malloc() you're actually using
so if you union{} the pointers with a 16 byte array, arguably you'd still save memory 17:17
timotimo but MVMString itself gets allocated in the nursery and/or gen2 17:18
where we pack things much more tightly
brrt true, so the more reason to avoid using malloc() by using in-situ allocation :-)
also, if my reading is correct, type punning via unions is implementation-defined, not undefined behaviour is C, so we can do that safely 17:19
(it is undefined behaviour in C++, which is an excellent reason for me to avoid using C++ for MoarVM) 17:20
i'll take a look at the branch
timotimo we should check what exact size class MVMString falls into and if we have a bit of memory left at the end if we're in gen2 17:21
Geth MoarVM/master: 7 commits pushed by (Samantha McVey)++, (Bart Wiegmans)++ 17:22
brrt yeah :-)
re: char-of-MVMint32-in-situ: that's actually a really good point
timotimo how hard will it be to use "known type" from spesh in the exprjit optimizer soon-ish?
we don't use that at all right now, right? 17:23
brrt hmmm 17:25
not that hard, but i'm moving at it somewhat laterally
and, as I realized, maybe even inefficiently 17:26
timotimo oh, but if we know the type with something like iscont_*, spesh will already have turned it into a constant anyway
brrt yes
17:26 zakharyas joined
brrt and spesh is much better at analyzing cross-opcode relations anyway 17:26
the expr jit can do two things though:
timotimo except for stuff that's kind of "hidden away" from spesh
like "the first thing this op's implementation does is check the reprid" 17:27
like, we'd often have an existskey followed by an atkey or bindkey
brrt - it can easily generalize some optimizations (like 'read the function from the repr structure) if the repr structure is constant
timotimo there'll be a branch in between, but still...
brrt - it can 'blend' opcodes together and implement constant-folding accross them 17:28
(or other optimizations)
- we can produce specialized templates in a way that would probably not be practical as specialized opcodes for representations
timotimo yes 17:29
brrt the thing is, for that to work, I need to associate an expression tree node with a set of spesh facts
timotimo yeah
brrt restricted to just those facts that we can use without inserting guards (since we're too late in the pipeline to insert guards) 17:30
now, I have a structure called MVMJitExprNodeInfo which could hold that but it is a pain to maintain correctly during tree optimizations 17:31
timotimo mhm
brrt and also, it is only useful for operator nodes (not for links / constants)
and what information we do need can fit in a 32 bit value 17:32
and finally; the info on operator nodes we need always (like size and register-type) 17:33
whereas facts information we only need for nodes that directly correspond to an interpreter variable
timotimo mhm
brrt so what i want to do is create a struct for the operator nodes, and union that with the link nodes, and remove the separate info array entirely
and then, to use some lookup structure to associate spesh facts with nodes 17:34
and that doesn't need to be maintained together with the expr nodes themselves, which saves when we are manimpulating nodes in the optimizer 17:35
timotimo mhm
brrt makes sense?
timotimo i think so 17:36
brrt cool 17:43
re: in-situ strings, we can even get rid of the cached_hash_code, since if the string is small enough to live in-situ, recalculating the hash will be cheap 17:48
timotimo it'll be cheap if the code for hashing is still in memory 17:49
if not, it'll be an instruction cache hit that could have been prevented
brrt hmmm 17:50
okay, so we'd better measure that then
then again, in case we want to access that, good chance that code is in memory
17:56 brrt left 17:59 zakharyas left 18:00 zakharyas joined 18:04 lizmat left 18:46 domidumont left 19:52 Kaiepi left, Kaiepi joined 20:09 brrt joined 20:31 brrt left 21:03 zakharyas left 21:22 brrt joined
jnthn . 23:22
yoleaux 09:24Z <tyil> jnthn: would you have time to talk to me about something around 8PM paris time today?
brrt i'm guessing not :-)
jnthn Indeed :)
brrt: Is the expr JIT, at the MoarVM instruction level, effectively implementing the memory-to-memory model? 23:23
brrt ehm. can you rephrase that?
jnthn If we have something like
add r2(1), r1(1), r0(1) 23:24
mul r2(2), r2(1), r1(1)
And if that is the only use of r2(1), is it able to avoid writing it back into ->work?
brrt yes
jnthn Nice; how much further does that go, ooc? 23:25
Is it a kind of "all uses within the expression"?
brrt yes
well, the algorithm is actually super simple
Kaiepi do ops like this that throw need to be done in asm or can i still make expr jit templates for them? 23:27
brrt we process the instructions in code order. when we find an input operand that hasn't been used yet, we load it from memory (and it is associated by a 'template variable' like $1 or $2)
when an opcode defines a value (like add does for r2(1)), we keep the associated node in a lookup table 23:28
same goes for the 'autovivified' local values like r1(1) and r0(1)
when we then process mul, the r2(1) is looked up to be the result node of add; the r1(1) is the node already used for the add input operand 23:30
if that mul is the last write, then at the end of the basic block (currently), we insert the store to memory
plan is to delay that store indefinitely if possible
Kaiepi: that's totally possible in the expr JIT, although I'm not entirely sure if we can handle constant strings well yet 23:31
but that is a silly matter that i'm working to clean up
the expr tree IR itself uses a register-to-register model (all loads and stores are explicit) 23:32
jnthn: so your example would in practice become something like:
(let (($r0 (load (addr (work) 0))) ($r1 (load (addr (work) 8)))) (store (addr (work) 16) (mul (add $r0 $r1) $r1))) 23:34
(if you can read that ;-)) 23:35
anyway, i'm going to sleep now 23:38
speak you later
jnthn Thanks for explaining :)
Will read it and think about it some, though also probably after sleep :)
brrt hope it made any sense
jnthn But basically, this means the expr JIT has a pretty huge potential advantage here
So I should probably be writing expr jit templates for my new guards and stuff to get representative results. 23:39
23:43 brrt left