g ++ / gcc在展开递归内联函数时效果如何?

时间:2011-10-17 17:40:58

标签: gcc recursion profiling g++ stack-trace

我是递归但不是尾递归内联函数,我希望gcc能够展开递归。是的,我当然正在使用g++ -O3 -funroll-loops

inline void recurse_fun(..., unsigned depth = 0, unsigned max_depth = 40) {
    if (++depth > max_depth) return;
    for (auto i = ..., iend = ...; i != iend; i++) {
        if (...) continue;
        ...
        recurse_fun(...,depth,max_depth);
    }
}

我可以通过手动处理stack<...>对象来轻松替换它,gcc应该正确地展开,但它不会那么优雅或可维护。

无论如何我都应该尝试分析这两个版本,但我很好奇是否有人可以放心地说某些最近的gcc版本会或者不会正确处理这个版本。

1 个答案:

答案 0 :(得分:1)

GCC(至少最新版本如4.5或4.6)会展开一些尾递归调用。 当然,您需要让它进行优化(因此需要-O2-O3)。

要明白它在做什么,你可以

  • 请求gcc -O3 -fverbose-asm -S yoursource.c
  • 之类的汇编输出
  • 询问各种dump files,例如gcc -c -fdump-tree-all -fdump-ipa-all -O3 yoursource.c(还有其他转储文件)

请注意GCC会打印很多(数百个)转储文件。转储文件只是为了帮助GCC开发人员或GCC插件开发人员(或GCC MELT开发人员)。不要指望它们从GCC的一个版本到下一个版本保持相同的格式。

转储文件的编号是无用的:它不是按时间顺序排列的,也不符合逻辑。

转储选项可能会在下一个GCC版本中发生变化( 4.7 ,可能在2012年)