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.
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 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.
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
leo
[calling convention change snippage]
I've already said no changes to the calling conventions, quite a
while ago. I don't see inconvenience in the register allocation code
as a reason to change it. Got a better reason?
--
Dan
--------------------------------------it's like this-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk
On Mon, 8 Nov 2004 13:23:36 -0500, Dan Sugalski <d...@sidhe.org> wrote:
> Okay, aesthetics and making up for a flaw in the implementation of
> how IMCC tracks opcodes and registers.
>
> Neither of those are sufficient, individually or together.
It feels to me like you are dismissing Leo's arguments a little too
lightly here. I find his logic fairly convincing...
Matt
--
"Computer Science is merely the post-Turing Decline of Formal Systems Theory."
-???
> [calling convention change snippage]
> I've already said no changes to the calling conventions, quite a
> while ago.
This doesn't really change calling convention, it changes call opcodes.
It makes register usage explicit.
> ... I don't see inconvenience in the register allocation code
> as a reason to change it. Got a better reason?
1) please grep -w invoke in imcc. There is quite an amount of code that
tracks register usage of this opcode.
2) I've outlined that the usage of especially P0 - P2 blocks registers
because we've to allocate them as non-volatiles too. This reduces
the usable register count by 3 for methods.
Current produced code looks like this:
set P16, P1 # preserve our return continuation
set P17, P2 # preserve self
set S0, "meth" # this method unavailable
set P2, obj
callmethodcc # call the meth P0 gets overwritten
set P1, P16 # restore P1
set P2, P17 # restore self
3) We have these variables in the context. Having them in registers too
just duplicates argument copying. It's not needed.
The return continuation works similar to the link register on PPC. There
are 2 opcodes to access this register. You can use it for branches...
Why should we have it additionally in P1, where it clutters the caller's
usage of P1 to be able to return?
leo
[snip]
>Ad 1) again a note: Imcc's instructions have *r[16] attached, a NULL
>terminated list of used registers/operands. This list doesn't have the
>length of the opcode's arguments because of such opcodes like invoke. The
>argument count of a plain C<invoke> is 0, but in r[0] a reference to P0
>is created to track the implicit usage of P0.
Okay, aesthetics and making up for a flaw in the implementation of
how IMCC tracks opcodes and registers.
Neither of those are sufficient, individually or together.
No, I'm not dismissing this stuff lightly. Leo's point to me earlier
is dead-ion correct -- screwing around with the design before
everything is specified and we have a working implementation is
premature optimization. And screwing around with stuff that works
when there's stuff that doesn't is misdirected effort.
The calling conventions and code surrounding them will *not* change
now. When all the sub stuff, and the things that depend on it, are
fully specified and implemented... *then* we can consider changes.
Until then, things stand the way they are.
Ah, OK. I was unclear, then. Sorry for the confusion.
It's so nice to see that any design element you don't approve of is
referred to in such glowing terms...
Regardless, now that this matter's closed it's time to get other
stuff going. Tail calls, for one.
> > Neither of those are sufficient, individually or together.
>
>Your code is spilling ... ;)
Well, duh. I've got a single sub with over a meg of source and 20k+
explicit temps. Of *course* it's going to make the register coloring
algorithm scream. While the coloring and spilling code needs help,
feeding it naively generated code is part of the problem.
> Dan~
>
> On Mon, 8 Nov 2004 13:45:08 -0500, Dan Sugalski <d...@sidhe.org> wrote:
>> The calling conventions and code surrounding them will *not* change
>> now. When all the sub stuff, and the things that depend on it, are
>> fully specified and implemented... *then* we can consider changes.
>> Until then, things stand the way they are.
>
> I missunderstood. I though you were saying that what is currently in
> is final and will *never* be changed. Thanks for the clarification.
Nevertheless, this is a legitimate topic for discussion, and the issues
are fresh in people's minds. That's independent of any impediments that
might block implementing changes at the current time.
JEff
I think it'd be a good idea to at least agree on a good TODO list, and
commit that to the bugtracker. Because it may turn out that some changes
are fine to delay, while some must be implemented now or never (because,
for example, a large ammount of compiler code will get broken because of
them).
Miro
While I won't stop any discussion, neither will I pay any attention
to it, so I'm not sure there's much point to it.