<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Aug 20, 2015 at 5:19 PM, Evgenii Stepanov via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi,<br>
<br>
There is a problem with the handling of alwaysinline functions in<br>
Clang: they are not always inlined. AFAIK, this may only happen when<br>
the caller is in the dead code, but then we don't always successfully<br>
remove all dead code.<br>
<br>
Because of this, we may end up emitting an undefined reference</blockquote><div><br>Why would the failure to inline produced an undefined reference? Wouldn't we just keep the body around? The following example seems to demonstrate this<br><br><pre style="color:rgb(0,0,0)">void f1();
inline __attribute__((always_inline)) void f2() {
f1();
}
void (*f3())() {
return f2;
}</pre> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"> for an<br>
"inline __attribute__((always_inline))" function. Libc++ relies on the<br>
compiler never doing that - it has lots of functions in the headers<br>
marked this way and does _not_ export them from libc++.so.<br>
<br>
Current implementation in clang emits alwaysinline+inline functions as<br>
available_externally definitions. </blockquote><div><br>I heard this mentioned in another thread - and I'm not seeing that behavior. Is there an extra step missing necessary to produce that behavior?<br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">The inliner is an SCC pass, and as<br>
such it does not process unreachable functions at all. This means that<br>
AlwaysInliner may leave some alwaysinline functions not inlined. If<br>
such function has an available_externally linkage, it is not emitted<br>
into the binary, and all calls to it are emitted as undefined symbol<br>
references.<br>
<br>
Some time ago I've made an attempt to add a DCE pass before the<br>
AlwaysInliner pass to fix this. Thst<br>
(a) caused a big churn in the existing tests<br>
(b) must be done at -O0 as well, which is probably undesirable and<br>
could inflate compilation time<br>
(c) feels like patching over a bigger problem.<br>
<br>
The following, better, idea was suggested by Chandler Carruth and Richard Smith.<br>
<br>
Instead of emitting an available_externally definition for an<br>
alwaysinline function, we emit a pair of<br>
1. internal alwaysinline definition (let's call it F.inlinefunction -<br>
it demangles nicely)<br>
2a. A stub F() { musttail call F.inlinefunction }<br>
-- or --<br>
2b. A declaration of F.<br>
<br>
The frontend ensures that F.inlinefunction is only used for direct<br>
calls, and the stub is used for everything else (taking the address of<br>
the function, really). Declaration (2b) is emitted in the case when<br>
"inline" is meant for inlining only (like __gnu_inline__ and some<br>
other cases).<br>
<br>
This way has a number of useful properties that are easy to enforce.<br>
1. alwaysinline functions are always internal<br>
2. AlwaysInliner can be split from normal inliner; it would be a super<br>
simple implementation that would ensure that there are no alwaysinline<br>
functions remaining after it's done.<br>
3. alwaysinline functions must never reach backend and can be rejected<br>
before machine code generation (in SelectionDAG?).<br>
<br>
As this changes the semantics of alwaysinline attribute in the IR, we<br>
would need to reserve a new attribute ID, rename the current ID to<br>
legacy_alwaysinline or something similar and only enforce the above<br>
properties on the new attribute.<br>
<br>
There is a proposed Clang patch here: <a href="http://reviews.llvm.org/D12087" rel="noreferrer" target="_blank">http://reviews.llvm.org/D12087</a><br>
The patch only implements the Clang codegen part of the proposal and<br>
does not do any of the backend improvements.<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div><br></div></div>