Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why noreturn/__builtin_unreachable prevents tail call optimization

Tags:

c++

c

noreturn

I have come to fact that all major compilers will not do tail call optimization if a called function does not return (i.e. marked as _Noreturn/[[noreturn]] or there is a __builtin_unreachable() after the call). Is this an intended behavior and not a missed optimization, and if so why?

Example 1:

#ifndef __cplusplus
#define NORETURN _Noreturn
#else
#define NORETURN [[noreturn]]
#endif

void canret(void);
NORETURN void noret(void);

void foo(void) { canret(); }
void bar(void) { noret(); }

C: https://godbolt.org/z/pJfEe- C++: https://godbolt.org/z/-4c78K

Example 2:

#ifdef _MSC_VER
#define UNREACHABLE __assume(0)
#else
#define UNREACHABLE __builtin_unreachable()
#endif

void f(void);

void foo(void) { f(); }
void bar(void) { f(); UNREACHABLE; }

https://godbolt.org/z/PFhWKR

like image 243
Nikita Kniazev Avatar asked Apr 12 '19 17:04

Nikita Kniazev


People also ask

Does C++ support tail call optimization?

Tail call optimisation isn't in the C++ standard. Apparently, some compilers, including MS Visual Studio and GCC, do provide tail call optimisation under certain circumstances (when optimisations are enabled, obviously).

What is __ Builtin_unreachable?

The purpose of __builtin_unreachable is to help the compiler to: Remove dead code (that programmer knows will never be executed) Linearize the code by letting compiler know that the path is "cold" (similar effect is achieved by calling noreturn function)


Video Answer


1 Answers

It's intentional, though perhaps controversial since it can seriously harm stack usage properties; for this reason I've even resorted to tricking the compiler to think a function that can't return can. The reasoning is that many noreturn functions are abort-like (or even call abort), and that it's likely someone running a debugger wants to be able to see where the call happened from -- information which would be lost by a tail call.

Citations:

  • https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10837
  • https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56165
  • https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67327
  • etc.
like image 68
R.. GitHub STOP HELPING ICE Avatar answered Oct 18 '22 20:10

R.. GitHub STOP HELPING ICE