#Tail Call Optimization Requirements.

1 messages · Page 1 of 1 (latest)

winter tendon
#

I am parsing some lists in a way which uses recursion and looks like it could benefit from TCO, that is it would be the final call in the function when its called. My concern however (this does not seem clear from the docs) is that it might not be the final instruction listed in the call, just the final instruction WHEN its called:

I am concerned with problems along this line:

        // given the subsequent line(s), is the following allowed?
        if (some-exception) { return @call(.always_tail, clone_list_inner, .{self, cursor, n}) }

        // given the existance of the else branch, is the following allowed?
        if (next) |n| { return @call(.always_tail, clone_list_inner, .{self, cursor, n}) }
        else {
          // other code here...
          // does this prohibit the above?
        }

In all cases when the tail call is called, its the final thing being executed and its returning its value. But its not the final statement, as other brnaches may take it in another direction, and i assume there will be generated IR after it.

shy hawk
#

it just has to be the final statement in control flow, not textually

#

the way TCO is that it replaces the curren't function's stack frame with the called function's

#

so the value of the arguments, the result pointer, stack trace, etc, are replaced with the tail-called function's, instead of allocating more space

#

only thing I imagine it has to retain is the return address

#

hence the requirement that the calling function and the tail-called function have equivalent signatures

winter tendon
#

awesome! I was reading some of the open issues and saw the mentions of undefined behavior rather than a compiler error in the self hosted compiler, which lead me to some IR stuff that had me concerned.

shy hawk
#

yeah

#

it should probably be obligatory for tail calls to be the return expression

#

but that's details for the core team to worry about and fix

winter tendon
#

yeah, im trying to only use it when it clealy should work (ie the stack frame is obviously reusable)

shy hawk
#

the only rule is: after a tail call, continuing control flow in the calling function is undefined behaviour

#

also, defers are a bit finnicky

winter tendon
#

can you elaborate on that?

shy hawk
#

I recall having trouble with them and tail calls

winter tendon
#

because this is actually about list cloning and list freeing, and at least the cloning one uses errdefer

shy hawk
#

well, this was a year ago

#

it's likely improved and been fixed

#

but I suggest thoroughly checking the behaviour

winter tendon
#

yeah, ill keep an eye on the edge case at least

shy hawk
#

// Here be dragons

winter tendon
#

heh everywhere be dragons, but you gotta get to them for comptime