While playing with JIT on Suns, I've found out that the following pasm code:
set I1, 2 LOOP: sub I1, 1 if I1, LOOP print "end\n" end
never finishes.. that is: parrot -j loop.pasm hangs forever (never printing 'end') while the non-jitted "parrot loop.pasm" prints 'end' and finishes there as expected.
Can anybody give me some hints as to what is going on there? :) Thanks, Stephane
PS.: placing a 'print I1' within the loop resolves the problem, both jitted and non jitted finishing properly in that case. Instead 'noop', 'set <some>' or else within the loop dont help the jitted case and hangs again..
Stephane Peiry <steph...@modxml.org> wrote: > While playing with JIT on Suns, I've found out that the following pasm code: > set I1, 2 > LOOP: sub I1, 1 > if I1, LOOP > print "end\n" > end > never finishes.. that is: parrot -j loop.pasm hangs forever (never printing > 'end') while the non-jitted "parrot loop.pasm" prints 'end' and finishes > there as expected.
I don't know suns JIT code nor the assembler syntax, but it seems that the two subcc lines are broken:
On Fri, Feb 13, 2004 at 10:48:09AM +0100, Leopold Toetsch wrote: > I don't know suns JIT code nor the assembler syntax, but it seems that > the two subcc lines are broken:
This would actually compare, say I1, to itself, and would then always be equal. So as I understand it, the line is ok: the subcc_r lines build these "synthetic" instructions where a compare is
Since <if> compares reg to 0 (as the not jitted core does), it uses register %g0 (for reg_or_imm) which contains 0 (%g0 is actually a special register in sparc always containing 0 no matter how - its just "constant 0"). Hence we have
Somehow I thaught that the problem could lie in the "optimize" section? Is there any simple way to disable that for jit? (it seems quite hardwired atm). Also, whats a good way to debug jit? meanning, I'm able to step through and see what is going on with gdb while still in "parrot itself" so to speak, but as soon as it jumps in jit.. its just a sort of blackbox.
> > PS.: placing a 'print I1' within the loop resolves the problem,
> That could clear g(0) ...
As said %g0 is just always 0, the only thing is that this one kind of "jumps out of jit"?
Stephane Peiry <steph...@modxml.org> wrote: > On Sat, Feb 14, 2004 at 02:35:02PM +0100, Leopold Toetsch wrote: >> docs/debug.pod /jit > saw that one, but jit doesn't generate a .o file under sparc?
Calling Parrot_jit_debug() is enabled for __GNUC__ and __IBMC__. If your system doesn't define one of these, try adding a define.
If that runs and it works you get a stabs file (for parrot -d -j). This is compiled via an hardcoded line with "as". s. jit_debug.c
$ parrot -d -j t.imc $ l *stabs* -rw-r--r-- 1 lt users 8891 Feb 14 18:17 t.stabs.s
On Sat, Feb 14, 2004 at 06:19:42PM +0100, Leopold Toetsch wrote: > If that runs and it works you get a stabs file (for parrot -d -j). This is > compiled via an hardcoded line with "as". s. jit_debug.c
mh ok, I do get the stabs file, and apparently the reason no objfile gets created is that "as" complains with loads of warnings and some errors when given the stab file.
Attached is an example stab file generated for a very simple pasm, and the warnings/errors "as" complains about when feeded with it.. mainly hopping that you can spot the problem? :)
Stephane Peiry <steph...@modxml.org> wrote: > mh ok, I do get the stabs file, and apparently the reason no objfile gets > created is that "as" complains with loads of warnings and some errors when > given the stab file.
I see. Your libc's sprintf seems to be missing the "0x" prefix for the "%p" format. Can you verfy that with a small test:
On Mon, Feb 16, 2004 at 09:08:55AM +0100, Leopold Toetsch wrote: > I see. Your libc's sprintf seems to be missing the "0x" prefix for the > "%p" format.
Ok you were right, that fixed it immediatly, and I'm now able to see "within jit" :). Attached are the dumps for this loop, with and without the print in between.
Looking at it makes it pretty clear why it loops forever (mainly it jumps back to a load, loading always the same value). Somehow it relates to the way these "jit sections" are built afaik, but still do have to dig more and understand better its works.
(if there are any hints/pointers, they are greatly appreciated ;) Thanks again for the help, Stephane
PS.: apoligize for the delay in answering back.
Also concerning fixing the debug part, I kind of prefer your second option (using Parrot_sprintf) since as I understand it its meant to avoid platform specific quirks?
> Looking at it makes it pretty clear why it loops forever (mainly > it jumps back to a load, loading always the same value).
Yep. That's a bit complicated. The jit code tries to avoid loading/storing the same register from/to memory. This is achieved by remembering the size of the register loads (load_size) and setting fixup->skip accordingly. When now a branch goes to the same section (a backward branch like in mops.pasm), then the load should be skipped.
jit/i386/jit_emit.h implements all the necessary bits. s. jit_emit_jcc, fixup->skip and load_size.
On Mon, Feb 23, 2004 at 11:07:48AM +0100, Leopold Toetsch wrote: > Yep. That's a bit complicated. The jit code tries to avoid > loading/storing the same register from/to memory.
Actually on this, while looking at what jit on i386 would give for this particular loop, just noticed it does quite a lot of these store/loads to memory who are, afaik, useless? (althaugh as I understand they are needed for the general case)
0x0829c5ed <jit_func+53>: mov $0x2,%ebx 0x0829c5f2 <jit_func+58>: mov %esi,%esi 0x0829c5f4 <jit_func+60>: mov %ebx,0x8278c74 0x0829c5fa <jit_func+66>: mov 0x8278c74,%ebx 0x0829c600 <jit_func+72>: sub $0x1,%ebx 0x0829c606 <jit_func+78>: test %ebx,%ebx 0x0829c608 <jit_func+80>: jne 0x829c600 <jit_func+72>
(up here we could just skeep 58 to 66)
> jit/i386/jit_emit.h implements all the necessary bits. > s. jit_emit_jcc, fixup->skip and load_size.
Thanks.. was going "round in loops" ;) I'll go on it as time permits.
Stephane Peiry <steph...@modxml.org> wrote: > On Mon, Feb 23, 2004 at 11:07:48AM +0100, Leopold Toetsch wrote: >> Yep. That's a bit complicated. The jit code tries to avoid >> loading/storing the same register from/to memory. > Actually on this, while looking at what jit on i386 would give for this > particular loop, just noticed it does quite a lot of these store/loads to > memory who are, afaik, useless? (althaugh as I understand they are needed > for the general case)
Yes. The problem are of course branches and branch targets. Before a branch there is a store and on a branch target is a load (the register assignment CPU-reg <-> Parrot-reg can and will differ in different basic blocks).
So there may be unneeded store/load sequences. I tried (with some success) to avoid such sequences with imcc/jit.c, but that is currently unusable due to register renumbering with PCC.
> 0x0829c5ed <jit_func+53>: mov $0x2,%ebx > 0x0829c5f2 <jit_func+58>: mov %esi,%esi > 0x0829c5f4 <jit_func+60>: mov %ebx,0x8278c74 > 0x0829c5fa <jit_func+66>: mov 0x8278c74,%ebx > 0x0829c600 <jit_func+72>: sub $0x1,%ebx > 0x0829c606 <jit_func+78>: test %ebx,%ebx > 0x0829c608 <jit_func+80>: jne 0x829c600 <jit_func+72> > (up here we could just skeep 58 to 66)
No. mov %esi, %esi is a nop to align the branch target. And the load on the branch target can't be omitted either (or only if you know that the only brach comes from a place, where registers match. But - the loop itself doesn't do any load/stores so that's fine.