HomePhabricator

Always_inline codegen rewrite.

Description

Always_inline codegen rewrite.

Current implementation may end up emitting an undefined reference for
an "inline attribute((always_inline))" function by generating an
"available_externally alwaysinline" IR function for it and then failing to
inline all the calls. This happens when a call to such function is in dead
code. As the inliner is an SCC pass, it does not process dead code.

Libc++ relies on the compiler never emitting such undefined reference.

With this patch, we emit a pair of

  1. internal alwaysinline definition (called F.alwaysinline)

2a. A stub F() { musttail call F.alwaysinline }

  • or, depending on the linkage --

2b. A declaration of F.

The frontend ensures that F.inlinefunction is only used for direct
calls, and the stub is used for everything else (taking the address of
the function, really). Declaration (2b) is emitted in the case when
"inline" is meant for inlining only (like gnu_inline and some
other cases).

This approach, among other nice properties, ensures that alwaysinline
functions are always internal, making it impossible for a direct call
to such function to produce an undefined symbol reference.

This patch is based on ideas by Chandler Carruth and Richard Smith.

Details

Committed
eugenisSep 11 2015, 1:29 PM
Parents
rL247464: [MS ABI] Select an inheritance model in template arguments
Branches
Unknown
Tags
Unknown

Event Timeline

With this CL LLDB test TestInlinedFrame started to fail - http://lab.llvm.org:8011/builders/lldb-x86_64-ubuntu-14.04-cmake/builds/6189, we'use using Tot clang in this configuration.
Could you take a look into this issue - either fix it or revert the CL?

Yes, I'm reverting right now. It broke a similar test in the gdb test
suite as well.