void返回类型函数的尾调用优化

时间:2013-06-16 18:24:49

标签: optimization recursion

Tail会调用优化工作来递归调用返回void的函数吗?例如,我有一个函数, void fun()

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

这里编译器不会知道,调用fun()是最后一个语句。那么尾部调用优化仅针对返回某些值的函数进行吗?

1 个答案:

答案 0 :(得分:1)

答案是肯定的,它可以,但编译器没有义务这样做。它是否取决于功能,编译器和选定的优化级别。如果您对特定函数关注此问题,请查看特定编译器在特定优化级别生成的程序集。

更具体地说,GCC(至少是使用LLVM作为后端的Apple版本)将为至少一些在优化级别void或更好的情况下返回-O1的函数生成尾调用优化代码

一些测试代码:

/* 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);
}

通过最小化优化(-O1),编译到程序集(gcc -O1 -S test.c)会产生一个很好的尾调用优化函数:

_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

(注意:我已经删除了一些不必要的标签和对齐语句,这些语句会掩盖组件的结构。)

此外,当关闭优化(-O0)时,生成的代码是递归的(而不是尾调用优化)。