01:47 colomon joined 06:43 FROGGS joined
nebuchadnezzar \o 06:53
nwc10 o/ 06:55
07:09 rurban_ joined
nebuchadnezzar the NQP .moarvm files are installed under /usr/share/nqp/lib/, so they are architecture independant files? I should have the same .moarvm files if I build nqp from amd64, i386 or armhf, right? 07:10
JimmyZ yes 07:11
nebuchadnezzar So I need to split the NQP Debian packaging more, with the .moarvm files and .jar in their own packages 07:13
nwc10 the files are architecture independant and the file reader in MoarVM is backwards compatible 07:20
so unlike what Parrot ended up with, newer MoarVM will (or it's a bug) run older files
(and newer NQP will build existing Rakudo. Unless there are real flag day changes, but that feels it would be a problem post Alpha) 07:21
IIRC packages for parrot, nqp and rakudo had to be in lockstep, with exact versions matching
certaily, moarvm is designed to be only a miminum version requirement
nebuchadnezzar thanks for the explanations, actually, it looks like any new NQP requires the latest MoarVM 07:22
nwc10 yes, that's usual
I meant the other way round
(sorry, wasn't clear)
with parrot, at least at one point 07:23
NQP 2014.03 would require parrot 2014.03
and parrot 2014.04 wouldn't load .pbc files written by parrot 2014.03
so if you upgraded parrot, you had to rebuild nqp
I don't know if that got fixed/improved later on
but there was certainly a time in the middle where it was that way, and annoying
07:24 brrt joined
nwc10 what I meant was, next month or 3 months from now, you can upgrade the MoarVM package 07:24
and the existing, built, NQP and Rakudo will be happy
(and if not, that's a bug that we'll address)
nebuchadnezzar ok, I understood the other way ;-) 07:25
07:26 zakharyas joined
brrt good * 07:28
timotimo: that's ok, it's not your job after all :-) 07:49
08:13 zakharyas joined 08:16 zakharyas joined
dalek arVM/even-moar-jit: 50279e7 | brrt++ | src/jit/ (3 files):
Implement initial tiler

Tiling is probably seperate from emitting code.
08:36
08:37 [Coke] joined, Util joined, japhb joined 10:49 colomon_ joined
timotimo brrt, but i've offered to do it and i'd be happy to see the jit advance more quickly ... :| 10:49
10:53 colomon joined
timotimo well, i parse op_to_func properly now, it seems 11:38
jnthn
.oO( parse that right now, the func op brother )
11:39
timotimo tee hee 11:40
pancakes! 11:43
jnthn envy!
arnsholt Indeed. I almost asked if they were the French kind or the American kind, but realized it doesn't really matter 11:55
12:12 brrt joined
brrt hai 12:13
what's the difference between french and american pancakes 12:15
timotimo++
timotimo american pancakes are much thicker and fluffy
brrt just cleaned up his apartment and recieved a new desk
timotimo oooh, a new desk 12:16
brrt as in, i got to use a desk that was unusable before
timotimo i just arranged getting new monitors
one of my current monitors is beginning to die
brrt also very nice
so you got a few to replace them?
i use only one monitor and find myself following the cursor by head movement, so i'm not sure i'd need multiple 12:17
timotimo "a few"? no, just two 12:18
two before, two after
i really appreciate having, for example, vim open on one monitor and some terminals on the other 12:19
and on my first workspace, i usually have a browser on the left screen and irc and IM on the other one
brrt HMM 12:20
oh oops caps
timotimo brrt: how would you represent the fact that we can only devirtualize reprops if a given fact is present for a given argument? 12:21
brrt not yet there
timotimo that won't fit into the file parse_jit_graph.p6 will generate, right?
brrt no, and it doesn't matter
timotimo good
brrt in fact, you can skip reprops as far as i care 12:22
or, maybe not
that makes it more difficult for you
no, my hypothesis was this
first generate the repr call as the full virtual call template
then, *if* you know off the type fact, you can replace the virtual-call-address-loading to a constant function pointer 12:23
in an optimization pass
timotimo ah, so instead of refering to the reprconv functions, we'll fully generate the *contents* of the reprconv functions
that'll make it totally amendable to constant folding
brrt aye
timotimo good
brrt constant folding is exactly what i mean 12:24
timotimo perfect
brrt although honesty forces me to declare that i'll probably only implement the skeleton of an optimizer for the JIT 12:25
timotimo that's no problem at all 12:26
that seems to be the kind of thing i enjoy doing :)
no guarantees, though
brrt oh, i know soo many things one can do
timotimo the infinities are possible! 12:27
brrt :-) 12:29
are you planning to go to yapc::eu this september?
timotimo no, i'll only attend SPW
brrt which i won't attend... shame 12:31
timotimo damn :|
brrt yeah 12:32
timotimo maybe i'll stay interested in perl6 even after its "public release" 12:33
and perhaps you will, as well
and then ... maybe ... one day
we'll meet
brrt :-)
it should be possible 12:37
timotimo do you suggest i immediately emit the full reprconv-inlined-tree format from jgb_consume_reprop? or should i start with emitting calls to the regular reprconv functions unconditionally for the time being? 12:38
reprops aren't really rare in jit code
brrt preferably the first, but i could imagine that to be hard
timotimo it would be sad if such common ops would cut up the optree-based jit pieces so regularly that the optree can't generate terribly good code 12:39
i can do it, but it may be super nice if you could at some point provide a template for the reprconv functions
in fact, if you could provide only two or three templates i can cargocult the rest of them
brrt well, for that case, i want to have a jit op for the type to generate a exprtree segment, or maybe just an exprtree template 12:40
oh, templates for reprconv virtual calls?
i was talking about directly inlining e.g. array access 12:41
which is possible, damnit
virtualized hardcoded jit templates
yes, i'll make one for you
which one do you want
timotimo let's see 12:42
brrt google calendar sends me to the mobile page with epiphany... many wow
timotimo give me MVM_repr_exists_pos, MVM_repr_at_pos_o, MVM_repr_bind_key_i and _n, MVM_repr_exists_key 12:43
that should get me very far
hm, the _attr_ functions will be interesting, too, but i suppose they can wait a little bit 12:44
since we turn attribute access into spesh'd direct access often-ish anyway
brrt aue 12:45
aye
ok, let me see
timotimo if the template looks the same as these functions with regards to their arguments, i'll be able to re-use the latter half of consume_reprop and just "call" the template instead of the reprconv function 12:47
brrt aye
jnthn Isn't the answer to "what's the difference between X and american Y" always "american Y are bigger"? :) 13:03
brrt huh, yeah
timotimo what's the difference between music and american music"? :) 13:04
nwc10 what's the difference between pints and American pints? 13:05
(also)
and I'm not convinced that the answer holds universally for "Beer" either
brrt american pints have high fructose corn syrup as their main ingredient 13:06
(if you want to make something evil in american, just add 'big' before it) 13:07
nwc10 big hug! 13:08
brrt fears
:-P
damnit 13:23
repr ops assume memory-to-memory
that's not compatible with my register-to-register model
timotimo ah, damn
[Coke] my favorite bartender always used to ask me if I wanted a 16 oz pint or a 20oz pint. :P 13:25
13:25 zakharyas joined
[Coke] (sad story - he semi-retired, opened a bar in our shared home town, which closed over a year ago, and he just died, apparently) 13:25
brrt i'm incapable of saying enough things to deter the use of imperial units
imperial units are a blight upon my working, or at least studying, existence 13:26
with the top of these all, the british thermal unit
what the hell
(that is a sad story, though :-o)
timotimo yeah :( 13:27
argh
all i want to do is swallow up some potentially curly blocks properly ... 13:28
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | curly_block
something says me i'm doing it wrong somehow
dalek arVM/even-moar-jit: 8904fef | brrt++ | src/jit/ (2 files):
Add elems reprop as an example for timotimo+
13:37
brrt ok, i can add the address of a writeable register as a parameter by default, or specially if it's a repr op 13:38
but at any rate it requires some special handling
timotimo that doesn't look terribly hard 13:43
but i agree the memort-to-memory vs register-to-register thing could be solved better :\
or "could be a problem"
brrt not hard, but i don't like special cases 13:44
huh
i think i know how to generic-case this
let me think about that a bit
bbiab 13:45
timotimo how will the jit learn about/discover functions supplied by a repr?
like, if there's a jit optree alternative for a REPR's elems function, for example 13:46
brrt by means of the example for spesh (src/6model/6model.h:593) 13:47
known type? known type can jit? get that template instead of the generic one
timotimo oh
fair enough
in that case we can't just rely on constant folding any more, though 13:48
for the reprop thing, i mean
if the reprop wants to supply a optree based version
13:56 zakharyas joined
dalek arVM: ef22a17 | timotimo++ | src/jit/graph.c:
this default case isn't supposed to be reachable

but in case it does get reached at some point, properly bail out of everything.
14:00
arVM: e313294 | timotimo++ | tools/parse_jitgraph.p6:
WIP on parsing jit/graph.c for conversion to optree
brrt no, but these cases are supplementary 14:21
timotimo fair enough i suppose?
brrt either you constant-fold the repr func to devirtualize, or you implement a repr-specific template 14:23
both are better than the naive case
timotimo mhm
i think i'm going to take some kind of break and look at the parsing stuff with a fresh set of eyes and brain :P 14:25
maybe i'll make the curly block skipping much dumber, so that it won't understand } inside /* */ or after //
brrt makes sense, yes 14:31
ok, let me specify the generic case
i can add a sigil of sorts, maybe !, to signify that 'this template includes a store' 14:32
if i do that, then i do *not* define the value there, it does not enter the tree as such 14:34
wait, wht
what
but i actually do not think that is a good generic case 14:35
better then to use the reprconv function and add it to the tree
dalek arVM: cf06824 | brrt++ | src/jit/graph.c:
Rethrow does not have a writeable register

And it's object is read from variable zero
14:50
brrt dinner &
timotimo time to golf 15:04
15:08 lizmat joined
timotimo my code is somewhat unhappy. i'll just make it much more simple and just require that no { } appear inside comments. 16:11
since i'm in full control of the source data anyway, that seems acceptable
16:23 rurban_ joined
timotimo i killed moar, but control isn't coming back to my shell :| 16:28
oh, it was merely waiting for input and didn't display the prompt promperly 16:30
17:03 lizmat joined 17:49 FROGGS joined 18:11 colomon joined 18:41 lizmat joined
timotimo before i dig back into the parsing thing, i'll have a quick look at the code gen thing you mentioned 19:02
ok 94 - Array elements have new values after assignment (2) 19:07
Cannot assign to a readonly variable or a value
jnthn: ^- this is expected and it's just a TODO on your list?
hm, that seems quite a bit earlier than potentially intended 19:08
19:09 colomon joined
jnthn Oh...I have a local patch to Rakudo to fix a place it was inconsistent with JVM... 19:09
Forgot about that...
timotimo ah, i see
jnthn haha, that means you're probably the first person to run the gist :)
timotimo ;(
sad-haha, in that case 19:10
jnthn
.oO( Did jnthn forget...OR WAS HE SNEAKY??? )
timotimo could ust as well be the case that everyone just ran the benchmark 19:12
jnthn That's also true
Or they noticed but didn't want to bother me :)
timotimo will the benchmark flush pull-one into my spesh log? 19:14
jnthn Sure
But 19:15
If you grab the one benchmark we lose and put it into the profile target
Then you can run just that
timotimo fair enough
oh, you told me to find the iterator of GLRmap, but the benchmark we're losing on is for GLRfor 19:20
jnthn I think that for does a map though? 19:21
timotimo it just grabs the iterable it's passed, which is an xx in this case 19:23
did i put the wrong piece of code into the profile sub?
well, the code tests properly now 19:31
19:38 colomon joined
timotimo so ... which pull-one exactly am i supposed to look out for? :S 19:43
jnthn timotimo: oh damn, yes... 19:45
timotimo: Actually one of the other benchmarks that does map is good 19:49
Even the simplest one
GLRfor(('beer' GLRxx 100000).GLRmap(*.uc), -> $beer { })
19:49 colomon joined
timotimo good 19:49
jnthn We do win that benchmark but...you can see in the profile we've room to win by a good bit more 19:50
timotimo i'll have a look at the profiler output, too 19:51
oops 19:54
i accidentally pasted the before rather than the after ...
jnthn "oh no, did jnthn REALLY have a long-running method called reify again?!" :) 19:55
timotimo more like "how the F did we end up with so many things from CORE.setting?!?" 19:56
but i can see how you'd say we have room for improvement 19:57
what with find-method
i seem tor ecall you were going "wtf, how do we find-method so much?!" recently
jnthn yeah 19:59
I didn't work that out yet
timotimo could it be the find-meth for sink? 20:05
that's the only one that could potentially surprise you :) 20:06
that frame has multiple findmeth of course. let's look in the post-spesh to see how many of them are still findmeth 20:07
and not sp_findmeth
yeah, the sink findmeth remains in the post-spesh code 20:08
jnthn I wonder what it's trying to sink... 20:09
That lacks a method cache
timotimo i'll have a closer look
it's $storage 20:11
jnthn o.O
timotimo i don't find any mention of '$!storage' or even 'storage' in the code
no, wait 20:12
this is about a hash
jnthn A...a hash?!
timotimo yeah 20:13
an nqp::hash gets created and assigned to something's $!storage
probably a high level hash in that case
then it tries to sink that
um 20:14
... sorry
i slipped into the totally wrong code object, it seems
excuse the noise 20:15
20:15 zakharyas joined
timotimo but the sink that goes on there is probably BS, too :P 20:20
seems to be $redo perhaps 20:21
more precisely:
getlexref gives us the lexicalref
later in the code, we try to sink the lexicalref 20:22
jnthn ouch
timotimo could the lexicalref be sufficiently dumb that we don't have a method cache published or something? 20:24
this could also be leading to lots and lots of things having a sink block generated for them all over the place? 20:25
i shall have a look at the code that decides whether or not to emit a .sink
and perhaps teach it about lexicalrefs
hm, there's a nosink annotation
jnthn I think p6sink is handled as a QAST -> MAST thing 20:27
And we could look there if it's a lexicalref
It'll be in, iirc, src/vm/moar/Perl6/Ops.nqp
timotimo hmm, okay 20:29
so something like if nqp::istype($op[0], QAST::Var) && $op[0].scope eq 'lexicalref'? 20:30
we have lexicalrefs of type object, too, and those will want sinking ... how do i best reach the variable it refers to to check what getlexref_* type is the right one? 20:31
i can't walk outward in the qast tree to find the block that holds the definitions 20:32
the $qastcomp likely knows 20:35
oh, perhaps $*BLOCK is set at that position and i can ask it 20:36
timotimo compiles a first attempt 20:39
it did compile, but it doesn't seem to reduce the amount of find_method happening 20:41
maybe there's a hllize op in between 20:53
===SORRY!===
Invalid frame outer index; cannot fixup
well, that's great!
(while building NativeCall)
i'm not readily stumbling over the p6sink that'd cause this problem :| 20:56
perhaps i've been barking up the wrong tree and this findmethod isn't related to the sink method call 21:00
timotimo just puts a note into find_method so that it spits out what methods it's looking fo 21:08
yeah, it does spam "sink" all over my screen for about a bazillion pages 21:10
jnthn: since the spesh output is ending up with the whole "if isconcrete + can 'sink' + callmethod 'sink'" dance, it's pretty much impossible that this is not going through p6sink, right? 21:13
jnthn timotimo: p6sink desugars into those instructions 21:15
timotimo yeah
jnthn timotimo: It's not a vM-level op
Oh, wait, I missed the "not" in "not going through" :)
timotimo and the other kind of sink is just 'put a method call for sink into the resulting code'?
:)
jnthn That changes everything!
Yeah
timotimo it's just that i put a $op[0].dump at the beginning of p6sink and i couldn't find anything that'd obviously cause $redo as a lexref to be sinken 21:16
have i looked wrong? pretty possible!
jnthn It maches the symptoms though...hmm 21:17
timotimo let me look again 21:18
yup, i put in an inc_i op that does nothing at all, and it shows up
and somehow the $sinkee_res must contain the getlexref_i thing 21:19
the word 'redo' doesn't appear in the output at all, but to be fair ,it crashes before it compiles all of the program 21:23
that could be it, though
must, actually
much better. 21:24
the only thing that p6sinks $redo is the while loop itself 21:27
- QAST::Op(while) 21:28
- QAST::Var(lexicalref $redo :decl()) $redo
while doesn't return the first child, right?
jnthn Um...forget what it returns
I think it has some logic to return something 21:29
But I don't think it's to spec
timotimo all we care about in this context is the QAST's returnchild or something? 21:30
jnthn Well, I think we do try and take care of returning something from while 21:31
but we should probably rip that stuff out
And have it return nqp::null
And maybe give it a :result option like the :nohandler one for HLLs to choose
timotimo ah, i see where that is 21:33
push_op(@loop_il, 'set', $res_reg, @comp_ops[0].result_reg);
in the "repeat" version, we set the $res_reg to a fitting variation of null
in the loop version, not so much 21:34
let's see ... 21:35
if the current return value of while is not to spec, and it's supposed to be null or 0 instead
maybe with that change in nqp spec tests will still pass?
jnthn Worth a try 21:37
And if they don't...we should look at those tests
timotimo do you want to hear a progress report?
jnthn Sure :) 21:38
timotimo how does "find_method is now only called 31 times in total" sound to you?
and pull-one is now at 48% exclusive time
anon at line 900 - the first inner block of GLRFor, the one with &block.count == 1 - is in second place with 25% exclusive time 21:40
gist.github.com/timo/647bba53b9820268558c - my benchmark results 21:41
time for that spec test
jnthn timotimo: Wow, nice :) 21:44
timotimo how much better are these benchmark results? i don't remember the previous ones 21:45
jnthn m: say 3.7 / 0.2
camelia rakudo-moar 5da323: OUTPUT«18.5␤»
jnthn m: say 3.7 / 0.21
camelia rakudo-moar 5da323: OUTPUT«17.619048␤»
jnthn That ratio is way better
I'll run mine
timotimo 18.5 is way better than 17.6, yeah
jnthn uh, no, those are both yours
timotimo oh 21:46
jnthn I wasn't fair in the first one, I didn't use same number of sig figs :)
timotimo ah, ok
jnthn m: say 4.3 / 0.62
camelia rakudo-moar 5da323: OUTPUT«6.935484␤»
jnthn That's before
timotimo are you serious.
jnthn So yeah, we're 17 times faster instead of 7 times faster thanks to your changes
Yes.
timotimo that's quite good
jnthn I knew that was going to be darn costly.
When I saw the profile
timotimo++
TimToady \o/ 21:47
timotimo spec tests aren't all that happy all in all
but i think it's all known problems
it'll be finished soon
jnthn wonder how you helped the others... :) 21:48
m: say 3.7 / 0.39
camelia rakudo-moar 5da323: OUTPUT«9.487179␤»
jnthn m: say 4.3 / 0.90 21:49
camelia rakudo-moar 5da323: OUTPUT«4.777778␤»
timotimo lock, start and io-socket-async are unhappy here
jnthn OK, so second to last one from 5 times faster to nearly 10 times
timotimo probably not because of while changing its return value semantics
jnthn No, those are flappy
timotimo cool, i'll clean up the patch and push
jnthn m: say 3.7 / 0.61 21:50
camelia rakudo-moar 5da323: OUTPUT«6.065574␤»
jnthn m: say 4.3 / 1.2
camelia rakudo-moar 5da323: OUTPUT«3.583333␤»
jnthn And that's improvement on the final one.
Nice! :)
timotimo how do i set an instruction list to have no return value? 21:51
or should i actually spit out the code to null a register that gets returned?
um ... there's an if $*IMM_ARG thing in there 21:52
i was pretty sure my patch would break it, but that's not what's used for while (^10).pick -> $a { ... }
it seems like a fossil 21:54
jnthn Right, the $*IMM_ARG is for -> 21:55
I think the thing you removed is fossil
timotimo i'm not so sure about that 21:57
#push_op(@loop_il, 'set', $res_reg, @comp_ops[0].result_reg);
this should be responsible for making the value "the right value" in front of the IMM_ARG thing
it used to $*IMM_ARG($res_reg), which is the register i just nulled prior to that 21:58
21:58 TEttinger joined
timotimo jnthn: IMM_ARG isn't mentioned in rakudo at all and in nqp there's only a single spot that actually does set it and it's in vm/parrot 22:02
jnthn timotimo: It's only set/used in the code-gen itself 22:03
timotimo: I'm surprised it leaks out of QAST -> POST tbh
(That is, that it shows up in Rakudo at all) 22:04
timotimo um, we might be thinking of different things right now
i'm talking about the implementation of nqp::while
it doesn't show up in rakudo at all, not even mentioned a single time in its whole source tree 22:05
jnthn I thought you were talking about the IMM_ARG thing?
timotimo yeah 22:06
well, look, there's another block at the top that seems to handle "needs_cond_passed" for @children[1]
that's completely separate from IMM_ARG
what i'm saying is, that the IMM_ARG mechanism in nqp's implementation of nqp::while probably hasn't been used for a while
jnthn oh, wow 22:07
Yeah, I see what you mean :)
Yes, that one mention looks fossil
timotimo phew
i thought i was going insane :)
jnthn timotimo++ # persistence :)
Sorry, I'm really tired... 22:08
timotimo so, currently our while loop implementation can handle returning "null-ish" values of all four kinds
apparently that comes from the condition
i'll kick out tthat part of the logic and just unconditionally return an object register that's nulled 22:09
jnthn Leave in the logic that doesn't do it if we want void, though. :)
timotimo if we wanted void so far, we'd've gotten an integer register instead 22:10
how can i find out if "the outside" wanted a void register?
likely some method on $qastcomp?
perhaps a dynamic variable like $*WANT? 22:11
right, that's it
jnthn See if/unless
It does
my $is_void := nqp::defined($*WANT) && $*WANT == $MVM_reg_void;
timotimo very good
jnthn timotimo++ # optimization through cruft removal :) 22:14
Sleepy time; night o/
timotimo :) 22:15
good night, jnthn
jnthn: this is my experiment with checking candidate size for inlining (rather than original bytecode size): gist.github.com/timo/83455292fe1f61a75fea 22:51
dalek arVM: fc18ccc | timotimo++ | src/spesh/inline.c:
spesh inline: check candidate size, not original size

oftentimes, small-ish pieces of code that are just above the max inline size before spesh become small enough to be inlined; a very short survey of example code reveals that an improvement in size of 2x isn't rare.
22:52
arVM: 853b08e | timotimo++ | tools/parse_jitgraph.p6:
more work on the jitgraph parser
timotimo darn, didn't mean to push the second WIP commit
oh well.
that change sadly doesn't cause &infix:«<» to be inlined in the beginning of pull-one :| 22:53
gist.github.com/timo/11512a307d720dd182e4 - with this patch applied, &infix:* doesn't show up at all :( 23:03
but interestingly, lots of places apparently try to inline a .new method into a .new method 23:04
potentially because we have no candidate that takes an obj first, then a native int register 23:06
(because our number $i is kept around as a lexref_i)
23:09 lizmat joined
timotimo and we're initializing the int $i with 0 before we grab $!i 23:09