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