K Stol wrote:
The register stuff, I presume, is register allocation and the like? When targeting IMCC, you can use an infinite amount of registers. Just keep a counter in the code generator, each time a new register is needed, just increment the counter and add a "${S|N|I|P}" in front of it (example: $P1). IMCC does register allocation and spilling. So this is not really difficult.
Nono, the problem isn't that python uses *more* registers than <whatever>, but rather, that it doesn't use registers at all. Instead, it uses a stack. So, for example, python's add instruction might get translated into the following pir or pasm code:
restore P0 restore P1 clone P0, P0 add P0, P1 save P0
Needless to say, this is not efficient, due to how slow parrot's push and pop operations are.
Well, thats because you're trying to make a register machine act like a stack machine. It would be more efficient to translate add as:
$P2 = $P0 + $P1
That is to say, map stack positions to registers by simulating the stack while walking each op during translation time, rather than during runtime. So, in this case, the code that translates the add instruction might look something like:
translate_add_op { pop variable1 off of simulated stack pop variable2 off of simulated stack create new temp pmc push new temp_pmc onto simulated stack print temp_pmc's name print " = " print variable1's name print " + " print variable2's name }
So, after this code, our simulated stack is depleted by two items (the operands), and then replenished by one (the result); this makes it act exactly like the real stack, except that we are manipulating the registers rather than the values.
Hmm... If imcc is smart enough, (or perhaps I should say, when the flow control is simple/clear enough) it should be able to see when a value is pushed onto the stack, and later popped off, when there are enough registers free that we could have stored it in a spare register instead of on the stack. That is, a sort of register *un*spilling.
Doesn't IMCC already do this?
- Joe