Am Donnerstag, 14. September 2006 02:54 schrieb Karl Forner:
> Hello,
>
> So I propose a new implementation that solve the bugs, and that is linear
> in space and time, and hopefully produce
> an optimal list of moves. It is to be found in the second patch.

Great. Applied as r14621.

> We have two lists of registers, the src_regs[] and dest_regs[], that form a
> graph: src_regs[i] ==> dest_regs[i]

Please note:

- There are 2 use cases for register_move
  a) optimized recursive tail calls
  b) simple function call argument passing compiled to native code in JIT core

For a) {src,dest}_regs aren't register numbers, but just an index in the move 
list. While a function could have x 1000s of registers, a function call is 
limited to 255 arguments. This is currently the limit due to the usage of 
unsigned char (and there's no designer decision on that yet).

Anyway, a function call:

  foo(P2000, P3000, I5) 

would create

  src_regs := (0, 1, 2)

For b) it's either the same or (likely) HW register numbers (whatever is 
appropriate - it's not implemented yet) (see jit_set_args_pc())

> A same register may appear several times in the src regs, but only at most
> one time
> in the dest ones, because it makes no sense to assign two values to a same
> register.

While it doesn't make sense, we can't prevent users from coding such a 
function call. And worse: due to PMC registers any argument passing (with 
conversions) could have a side effect due to operator overloading or such.

This means that we just have to avoid these optimizations which are using 
register_move() in that case.

> To handle a cycle with exit, you do not need  a temp register.

Excellent.

> For instance, after a move(i -> j), j is now the backup of i.

This and the implementation assumes that now i and j have the same value. 
Again due to the nastiness of P registers and due to possible argument 
conversion, this isn't true in the general case. Again, while it doesn't make 
much sense, to create such recursive tailcalls with argument conversion 
to/from PMC registers, users might still code that.

Again, we have to check if any argument conversions could take place and then 
turn off the optimization in case.

> OPEN PROBLEMS
> ---------------------
> It is stated in the documentation that the mov_alt function should be tried
> before using a temp register

The idea of mov_alt is coming from the JIT code. src HW registers have a 
backup value in either a parrot registers or some call stack. The mov_alt 
code would produce an instruction like:

  mov 8[%ebp], %edx

> Suppose that you have a cycle 1 ==> 2 ==> 3 ==> 4
> If move_alt( 1 -> 2 ) fails, should we try move_alt( 2 -> 3) and move_alt(
> 3-> 4) too ?

It's not implemented yet, but I'd say, if mov_alt fails, a temp should be used 
always, and mov_alt shouldn't be tried again. It is likely true the other way 
too: if mov_alt succeeds for one register, it would always succeed for other 
registers too.

> So I hope that this work could prove useful, I would be very glad if I
> could help the development of parrot.

Very much appreciated.

> Regards,
>
> Karl Forner

Thanks,
leo

Reply via email to