Leopold Toetsch <[EMAIL PROTECTED]> writes:

> Piers Cawley <[EMAIL PROTECTED]> wrote:
>> Leopold Toetsch <[EMAIL PROTECTED]> writes:
>
> [ calculating registers to save ]
>
>>> ... once per sub per location where the sub is called from. But there
>>> isn't any knowledge that a sub might be called. So the cost is actually
>>> more per PMC instruction that might eventually run a PASM MMD. This is,
>>> when its done right, or ...
>
>> No. Once per compilation unit.
>
> An example:
>
>  .sub foo
>
>    # a lot of string handling code
>    # and some PMCs
>    $P0 = concat $P0, $S0            # <<< 1) calculate: save P, S here
>    # now a lot of float code
>    # no strings used any more
>    # and no branch back to 1)
>    $N1 = 47.11                      # $N1's live starts here
>    $P0 = $P1 + $N1                  # <<< 2) calculate: save P, N regs
>    $P2 = $P0 + $N1                  # <<< 3) calculate: save P regs
>    # no N reg used here
>  .end
>
> At 1) the caller is not interested in preserving N-registers, these
> aren't used there. Saving everything, the caller needs saving, ends up
> with C<saveall> in non trivial subroutines.
>
> Using your proposal would need a lot of storage for the saved
> register ranges.
>
> If the calculation is done based on the called subroutine, it's not
> unlikely that only a few registers have to be preserved, e.g. no
> N-registers for the overloaded C<concat> and no string registers for the
> overloaded C<add>.
>
> This doesn't violate the principle of caller saves: all that needs
> preserving from the caller's POV is preserved.

But under this scheme, the implementing function will have to do a
saveall for every function it calls because it doesn't know what
registers its caller cares about. And you're almost certainly going
to want to call other functions to do the heavy lifting for all the
usual reasons of code reuse. I can see a situation where you end up
with 

   .sub implementing_function
      saveall
      invokecc user_callable_implementing_function
      restoreall
      invoke P1
   .end

   .sub user_callable_implementing_function
      do_this(...)
      do_that(...)
      do_the_other(...)
      ...
   .end

simply because you want to follow good coding practice. You're right
that, in the limiting case, my 'fingerprinting' approach is going to
reduce to a saveall, but the example you give could be broken
up into 

   .sub foo
     $P0 = stringy_stuff($P0)
     ($P0, $P2) = floaty_stuff($P0)
     ...
   .end

which will simply need save P registers (and the called functions will
be able to arrange for efficient saves too...)

Reply via email to