On 9/15/06, Leopold Toetsch <[EMAIL PROTECTED]> wrote:

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)



So in that case ( a or b ?), the src_regs are always (0,1,2,..,n) ?
If so I'm sure that we can use this property to optimize the code.



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.


The problem is that I have no clue of JIT, registers and so on. But could
you give an example of code that would
lead to that case ?



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.



ok, so where would the check take place ?
I can imagine  an extra argument indicating whether or not doing this extra
optimization, or two different functions/implementations,
or more infomration about the registers  allowing the function to decide by
itself to do or not the optimization on a register-couple basis ....


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.


Ok, that's what the implementation does on a per cycle basis, meaning one
move_alt try by (disconnected) cycle.

It is likely true the other way
too: if mov_alt succeeds for one register, it would always succeed for
other
registers too.


ok, but I can't see how we could use this property.


So is there anything more I could do on this subject ?
Karl

Reply via email to