Optimizing tail calls for the void return function

Will there be a optimization of the Tail call for recursive calls to the function that returns void? For example, I have a function, void fun ()

void fun() { ... ... ... fun(); } 

Here, the compiler does not know that calling fun () is the last statement. So, is tail-tail optimization performed only for functions that return some value?

+4
source share
1 answer

The answer is that yes, it is possible, but the compiler is not required to do this. Regardless of whether it works or not, a lot depends on the function, the compiler and the chosen optimization level. If you are concerned about this function for a particular function, look at the assembly created by a particular compiler at a certain level of optimization.

To be more specific, GCC (at least the version of Apple using LLVM as the backend) will generate tail-optimized code for at least some functions that return void at the optimization level of -O1 or better.

Some test codes:

 /* Fills an array with a single value, recursively with side effects */ void fillarray(int val, int* curr, int* end) { if (curr==end) return; *curr = val; fillarray(val,curr+1,end); } 

With minimal optimization ( -O1 ), compiling to assembly ( gcc -O1 -S test.c ) creates a convenient optimized tail function:

 _fillarray: pushq %rbp movq %rsp, %rbp # set up the stack cmpq %rdx, %rsi # early exit if beg == end je LBB1_2 LBB1_1: movl %edi, (%rsi) # *curr = val addq $4, %rsi # curr++ cmpq %rsi, %rdx # TAIL CALL optimization is here jne LBB1_1 # if curr != end, go to LBB1_1 LBB1_2: popq %rbp # restore the stack and exit ret 

(Note: I edited some unnecessary labels and alignment instructions that hide the assembly structure).

In addition, when optimization is disabled ( -O0 ), the resulting code is recursive (not optimized with a callback).

+1
source

Source: https://habr.com/ru/post/1486499/


All Articles