Home > database >  GCC/Clang: disable tail recursion optimization for single function
GCC/Clang: disable tail recursion optimization for single function

Time:09-26

I understand I can disable tail recursion optimization in GCC with the option -fno-optimize-sibling-calls. However, it disables the optimization for the whole compilation unit.

Is there a way to disable the optimization for a single function?

It is my understanding that I can change the function so it's not a valid candidate for tail recursion - say, by using the return value in an expression so the return is not the last instruction in the function (e.g.: return f(n) 1;).

The solution above may still be optimizable, though, and future (or current, I don't know) versions of the compiler may be smart enough to make it into a tail call - say, by changing int f(i) { if(!i) return 0; return f(i - 1) 1; } into int f(i, r = 0) { if(!i) return r; return f(i - 1, r 1); }

I'm looking for a cleaner and future proof solution that doesn't require changing the algorithm, if at all possible.

Looking through the documentation I couldn't find a function attribute or built-in that does that, but my search hasn't been exhaustive.

CodePudding user response:

__attribute__((__optimize__("no-optimize-sibling-calls"))) appears to work on GCC.

Clang gives warning: unknown attribute '__optimize__' ignored.

CodePudding user response:

You may be able to use the GCC-specific #pragma optimize() directive (combined with suitable bracketing with push/pop #pragma lines) to achieve a result similar to specifying a function attribute:

#pragma GCC push_options // Save current options
#pragma GCC optimize ("no-optimize-sibling-calls")
int test(int i)
{
    if (i == 1) return 0;
    return i   test(i - 1);
}
#pragma GCC pop_options  // Restore saved options

int main()
{
    int i = 5;
    int j = test(i);
    return j;
}

But note that clang doesn't support this form of #pragma optimize. Also, note this warning from the manual:

Not every optimization option that starts with the -f prefix specified by the attribute necessarily has an effect on the function. The optimize attribute should be used for debugging purposes only. It is not suitable in production code.

  • Related