Tail-call optimization (TCO) is a compiler optimization that allows for efficient use of procedure calls in the tail position. A procedure call is in tail position if it is the last thing to happen before returning. Without TCO, procedure calls use additional stack space, which can lead to stack overflows for deeply recursive functions. With TCO, the compiler can eliminate unused stack frames to avoid this problem. TCO allows problems to be solved efficiently using recursion by preventing stack overflows.
4. What does it mean for a procedure
call to be in tail position?
A procedure call is in tail position if it’s
the last thing to happen before
returning
5. int a = bar():
return a + 1;
}
Example 1
public static void foo1(){
6. int a = bar():
return a;
}
Example 2
public static void foo2(){
8. Call stack
Container for storing procedure calls
Grows upward
Last in, first out (LIFO)
Composed of stack frames
9.
10. Keeping with current analogies…
Each pancake represents some procedure to be
stepped through (some computation).
The plate represents boilerplate used by the runtime
system to return from procedures once they’ve run to
completion.
Boilerplate might consist of return addresses, formal
parameters, etc.
11. What’s in a stack frame?
Each stack frame is made of up of:
Some computation to run (a pancake)
Some boilerplate used for returning (a plate)
So our stack really looks more like this…
14. Fine-tuning the analogy…
Remember, we consider a pancake
some amount of computation/work that
needs to be performed before a
procedure can return.
So we would expect the pancake to
vary in size over the course of its lifetime.
19. Oh no, stack overflow!
Our stack has to exist in memory, so
it has a finite size.
If we have too many stack frames,
eventually we’ll run out of room
and get a stack overflow.
20. A solution approaches
If procedure calls are in tail position, we can
pop their remaining stack frame, since the
plate is all that’s left.
Since stack frames aren’t something the
programmer deals with explicitly, we let the
compiler take care of the details.
Thus we have tail call elimination/optimization.
(TCE/TCO)
23. Benefits of TCO
You can solve problems efficiently using
recursion.
You can make efficient use of function
calls within procedures.
More stack space means more room for
the procedures that aren’t able to make
use of tail calls.