Benjamin Goldberg <[EMAIL PROTECTED]> writes: > Piers Cawley wrote: >> Benjamin Goldberg <[EMAIL PROTECTED]> writes: >> > Piers Cawley wrote: >> > [snip] >> >> Um... no. tail call optimization implies being able to replace *any* >> >> tail call, not just a recursive one with a simple goto. >> > [snip] >> > >> > In perl5, doing a tail call optimization can be done with just a simple >> > goto... well, 'goto &subname', anyway. (Well, first you'd assign >> > something to @_, then goto &subname). >> >> Ah... this discussion has been done in p5p and elsewhere; whilst goto >> &sub could, in theory, do tail call optimization, in practice it seems >> to be as slow as any other function call. > > Really? I did not know that. > > However, even if it's not significantly faster, at least it saves > memory, by discarding a level of saved stack information. > >> > Since (supposedly) there's going to be a perl5->parrot compiler, there >> > needs to be support for perl5's goto &subname. ISTM that once we have >> > figured out an efficient way of implementing that, we'll also have an >> > efficient way of doing native tail call optimization. >> > >> > As a wild-ass-guess, an optimized tail call will look something like: >> > >> > .sub _foo # sub foo(int a, int b) >> > saveall >> > .param int a # a = pop @_ >> > .param int b # b = pop @_ >> > ... >> > >> > .arg int x # push @_, x >> > .arg int u # push @_, u >> > .arg int q # push @_, q >> > restoreall >> > jnsr _bar # goto &_bar >> > .end >> > >> > .sub _bar # sub bar(int q, int u, int x) { >> > saveall >> > .param int q # q = pop @_ >> > .param int u # u = pop @_ >> > .param int x # x = pop @_ >> > ... >> > >> > .return int pl # push @_, pl >> > .return int ml # push @_, ml >> > restoreall >> > ret >> > .end >> > >> > The 'jnsr' opcode (JumpNoSaveReturn) might be spelled as 'j' or as >> > 'goto', or something else entirely, depending on what's least confusing, >> > and most aesthetically pleasing. >> >> The problem here is that you've pushed two loads of registers onto the >> register stack, and the return is only going to pop one set off. > > I think you're overlooking the "restoreall" done just before the > jump-no-save-returnaddress operation... I see two "saveall"s and > two "restoreall"s.
But with proper tail call optimization you'd only need *one* saveall. That's why it's an optimization. -- Piers