Steve Fink <[EMAIL PROTECTED]> writes:
> I think this has been discussd before, but are we all okay with this
> callee-save-everything policy? At the very least, I'd be tempted to
> add a bitmasked saveall/restoreall pair to reduce the amount of cache
> thrashing. ("saveall 0b00100110111111110000000000000000") It just
> seems odd that you have to either save all 32 of one of the types of
> registers, or to save selected ones onto a different stack. But it
> *is* simpler to copy over the entire register file to a stack frame, I
> guess.
>
> Taking that farther, I've always liked systems that divide up the
> registers into callee-save, caller-save, and scratch (nobody-save?)
> Maybe that's just me. And I vaguelly recall that there was some
> discussion I didn't follow about how that interferes with tail-call
> optimization. (To me, "tail call optimization" == "replace recursive
> call with a goto to the end of the function preamble")

Um... no. tail call optimization implies being able to replace *any*
tail call, not just a recursive one with a simple goto. Consider the
following calling sequence:

  sub a { 
    b(arg);
    # Continuation A
    ...;
  }

  sub b {
    ...;
    c(different_arg);
    # Continuation B;
    c(another_arg);
  }

  sub c {
    ...
  }

We have three function calls here, b(arg), c(different_arg), and
c(another_arg).

Under caller saves, those calls look like the following:

   b(arg) -> Push Continuation A onto the continuation chain
             Setup the parameters
             Save anything important.
             Jump to B.

   c(different_arg) -> Push Continuation B onto the continuation chain
                       Setup the params
                       Save anything important
                       jump to C, C will return to continuation B

   at Continuation B
                    -> pop the continuation stack
                    -> restore saved params

   c(another_arg) -> Setup the params
                     jump to C, *C will return to continuation A*

Under caller saves, this is easy to do. Under callee saves, b's second
call to c() cannot simply return to Continuation A but must unwind the
call stack via b to make sure that the right things are restored.

Thinking about this still further, I'm not sure whether it's tail call
optimization or simply the presence of first class continuations that
makes callee saves an unwise proposition. 

Why do I have the feeling that I've managed to make this whole thing
even less clear now?

-- 
Piers

Reply via email to