01:12
colomon joined
01:50
FROGGS_ joined
02:42
jimmyz joined
|
|||
jimmyz | Stage parse : 38.452 , yeah 1s lower | 02:42 | |
03:44
ventica joined
|
|||
sergot | hi o/ | 06:38 | |
06:44
brrt joined
|
|||
brrt | \o #moarvm | 06:51 | |
sergot | hi brrt | 06:54 | |
brrt | hi sergot | ||
hows your project going? i'm not often in #perl6 these days, so i don't see much of it | |||
07:02
zakharyas joined
|
|||
brrt | i've an evilly awesome idea on how to implement jumplist, btw | 07:11 | |
basically, create a segment containing a bunch of jumps after another | |||
so jmp label1; jmp label2; jmp label3; | |||
prefix that with a (local) label of its own | 07:12 | ||
before that, load the address of that label, and load the jump table index, multiply this by the size of a single jmp instruction | 07:15 | ||
add this to the start label, jump and presto | 07:16 | ||
only caveat - what if not all jumps are equal in size? | 07:26 | ||
moritz | then you make them equal in size (by extending smaller ones with no-ops) | 07:36 | |
07:38
klaas-janstol joined
|
|||
brrt | good point | 07:40 | |
but, i can't actually figure that out (what the size of a single instruction will be) | 07:44 | ||
much fuu | |||
moritz | why ever not? | 07:47 | |
brrt | because dynasm kindly hides that information | 07:48 | |
and it seems that a jump to a nearby target is a smaller than a jump to a far target | 07:49 | ||
hmm, that doesn't have to be so, though | |||
brrt may have a solution for that | |||
basically, a load-effective-address should be relatively constant in size, i'd expect? | |||
moritz | you could talk to the dynasm folks | ||
brrt | good point too | ||
moritz | maybe they have something for aligned jumps | 07:50 | |
(or would welcome patches :-) | |||
brrt | hmm that's not really it, i think | ||
oh wait i see what you mean | 07:51 | ||
:-) | |||
btw, i'm seeing something very interesting in the 'unofficial dynasm documentation' | 07:56 | ||
"If the presence of such a Lua interpreter cannot be assumed, LuaJIT2's minilua can be built and used to invoke dynasm.lua:" | |||
ok, /me will be adding that to the refactor-todo-list :-) | |||
also this: corsix.github.io/dynasm-doc/referen...tml#_align | 07:57 | ||
basically, instructions can be aligned to the maximum size necessary, i think | 08:00 | ||
08:01
Ven joined
|
|||
nwc10 | n: say 6.8598e+01 / 7.1820e+01 | 08:09 | |
camelia | niecza v24-109-g48a8de3: OUTPUTĀ«0.95513784461152873ā¤Ā» | ||
nwc10 | jnthn: whatever you did last night, setting compilation now takes 4.5% less time | ||
brrt | figurring out whatever that maximum size is supposed to be is tricky, though | 08:15 | |
i /think/ in all 'practical' examples it'll be 5 | 08:17 | ||
08:18
klaas-janstol joined
08:19
FROGGS joined
|
|||
brrt | so aligning to 8 bytes /should/ be safe | 08:20 | |
4 bytes for a relative memory address... lets' see if i can make that bigger | 08:23 | ||
really worst-case, 32 bit displacement gives me 7 bytes | 08:25 | ||
align 8 should be ok | |||
the only way to go over that, as far as i can tell, is to have 64 bit absolute displacements, and i'm pretty sure dynasm won't output these | 08:28 | ||
(those 7 bytes are, as far as i can tell, rex, jump, register nr, offset (4 bytes) | 08:29 | ||
btw, the case of the broken nqp compilation is getting curioser and curioser | 08:33 | ||
FROGGS | yeah, until it is fixed I suppose | 08:40 | |
brrt | hmm, found something maybe | 08:43 | |
ok, found something, probably | 08:44 | ||
FROGGS | O.o | ||
dalek | arVM/jit-moar-ops: 06d54a9 | (Bart Wiegmans)++ | src/jit/graph.c: Repr ID is literal, not register |
08:48 | |
brrt | fixed it :-D | ||
FROGGS | so what is next now? | 08:50 | |
is the iterator bug still present? | 08:51 | ||
brrt | NEIN NEIN NEIN NEIN NEIN | ||
iterator bug was really 'oh, i can't really compile and deal with handlers properly' bug | |||
fixing that, will be a bit complex, because it involves the old 'interpreter uses current bytecode offset as semantically valuable' issue for the JIT | 08:52 | ||
oh, great news, SEGV | 08:53 | ||
lets see what ASAN does shall we | |||
jit log bytecode is wrong | 08:55 | ||
that's funny | |||
not nearly as stressful as any of the other bugs | |||
oh, i apparantly haven't got a file handle | |||
FROGGS | I can send you one :o) | 08:56 | |
brrt | clang, i hate you now | ||
i told you not to f*****g optimize | |||
why are my frame variables gone | |||
why are they optimized out | |||
that's not a funny joke | |||
anyway, there's probably something illegal in the name | 08:58 | ||
hah hah, :infix</>.bin | |||
FROGGS | why is that illegal? | 09:05 | |
brrt | it contains a slash, so linux trys to make file in the directory ./jit-cuuid-$number-infix</ | 09:10 | |
which doesn't exists, hence a null file pointer, hence a crash | |||
(why don't you check for a null file pointer? well..... .:-$) | |||
FROGGS | ahhh | 09:11 | |
dalek | arVM/jit-moar-ops: c5f6a4d | (Bart Wiegmans)++ | src/jit/log.c: Check for NULL in MVM_jit_log_bytecode Sometimes, routine names contain special characters, such as slashes. Rather than dealing with that, I'll just as well not dump that bytecode. |
09:16 | |
brrt | i think i can merge that with moar-jit now | ||
because all the quick tests look as if they work | |||
i'm not, by the way, in total agreement with regards to the implmenentation of newlexotic, but i'll see what i can do about that | 09:17 | ||
dalek | Heuristic branch merge: pushed 34 commits to MoarVM/moar-jit by bdw | 09:18 | |
brrt | ok, bbi3h, i'll try to implement jumplist / jumptable, sp_findmeth and the like | 09:22 | |
nwc10 | brrt: 7d17cb0498aebe69d5e9b1d870604d2f39b09e90 didn't upset ASAN | 09:23 | |
will take less than 3 hours to tell you about the new one :-) | |||
brrt | very nice | ||
i'll see about that then | |||
brrt off | 09:24 | ||
also timotimo++ for so many commits | |||
09:24
brrt left
|
|||
nwc10 | brrt: ASAN still fine | 09:47 | |
jnthn | brrt++ # bug finding | 10:05 | |
FROGGS | jnthn: I found a but right now and wonder where to start investigating: rt.perl.org/Ticket/Display.html?id=122447 | 10:07 | |
jnthn | what what | ||
FROGGS | in the... | 10:08 | |
jnthn | What's weird. | ||
Though curious it happens consistently on JVM and Moar | 10:09 | ||
FROGGS | I just wonder what SCRef it is trying to serialize | ||
and I dunno how to check | 10:10 | ||
jnthn | Well, it's a reference to an SC | 10:11 | |
FROGGS | don't you say :P | ||
jnthn | But quite why we have one of those I don't know | ||
Well, or why we have one somewhere and try to serialize it | |||
You can detect it by looking at ->REPR->ID | 10:12 | ||
So I'd maybe just set a conditional breakpoint in the code that adds things to an SC and see what place adds the SCRef | |||
FROGGS | okay | 10:15 | |
dalek | arVM: e68fa51 | (Tobias Leich)++ | src/core/interp.c: fix op name in error message |
10:20 | |
FROGGS | hmm, so it seems we add only one SCRef to one of the SC's, and this are two lines of the bt: | 10:27 | |
at <unknown>:1 (/home/froggs/dev/nqp/install/languages/nqp/lib/QAST.moarvm:deserialization_code:4294967295) | |||
from gen/moar/stage2/QAST.nqp:4476 (/home/froggs/dev/nqp/install/languages/nqp/lib/QAST.moarvm:compile_node:253) | |||
jnthn | Yes, I meant breakpoint in the C code to see if comes from another object, or a lexpad, or whatever. | 10:28 | |
FROGGS | okay, running now until it hits the break | 10:31 | |
but I don't know how to check where it comes from | 10:32 | ||
ohh, do you mean by looking at the gdb backtrace? | |||
#0 MVM_sc_set_object at src/6model/sc.c:173 | 10:34 | ||
#1 MVM_sc_push_object at src/6model/sc.h:140 | |||
#2 write_obj_ref at src/6model/serialization.c:365 | |||
#3 write_ref_func at src/6model/serialization.c:628 | |||
#4 serialize at src/6model/reprs/P6opaque.c:1087 | |||
jnthn | Hm, seems the optimizer lost the interesting stack frames... | 10:40 | |
(between 3 and 4) | |||
FROGGS | here is the bt in full length: | 10:41 | |
gist.github.com/FROGGS/3bde10c30c9fe3c6723b | |||
jnthn | oh wait, I misread | ||
OK, it comes from a P6opaque | 10:42 | ||
FROGGS | yeah | ||
jnthn | That means somehow, some object we end up trying to serialize contains an SCRef | ||
FROGGS | and again I'd like to do $obj.VAR.name in C :o) | 10:43 | |
yeah: p *((MVMObject *)0x7ffff6782d40)->st->REPR shows: name = 0x7ffff7a235b5 "SCRef" | 10:45 | ||
jnthn | You could try finding where it's set by spotting it and dumping a backtrace in bind_attribute | 10:46 | |
You'd have to turn off spesh to make sure it doesn't do away with the bind_attribute calls though | 10:47 | ||
We should put it in to a Perl6::World (inherited from HLL::World) instance, for example | |||
10:56
colomon joined
|
|||
timotimo | brrt, *ouch*, the repr id pointed at a random register? yeah, that's bad. | 11:11 | |
FROGGS | jnthn: we do this: MVM_sc_set_object(tc, sc=0x7f9426e81d40, idx=810, obj=0x7f9426e81d40) | 11:14 | |
timotimo | but doesn't that just put an object into an sc? | 11:15 | |
FROGGS | yes, where the obj is the sc itself | ||
jnthn | OK, where does taht happen? | ||
FROGGS | bindattr_o o=0x7f9426e81d40 | ||
at <unknown>:1 (/home/froggs/dev/nqp/install/languages/nqp/lib/QASTNode.moarvm:sc:4294967295) | |||
from gen/moar/stage2/QASTNode.nqp:59 (/home/froggs/dev/nqp/install/languages/nqp/lib/QASTNode.moarvm:new:34) | |||
from src/Perl6/Actions.nqp:406 (/home/froggs/dev/nqp/install/languages/nqp/lib/Perl6/Actions.moarvm:comp_unit:1019) | |||
that is a bt called from bindattr_o where the _o has REPR->ID 17 | 11:16 | ||
which is our SC | |||
timotimo | oh, that seems weird | 11:18 | |
but i don't know how our scs work internally | |||
FROGGS | so $*W.sc() is exactly at that address | 11:20 | |
but I don't understand that... we are creating a $compunit..., how can that be on the same memory address as $*W.sc()? | 11:21 | ||
jnthn | Yeah, something is odd there | 11:22 | |
Wait, does that MVM_sc_set_object call happen as part of the bindattr (due to tripping an SC write barrier)? Or much, much later? | 11:23 | ||
timotimo | oh, the write barrier would be a sensible thing to do | 11:25 | |
FROGGS | I see two bindattr_o, one showing Perl6::Actions, the other one QAST.compile_node (identical to the sc_set_object) | ||
the P6::A comes first of course | 11:26 | ||
jnthn | Ah | ||
FROGGS | the latter and the sc_set_obj could be following each, but I cant tell | ||
jnthn | I was expecting a third one... | ||
Unless somehow Perl6::World is making it into the SC... | 11:27 | ||
FROGGS | there another one before Perl6::A that shows a different mem addres | ||
s | |||
coming from | |||
from gen/moar/stage2/NQPCORE.setting:514 (/home/froggs/dev/nqp/install/languages/nqp/lib/NQPCORE.setting.moarvm:BUILDALL:61) | |||
from gen/moar/stage2/NQPCORE.setting:499 (/home/froggs/dev/nqp/install/languages/nqp/lib/NQPCORE.setting.moarvm:bless:17) | |||
from gen/moar/stage2/NQPCORE.setting:560 (/home/froggs/dev/nqp/install/languages/nqp/lib/NQPCORE.setting.moarvm:new:10) | |||
from src/Perl6/Grammar.nqp:341 (/home/froggs/dev/nqp/install/languages/nqp/lib/Perl6/Grammar.moarvm:TOP:499) | |||
which is about creating our $*W | 11:28 | ||
12:14
klaas-janstol joined
12:18
brrt joined
|
|||
brrt | \o | 12:18 | |
jnthn | o/ brrt | 12:19 | |
brrt | we have no known bugs in the JIT :-) | ||
moritz | does that mean somebody fixed the iter weirdness? | 12:20 | |
\o/ | |||
nwc10 | write more tests | ||
brrt | jnthn++ found that the weirndess was caused by the frame having handlers, and /me not having implemented the code to deal with that | 12:22 | |
it is quite complex, though, so i'm trying not to feel bad | |||
FROGGS | jnthn: all three bindattr_o bind '$!sc' | ||
12:25
brother joined
|
|||
brrt | hmm jnthn, i have four things on my immediate to do list | 12:25 | |
FROGGS | okay, this first sc is $*W, then we bind $*W.sc() to probably $compunit, and then we bind the same $*W.sc() to something else in QAST.compile_node | ||
brrt | or rather, yesterdays todo list | ||
FROGGS | and the third seems to explode | ||
brrt | sp_findmeth, the jumplist thingy, proper implementation of throwish and handlers, and non-speshed args | 12:26 | |
oh, and extops of course | |||
jnthn | OK :) | 12:27 | |
Well, all matter. Given you just had some frustrating days of debugging, it may be nice to pick some that shouldn't be too horrible to do. | 12:28 | ||
brrt | handlers seem like the most complex of these | ||
jnthn | Right. | ||
brrt | jumplist is going to be fun, but i don't know if there are any non-regex tests | ||
jnthn | No, it shows up entirely in regexes. | ||
So far, at least. | 12:29 | ||
It tends to show up near the *end* of regexes too | |||
Meaning that if you're getting that far you'll likely get the rest of the way through the regex code. | |||
FROGGS | this is the '$!sc' #3: | 12:30 | |
$block.push(self.deserialization_code($cu.sc(), $cu.code_ref_blocks(), | |||
$cu.repo_conflict_resolver())); | |||
brrt | ok, but that's still pretty awesome | ||
brrt is collecting the core.setting jitlog | |||
FROGGS | jnthn: that means that I still don't know how the sc gets into its own attribute slot, right? | 12:47 | |
jnthn | FROGGS: Yeah, think something's missing still | ||
brrt | jnthn: jumplist nodes are always followed by a set of goto statements, right? | 12:56 | |
i.e. i can consume a jumplist + gotos as if it were a single node | |||
its current implementation seems to be: jump 6 * x bytes, after which we land on a goto, after which the goto will take us where we want to be | 12:58 | ||
jnthn | brrt: Correct, and there's a special case for non-match which I froget. | 12:59 | |
brrt: The bytecode verifier ensures that jumplist is followed by enough gotos | |||
brrt checks it out, and would easily forget it | 13:00 | ||
jnthn | brrt: So basically you can assume that's what you'll always have. | ||
brrt | ok | ||
the negative or greater-than-number-of-labels case, that... is inelegant | 13:03 | ||
jnthn | huh? | 13:06 | |
It's just saying "skip over all the gotos" | |||
brrt | oh.... | ||
/pfew/ | |||
that is implementable | 13:07 | ||
i read that wrong, i guess | |||
jnthn | /* skip the entire goto list block */ | ||
:) | |||
brrt | :-) | 13:10 | |
FROGGS | jnthn: compiled perl6-m with optimization turned off fails with: getlex: outer index out of range | ||
timotimo | i wonder where we have native nums we use in the setting compilation process | 13:14 | |
jnthn | "optimization"? | ||
timotimo | because eq_n is somewhat common (28 times) | ||
FROGGS | jnthn: I changed the Makefile so it reads: --optimize=off | ||
it fails building RESTRICTED.setting.moarvm then fwiw | |||
13:14
carlin_ joined,
lizmat_ joined
|
|||
jnthn | timotimo: NQP defaults to floating point for numbers in the absence of "int" decls | 13:14 | |
13:15
tadzik joined,
odc joined
13:16
TimToady joined
|
|||
brrt | don't the goto's all end a basic block? | 13:16 | |
timotimo | oh, i forgot about that | ||
13:16
xiaomiao joined
|
|||
brrt | nope, is handled as a special case | 13:19 | |
jnthn | Yes | ||
Every goto is in its own BB | |||
brrt | hmm ok | 13:20 | |
well, then, i'll have to walk bb's then :-) | |||
FROGGS | ohh dear... now I run into a spesh bug again >.< | 13:28 | |
"postcircumfix:<{ }> binding not defined for type Hash" at rakudo/src/core/CompUnitRepo/Local/File.pm:62: $potentials{$root}{$ext} := \($file, :name($root) ); | 13:29 | ||
lizmat | :-( | 13:30 | |
nwc10 | Every goto is sacred? www.youtube.com/watch?v=fUspLVStPbk | 13:31 | |
[not actually a rickroll, but maybe it should have been :-)] | |||
jnthn | FROGGS: Do you know it's a spesh bug? | 13:32 | |
I thought you already had this exact one before. | |||
13:34
FROGGS[mobile] joined
|
|||
brrt | every goto is sacred | 13:36 | |
oh what a horrible scene that is | 13:37 | ||
FROGGS[mobile] | jnthn: I had this before and it vanishes when spesh is disabled | 13:38 | |
it shows up know when I require a file from within v5 | 13:39 | ||
nwc10 | a rickroll looks like this: www.youtube.com/watch?v=dQw4w9WgXcQ | 13:40 | |
brrt | the horror of overpopulation, that is; thank god for demographic transition | ||
jnthn | FROGGS[mobile]: Yeah, but I thought I'd already fixed it :/ | 13:44 | |
brrt bbiab, errands & | 13:47 | ||
FROGGS[mobile] | jnthn: yes, that's why I cry | 14:04 | |
14:05
brrt joined
|
|||
brrt | ooh, it blows up swiftly | 14:16 | |
timotimo | that's a good sign :) | 14:19 | |
brrt | i suppose it is | ||
timotimo | "it" refers to jumplists? | 14:27 | |
brrt | yes | 14:29 | |
i suspect i jumped a little too far | |||
timotimo | if you think you're not progressing with jumplist, try something easier, like not_I, ne_s, lt/gt/le/ge_s and _n, ... :P | 14:30 | |
indexat, indexnat :) | 14:31 | ||
well, you have the list, too | |||
er, i meant not_i actually | |||
brrt | but jumplist is fun :-) | 14:32 | |
jnthn | And useful :) | ||
timotimo | fair enough :) | 14:33 | |
how far are we off from turning sufficiently simple given/when or if chains into jumplists? :P | |||
actually ... i don't think it'd even really be worth it at all | |||
in the if chain case | |||
jnthn | timotimo: I think that transform would go in the Perl 6 optimizer, and I don't see it as especially trivial | 14:48 | |
Also I don't know how much real code has it :) | 14:49 | ||
Forest fire kinda does... | |||
brrt | ehm, the regex graphs ends with a goto? wtf? that isn't right | 15:01 | |
jnthn | No, it's not right :) | 15:03 | |
The jumplist is one of the last things | |||
But not *the* last thing | |||
The fallthrogh does self.'!cursor_fail'() and return self, iirc | 15:04 | ||
brrt | there ought to be a return, at the very least | 15:05 | |
15:05
cognome joined
|
|||
jnthn | yeah | 15:05 | |
You've not nomming too many blocks as the goto blocks? | 15:06 | ||
15:43
oetiker left
16:21
brrt joined
16:37
ventica joined
17:14
Ven joined
17:52
brrt joined
|
|||
brrt | no, it appears not, i thought that might be the case but the spesh log agrees with the jit log | 17:54 | |
18:12
cognome joined,
cognominal joined
18:35
Ven joined
|
|||
brrt | aha, emit jump to label -1 | 18:57 | |
very interesting | |||
oh wait, that's nothing | |||
grrr | |||
jnthn | .oO( If the -1 is the root of the problem, it must be a complex problem... ) |
18:58 | |
[Coke] | jnthn: you're a dirty Rat. | ||
brrt | :-) | 19:01 | |
brrt enjoys the punning in #moarvm | |||
TimToady | i do two. | 19:20 | |
2i or not 2i, that is the question... | 19:21 | ||
brrt | but, it does seem at least that there's a 'negative label' assigned | 19:22 | |
TimToady | that doesn't square with y jnthn abcissas over 0... | 19:24 | |
-1 is obviously under 0 | |||
*abscissas | 19:25 | ||
in any case, it's in-ordinate... | 19:26 | ||
brrt | :-) | 19:28 | |
good news all, php has a spec :-) | |||
now we can implement php for moar | |||
TimToady | well, but they won't come unless we de-emphasize the link with Perl 6... | 19:29 | |
really, though, I'd think it would be much better to give them a refactoring translator to Perl 6... | 19:30 | ||
brrt | (how cool is it that we can nearly jit compile regexes, btw) | 19:35 | |
jnthn | Very :) | ||
OK, I'm done with $dayjob things until Monday :) | 19:36 | ||
Going to take a stroll, then will look at Rakudo/Moar things. :) | |||
brrt | see you then | 19:39 | |
brrt was going to swim but it's just a bit too dark outside | |||
btyler | brrt: that is extremely cool! I didn't realize that regexes were in scope for your JIT work...very exciting | 19:42 | |
brrt | neither did i, but the total lack of any regex-specific code in moarvm should have aroused my suspicion | 19:43 | |
and timotimo++ implemented most of the ops necessary, so that only the asm-level ops were necessary | |||
timotimo | aye, we compile regex to "just" moarvm bytecode | 19:46 | |
we just have a few ops that are especially useful in regexes as compared to everyday code, like "findcclass" and "findnotcclass" | 19:47 | ||
TimToady | not having a separate regex engine was something I insisted on from the very start | ||
the first time I mentioned it in a design meeting, I got blank looks all around | 19:48 | ||
timotimo | well, to be honest, the NFA thing is kind of separate | ||
but that part is not something you'd need to re-implement in jitted form | |||
it's quite a monolithic blob that you can just call through its interface and be fine | 19:49 | ||
19:49
Ven joined
|
|||
TimToady had way too much experience with inferior regex runloops in Perl 5 | 19:51 | ||
it wasn't a mistake I cared to repeat | 19:52 | ||
timotimo | how come we ended up with inferior runloops in parrot? | 19:53 | |
TimToady | alas, parrot kind of fell into nested runloops while I wasn't paying attention | ||
timotimo | ah | ||
TimToady | taking a year off for various stomach surgeries is kind of distracting that way... | 19:54 | |
timotimo | oh my :\ | 19:55 | |
TimToady | well, didn't take it off completely, but it was a year before my brane was fully up to snuff again | 19:56 | |
poor nutrition and multiple anesthesias will do that to you | 19:57 | ||
timotimo | i can only imagine | 20:00 | |
20:01
raiph joined
|
|||
TimToady | on top of which, they told me in no uncertain terms that I was the language designer, not the implementor, and they didn't want the internals of parrot to turn out like Perl 5 | 20:05 | |
so they ended up making the same mistakes differently, instead of making different mistakes | |||
well, they made some of those too, I suppose... :) | |||
required nap is required & | 20:06 | ||
masak | back when I learned about the "inferior runloop", I couldn't understand why when I Googled the term, I only got Parrot hits. | 20:20 | |
now I know. | |||
brrt | is parrot the only thing that ever did that? | 20:21 | |
jnthn back | 20:23 | ||
MoarVM does have some operations in its opset that are there with making regex interpretation/compilation efficient. | 20:24 | ||
*with the goal of | |||
But they're part of the same interpreter as everything else. | |||
20:36
Ven joined
|
|||
jnthn | Urgh, my problem last night is a spesh bug... | 20:42 | |
And it *looks* like it might be in optimizing isfalse | 20:43 | ||
oh...yeah. | 20:45 | ||
timotimo: About? | |||
timotimo -> Help -> About | 20:49 | ||
jnthn | timotimo: Well, think I found it... gist.github.com/jnthn/d202be34d80ad085cc71 | 20:52 | |
That patch helps, anyways. | 20:55 | ||
timotimo | that fixes what exactly? | 21:06 | |
jnthn | isfalse r0, r1 | ||
if r0 goto foo | |||
r1 was something with boolspec meaning we could lower it to isconcrete | |||
So it did that | 21:07 | ||
Then it said "oh, but isconcrete can be optimzied maybe" | |||
So that got optimized into an iconst op | |||
Then it added the not_i there and assigned back to the same reg (naughty) | |||
But the iconst op isconcrete had put there had a known value | 21:08 | ||
And the not_i was re-using the fact without flipping the known value. | |||
Then the if_i got optimized into a branch to the wrong place. :P | |||
While I'm quite please to see an isfalse/if get optimized into a goto, it's helpful if it goto's the correct branch :) | 21:09 | ||
*pleased | |||
timotimo | oh damn! | ||
that was a pretty nasty combination of things | |||
sorry about that | 21:10 | ||
jnthn | np | ||
timotimo | did that cause the Nil thing for xor? | ||
jnthn | No idea | ||
timotimo | i don't see a reason to not commit that, it sounds quite sane. | ||
jnthn | But it did cause CORE.setting compilation to explode with my patch that improves NQP optimization. | ||
Basically, regexes that called back into NQP code poisoned. | 21:11 | ||
I've changed that and now it can lower more lexicals and - even better - flatten away many nested blocks | |||
Which is enough to shave almost another second off stage parse here. | 21:12 | ||
timotimo | yus! | ||
jnthn | however, something bizzare happens. | ||
Stage optimize : WARNINGS: | |||
Useless use of "," in expression "my %m =\r\n '$*' => '^^ and $$',\r\n '$\"' => '.join() method',\r\n '$$' => '$*PID',\r\n '$(' | |||
timotimo | dear lord. rakudo-jvm is still going at i. | ||
jnthn | ... | ||
That's quite clearly not useless... | 21:13 | ||
timotimo | it's doing benchmark 31 of 63 now | ||
is , marked as pure or something? | |||
jnthn | yeah | 21:14 | |
But it's in an assignment which sure ain't | |||
timotimo | .. right | 21:15 | |
well, can you reproduce it with only that little statement? | |||
and get the --target=optimize and --target=ast? | |||
jnthn | WEll, it's in the entirelty of CORE.setting | ||
timotimo | of course it is %) | ||
jnthn | but I get spectest fails too that will give me more clues | ||
timotimo | aye | ||
FROGGS | lol, --target=ast on the setting :P | ||
timotimo | is jit-moar-ops being blocked from being merged ATM? | 21:16 | |
brrt | no, jit-moar-ops has been merge | 21:17 | |
d | |||
:-) | |||
jumplist is blocking-on-merged because? the code isn't even ever touched | 21:18 | ||
timotimo | oh, it has been? | ||
cool :) | |||
i'm glad my contributions were warmly accepted into the main jit development branch | 21:19 | ||
jnthn: clearly, the way it was before is wrong, so even if your patch introduces spectest failures, the previous state *has* to have been worse %) | 21:20 | ||
perhaps in much subtler ways | |||
er, wait | 21:21 | ||
that problem in the setting and spectests is not from fixing the not_i thing, it's from making the nqp optimizer in-line stuff more heavily | |||
jnthn | Right. | 21:22 | |
Oh, I know that. | |||
timotimo | will you commit & push the patch for isfalse? | ||
brrt is not gaining any insight from walking through the breaking frame | 21:25 | ||
jnthn | oh wtf, it's compiling a list assignment as an item assignment | 21:26 | |
timotimo: Can do | |||
Just trying to figure out the other thing... | |||
Ven | Error while compiling op bind: QAST::Block with cuid cuid_532_1406661053.31266 has not appeared | ||
uuuh. | |||
m: say so 'foobar' ~~ / foo ( A B C ) ** 0 bar /; | 21:27 | ||
camelia | rakudo-moar ccda7d: OUTPUTĀ«===SORRY!===ā¤Error while compiling op bind: QAST::Block with cuid cuid_1_1406842041.65097 has not appearedā¤Ā» | ||
dalek | arVM: b83a206 | jnthn++ | src/spesh/optimize.c: Update facts during isfalse optimization. We got the facts out of sync with the not_i insertion, meaning that a wrong branch could then result later. |
21:28 | |
timotimo | benchmark 37 out of 63 ... | 21:30 | |
jnthn | Arrgh | 21:32 | |
timotimo | good thing i started it on my desktop before i left home | 21:37 | |
rather than when i arrived here | |||
nqp-jvm is still ahead of us, though | |||
i may ctrl-c that, though | |||
dalek | arVM: b12cccd | jnthn++ | src/core/op (2 files): Cannot inline [get|bind]lexdyn. They do a tc->cur_frame->caller, which of course will look different if we were to inline them. |
21:44 | |
brrt | ugh, getwhat has an operands error | 21:51 | |
such dumb | |||
FROGGS | jnthn: your last patch might fix what I've seen earlier | ||
jnthn | FROGGS: Yeah, wroth a try | 21:52 | |
*worth | |||
We do have a problem with dynamics and spesh still though | |||
They're looked up by name | |||
And when we're searching for $*FOO we don't take into account lexicals declared in things we've inlined. | 21:53 | ||
FROGGS | ohh | ||
jnthn | Which I can fix quite easily for interpreted things. | 21:54 | |
Because I can use the current bytecode location/pointer to know where we are | |||
And then consider the appropriate inlines. | |||
But...JITted frames with inlines present more of a challenge. | |||
But I guess deopt_all must already handle this... | 21:55 | ||
brrt: Lemme know when I can borrow your brane for a moment :) | |||
brrt | borrow away | ||
but my bran is in the kitchen | |||
brrt hasn't read all the discussion yet | 21:57 | ||
jnthn | brrt: (How) is the deopt_all case of uninlining handled wrt JIT? | 21:58 | |
brrt | i haven't seen that yet | ||
jnthn | Or deopt_all in general I guess | ||
brrt | as far as i know, only rebless does deopt_all | ||
jnthn | Right | ||
But it has far-reaching consequences | |||
It deopts in place all frames down the stack | |||
brrt | hmmmm | ||
jnthn | When the JIT invokes something, what information does it keep around? | 21:59 | |
brrt | it uses a pointer called jit_entry_label | ||
jnthn | OK, that's used when we return? | ||
brrt | this is a direct address into the bytecode of the next instruction | ||
so it's the return_address of the JIT | |||
jnthn | Where bytecode = JITted machine code, yes? | 22:00 | |
brrt | yes | ||
jnthn | OK | ||
brrt | yes | ||
jnthn | That's not going to be quite enough for deopt_all I suspect | ||
brrt | no, but here's the thing more or less | ||
for regular invoke ops, there' always a mapping between basic block -> jit entry label | 22:01 | ||
regular invokes use so-called dynamic labels, but these aren't all that dynamic, they are 'linked' at compile time | |||
for invokish ops, which do not need to end at basic block boundaries, i use the address of local labels, and these are computed at runtime | |||
what you'd probably need - i assume - is to map the jit entry labels to the original moar bytecode somehow | 22:02 | ||
jnthn | Yeah | ||
Well | 22:03 | ||
What we actually need is to know is what inline we're inside, if any. | |||
brrt | if you can do that, you're golden; however for invokish ops i can't guarantee such a mapping, /unless/ this position can be computed at spesh-codegen time (or at annotation time) | ||
hmmm | 22:04 | ||
jnthn | Well, position can't, but inline index trivially can. | ||
brrt | yeah | ||
jnthn | (There's annotations) | ||
brrt | well, i can in principle add bookkeeping to the JIT so some kind of inlining index is updated whenever we move a boundary | 22:05 | |
jnthn | Yeah | ||
We probably need to do that | |||
It ties into the issue I'm about to fix now | |||
But given the machinary isn't there for the (more common) deopt_all goes, I'm not gonig to worry over it hugely yet | |||
But at present, deopt_all and a rare interaction between inlining and dynvars are going to be JIT issues. | 22:06 | ||
Just so you have them in mind when debugging. | |||
brrt | ok, but i don't think i do these yet | 22:08 | |
i'm perhaps a bit overly cautious | |||
oh, weird, 'invoke instruction isn't last of basic block or is last of graph', let's check that out | |||
jnthn | They're both sufficiently action-at-a-distance you can be easily bitten | ||
brrt nods with feeling | 22:09 | ||
it cautiously appears my evil jumplist scheme is working | 22:11 | ||
jnthn | :) | 22:13 | |
Dynvar lookups are sufficiently action-at-a-distance that I've just got bitten on the interaction of them with inlining. | |||
TimToady | btw, the Perl 4 compiler did the jumplist optimization on if/elsif/else, and in fact also did it on the first characters of strings if the matchers in each condition were anchored to ^ | 22:15 | |
jnthn | o.O | 22:16 | |
TimToady | in fact, it didn't even have to be if/elseif/else, it did it on any exclusive guards | 22:17 | |
well, if there were more than three or so | |||
in fact, I think it even handled character sets on the first character match (all ASCII semantics, of course) | 22:20 | ||
brrt | yep, there's a fastinvoke that's not the end of bb | ||
i'll get to that later | |||
(stage parse took even longer than normal now :-o) | 22:23 | ||
oh wait | |||
i'm logging spesh and jit logs | |||
jnthn | Yes, spesh_log alone can add a LOT | 22:25 | |
brrt | still 53s :-o | ||
:-( | |||
dalek | arVM/moar-jit: 7eb1b80 | (Bart Wiegmans)++ | src/jit/emit_x64.dasc: Fix bug in getwhat/getwho etc |
22:26 | |
arVM/moar-jit: 681b4ec | (Bart Wiegmans)++ | src/ (8 files): Add jumplist support. This is necessary for the compilation of most regexes. |
|||
brrt | oh, disabling jit makes no differense / 0.2 s slower | 22:27 | |
so | |||
that's not it, at least | |||
maybe computer is just slow today | |||
anyway, that was jumplist, hope you enjoy, will be here tomorrow for more epic bugfixing and maybe actually implementing some functionality | 22:28 | ||
/sarcasm-off | |||
:-) | |||
jnthn | :-) | ||
I'll give JIT a try tonight if I fix this other thing, or tomorrow morning. :) | 22:29 | ||
brrt | have fun :-) | ||
jnthn | :) | ||
brrt | sleep & | ||
jnthn | 'night o/ | ||
22:29
brrt left
|
|||
jnthn | Ah good, spectest is looking better with the fix | 22:43 | |
Made dynvar lookup more costly again to fix it though. | |||
Really gonna have to do something about that... | |||
dalek | arVM: 1fd42e6 | jnthn++ | src/core/frame.c: Account for inlining in dynlex lookup. |
22:46 | |
TimToady | well, we have ::= to indicate a readonly dynvar, which you can copy the value down instead of the container | 22:47 | |
m: my $x ::= 42; $x = 43 | 22:48 | ||
camelia | rakudo-moar 89c8e4: OUTPUTĀ«Cannot assign to an immutable valueā¤ in block at /tmp/X85viNoPuo:1ā¤ā¤Ā» | ||
jnthn | You can't copy the container down in the other case 'cus you might re-bind | ||
TimToady | maybe we can call that erroneous | 22:49 | |
jnthn | Well, the real time-consuming bit is that every time you do $*FOO, we go looking down the call stack to find it. | ||
TimToady | m: my $a = 42; my $x ::= $a; $x = 43 | ||
camelia | ( no output ) | ||
jnthn | Every. Single. Time. | ||
Just to figure out which frame declares it. | |||
TimToady | yes, that's why it's always been envisioned that it would be cached locally | ||
like env vars are, at least in unix | 22:50 | ||
jnthn | Sure. I've just been scribbling out a cache mechanism for it here. :) | ||
TimToady | it would appear that ::= is just doing := currently | ||
not defaulting $x to readonly | |||
jnthn | Yeah, we're cheating there at the moment. | 22:51 | |
TimToady | hmm | ||
jnthn | How does that work anyway? Just decont before binding? | ||
TimToady | m: constant $*foo = 42; | ||
camelia | rakudo-moar 89c8e4: OUTPUTĀ«===SORRY!=== Error while compiling /tmp/AP0smLPZaQā¤Twigil-Variable constants not yet implemented. Sorry. ā¤at /tmp/AP0smLPZaQ:1ā¤------> constant $*foo = 42ā;ā¤ expecting any of:ā¤ postfixā¤Ā» | ||
jnthn | Well, can't be decont if it's a $ sigil otherwise we'll screw up flattening | ||
TimToady | ::= is supposed to work exactly as it does in siggies | ||
jnthn | Has to work like param...right. :) | ||
And I already dealt with that issue there. | 22:52 | ||
TimToady | so same deal, basically | ||
jnthn | In my last profile of CORE.setting compilation, before the latest opt I have here, 1.8% of the time was on dynvar lookups. | ||
Which already sounds bad enough | |||
Except I suspect their cache consequences may be quite horrific too if you need to go deep to find the thing. | |||
TimToady | well, if something's cached halfway, you can stop there | 22:53 | |
jnthn | (as in, CPU cache) | ||
I'm thinking of just keeping a cache per thread | |||
TimToady | how bout just a local | ||
don't make a big datastructure | |||
jnthn | And marking frames we cache things from | ||
And when we return from those we just invalidate the cache entry. | 22:54 | ||
TimToady | returning throws away the locals | ||
jnthn | A local where, exactly? | ||
The problem isn't typically that we look them up in loops, at least not for the compiler | 22:55 | ||
TimToady | I mean a lexical; just install a my $*foo = caller's $*foo anywhere you think you need it | ||
jnthn | Oh, I was thinking of having the VM cache it | ||
TimToady | and it already will be found by the current lookup | ||
it'll just be closer | |||
timotimo | i'm now at benchmark 58 of 63 | ||
jnthn | That trick will show up if we introspect, though. | ||
TimToady | I don't think that matters much, and we can mark fake ones somehow | 22:56 | |
jnthn | Still means we need smarts on where to put them. | ||
And will also get re-binding wrong. | 22:57 | ||
TimToady is quite willing to forbid rebinding | |||
and, offhand, you can cache it where you noticed it's being used | |||
or just outside that, if it's a loop | 22:58 | ||
jnthn | I'm not convinced this solution wins us anything over the VM-level caching I'm proposing. | ||
We'll get most of them down to a single hash lookup | |||
TimToady | automatic cleanup | ||
jnthn | After the first time we look for it after declaration | ||
True. | |||
TimToady | it's how I pictured them from the start, anyway | 22:59 | |
jnthn | Said unwind stuff is in exactly one place, though... | ||
timotimo | should i backlog the recent hours? | ||
TimToady | well, I like how env vars just get copied into the current process | ||
and exit() cleans them up real quick :) | 23:00 | ||
jnthn | Sure. But to consider a concrete use case... | ||
$*ACTIONS | |||
It's declared and accessed in Cursor | |||
And barely mentioned in Perl6::Grammar | 23:01 | ||
$*W is used all the time in Perl6::Actions and never mentioend there | |||
It's really hard to insert the copies. | |||
In an effective way, I mean. Or to know what copies to insert. | |||
TimToady | nodnod | ||
jnthn | uh, never mentioned there wasn't quite right... | 23:02 | |
But it's hard to see how caching it at that level helps a lot when there's all the grammar frames below. | |||
TimToady | reserve one slot per frame for a cache maybe, and just cache it halfway, if unoccupied? | ||
jnthn | Hm, could work. | 23:03 | |
TimToady | so populate it stochastically? maybe occasionally remove them probabalistically to make room for mode shifts | ||
jnthn | Well, if the current frame you're on doesn't have a space for it, you can always look one down. | 23:04 | |
TimToady | various ways that it could improve things on average without too much cost | ||
yes, and if both of those are the same, steal one | |||
after all, they're *dynamic* :) | 23:09 |