仅在GCC中启用尾调用优化

时间:2017-02-13 14:26:27

标签: c gcc tail-recursion

previous question中,我正在查看一个简单的代码示例,查看尾部调用优化。

针对这个问题,我遇到了GCC应用太多优化的问题,以演示本示例代码要显示的原则,并消除了循环/递归。

如何在启用尾调用优化的情况下让GCC编译,但尽可能少进行其他优化?

我目前正在尝试使用以下选项进行编译:

Selector selectorObject;
thrust::transform(results.begin(), results.end(), count.begin(), selectorObject);

有问题的递归函数是:

gcc -O0 -foptimize-sibling-calls -ftree-tail-merge tail_recursive.c -o tail_recursive.c.exe
gcc -S -O0 -foptimize-sibling-calls -ftree-tail-merge tail_recursive.c

由此产生的汇编程序是:

long recursive_tco(long loop, long current) {
  return (loop>0) ? recursive_tco(loop-1, current+1): current;
}

(注意它正在调用自己,而不是条件jmp,这是我期望的)

我没有哪些选项让gcc在不删除示例代码的情况下执行尾调用优化?

显然在实际代码中,我只启用 .globl recursive_tco .def recursive_tco; .scl 2; .type 32; .endef .seh_proc recursive_tco recursive_tco: pushq %rbp .seh_pushreg %rbp movq %rsp, %rbp .seh_setframe %rbp, 0 subq $32, %rsp .seh_stackalloc 32 .seh_endprologue movq %rcx, 16(%rbp) movq %rdx, 24(%rbp) cmpq $0, 16(%rbp) jle .L2 movq 24(%rbp), %rax leaq 1(%rax), %rdx movq 16(%rbp), %rax subq $1, %rax movq %rax, %rcx call recursive_tco jmp .L3 ,我更喜欢在C中编写循环而不是递归。

-O2

上的编译

编辑:

将功能更改为:

gcc version 4.9.3 (GCC)

在-O2:

处产生以下结果
__attribute__ ((noinline)) long recursive_tco(long loop, long current) {
  return (loop>0) ? recursive_tco(loop-1, current+1): current;
}

如果我正在阅读汇编程序,那么在使用recursive_tco: .seh_endprologue movq %rdx, %rax leaq (%rcx,%rdx), %rdx testq %rcx, %rcx cmovg %rdx, %rax ret 进行编译时,它似乎可以完成尾递归函数的工作:

gcc -O1 -foptimize-sibling-calls -ftree-tail-merge

不幸的是,它也在以类似的方式优化非尾递归函数,这不是我所期望的:

recursive_tco:
    .seh_endprologue
    movq    %rdx, %rax
    testq   %rcx, %rcx
    jle .L2
    movq    %rcx, %r8
.L3:
    subq    $1, %r8
    jne .L3
    leaq    (%rcx,%rax), %rax
.L2:
    rep ret

我希望还有一些进一步的优化,我需要提供一些额外的标志来禁用它们。有什么建议吗?

0 个答案:

没有答案