[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Optimizing tail-recursive operations using jumps
Consider the following calling pattern:
;0 Calling /' with arguments (<f <f 1>> <f <f <f -2<pp Y>>>>)
; 1 Calling // with arguments (<f <f 1>> <f <f <f -2<pp Y>>>>)
; 2 Calling /' with arguments (<f 1> <f <f -2<pp Y>>>)
; 3 Calling // with arguments (<f 1> <f <f -2<pp Y>>>)
; 4 Calling /' with arguments (1 <f -2<pp Y>>)
; 5 Calling // with arguments (<f 1> <f -2<pp Y>>)
; 5 Returned from // with values ((<f 1>) / (<f -2<pp Y>>))
; 4 Returned from /' with values ((<f 1>) / (<f -2<pp Y>>))
; 3 Returned from // with values ((<f 1>) / (<f -2<pp Y>>))
; 2 Returned from /' with values ((<f 1>) / (<f -2<pp Y>>))
; 1 Returned from // with values ((<f 1>) / (<f -2<pp Y>>))
;0 Returned from /' with values ((<f 1>) / (<f -2<pp Y>>))
/' is a procedure and // is an operation. Both are compiled, one calls
the other. It is apparent that every call is tail-recursive, since the
results on the way "back up" are unmodified.
Why not use continuations somehow to have a "REWRITE-CALL", similar to
a plain old JUMP, which passes arguments to a subprocedure, overwriting
the argument space on the stack for the calling procedure, such that
when the subprocedure returns, it returns to the caller of the caller?
Like DEFINE-INTEGRABLE, REWRITE-CALL would be an optimization that the
user applies intentionally when it is clear that the call is tail-recursive.
This seems like it would be pretty easy to implement, both for interpreted
and compiled code, in terms of continuations.
-- Lars Ericson