> We now have dedicated PMC* pointers in the context that hold > current_cont, current_sub, and current_object. This is necessary to > create traceback information. But subroutine and return opcodes are not > adapted yet. > > We have e.g.: > > invoke # implicitely P0 and use P1 for return > # could also be a method call > invoke P1 # likely a return > > The implicit usage of P0 in function and method calls is a PITA for the > register allocator, all this implicit usage causes special handling n > code, so that P0 gets properly tracked.
Special handling on both your end and the PIR programmers end. I found the implicit registers to be pretty confusing. > Additionally, P0 and especially P1 is first created in the callers > registers. This implies that the old contents of P1 has to be preserved > by copying to another register, Which Parakeet does in every sub it generates. > which increases pressure on the register > allocator. The same is done for P2 in method calls. This scheme just > reduces the usable register count by 3 in methods and by 2 in functions. > > To streamline that and take advantage of the current_* pointers in the > context, I'd like to adapt call/return ops slightly: > > invoke PSub, PRet # replaces implicit P0, P1 handling > invokecc PSub # replaces implicit invokecc [P0] > callmethod Pobj, Smeth, Pret # analog, no implicit S0 > callmethodcc Pobj, Smeth > ret_cc # replaces invoke P1 > > This gets rid of all hidden register semantics of these opcodes and > makes it explicit for the register allocator (and when reading the > code), which registers are used. As a minor improvement it also avoids > the "set P0, PSub" and such opcodes, to move the needed registers in place. Please! Myself being only a PIR user right now this makes so much more sense. Explicit is better than implicit. These objects are lying around in P registers or local vars anyway. This would remove several annoying contortions in Parakeet. This might be heretical, but I think you should change the unprototyped calling convention so that *all* of the arguments are in an array, not the first 11 in PMCs and the rest in an overflow array. Most unprototyped high level languages or reflection APIs are building their arguments dynamicly anyway. If one unprototyped language were to call into another unprototyped language, chances are it would build the argument list at runtime. Setting up registers is a PITA. Pass an array, it has a length, your done. > In the called subroutine P2 remains "self". But P0 and P1 (current sub > and continuation) are available only on demand, currently with the > interpinfo opcode. Maybe two opcodes for that are in order too: > > get_sub Px # simplifies coroutines > get_cc Px # simplifies call/cc and a get_self opcode. I see no reason why it or anything else should be implicit. -Michel