Piers Cawley <[EMAIL PROTECTED]> wrote:
> Okay, I'm confused, I thought that the whole point of a caller saves,
> continuation passing regime was that the caller only saves what it's
> interested in using after the function returns.

We don't have a problem WRT register preservation, the problem arises
due to register re-using.

> ... Exactly *where* that
> return happens, and whether it happens more than once, is completely
> irrelevant from the point of view of the caller.

The return can only happen, where the normal function call would have
returned, but anyway.

> ... ISTM that the register
> allocator should work on the principle that anything it didn't save
> before it made the call will be toast afterwards.

Yes. But - please remember your example "Fun with nondeterministic searches".
Here's the relevant piece of code from main:

   arr1=[1,3,5]
   arr2=[1,5,9]
   x = choose(arr1)
   y = choose(arr2)
   $P0 = find_lex "fail"
   $P0()

You know, both "choose" calls capture the continuation and backtrack via
"fail" (basically). But the register allocator isn't aware of that. The
control flow graph (CFG) is linear top down, with new basic blocks
starting after each function call. "arr2" is obviously used around a
call and allocated in the preserved (non-volatile) register area. This
works fine.

Now the register allocator assigns a register to "$P0". It finds the
register that "arr2" had usable, because in a linear CFG, there's no way
that "arr2" might be used again. So that register is considered being
available. Now if $P0 happens to get the register that "arr2" had,
backtracking through the call to "fail()" obviously fails, as "arr2" is
now the Closure PMC. And that was exactly the case.

> Or am I missing something fundamental?

I don't know ;) It's basically a problem of the interpretation of the term
"caller saves". The first call to "choose" preserves "arr2", but then -
seen from the CFG - the register allocator has no clue that "arr2" is
needed again.

leo

Reply via email to