github.com/moarvm/moarvm | IRC logs at colabti.org/irclogger/irclogger_logs/moarvm Set by AlexDaniel on 12 June 2018. |
|||
Geth | MoarVM: Kaiepi++ created pull request #881: Fix tools/compare-oplist-interp-order.sh on *BSD |
00:03 | |
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 github.com/MoarVM/MoarVM/blob/mast...erview.org | |||
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/compare-oplist-interp-order.sh Fix tools/compare-oplist-interp-order.sh on *BSD \s and \S aren't tokens in BSD regex. |
04:15 | |
MoarVM: 10f915d436 | (Samantha McVey)++ (committed using GitHub Web editor) | tools/compare-oplist-interp-order.sh Merge pull request #881 from Kaiepi/tools Fix tools/compare-oplist-interp-order.sh 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 |
16:08 | |
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? hastebin.com/lorotowayi.rb | 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
|