<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Aug 17, 2015 at 11:07 AM, Evgeniy Stepanov via cfe-commits <span dir="ltr"><<a href="mailto:cfe-commits@lists.llvm.org" target="_blank">cfe-commits@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">eugenis created this revision.<br>
eugenis added reviewers: chandlerc, rsmith.<br>
eugenis added a subscriber: cfe-commits.<br>
eugenis set the repository for this revision to rL LLVM.<br>
<br>
Currently always_inline definitions are emitted as (in most cases) an available_externally llvm function with an alwaysinline attribute. </blockquote><div><br>Naive dude missing some context here: How can that ^ be correct? <br><br>A basic test case doesn't seem to indicate that that's the case:<br><br>__attribute__((always_inline)) void f1() { }<br>void f2() { f1(); }<br><br>Compile with LLVM optimizations disabled, etc - the bitcode has no mention of available_externally in it... <br><br> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">This is not exactly right: always_inline functions are NOT available externally, and, for example, libc++ uses this semantics to preserve ABI stability.<br>
<br>
Emitting an undefined symbol for an always_inline function is always a bug. The current code can still do it in certain cases.<br>
 a. Inliner is an SCC pass. It traverses the graph starting from the roots, which are either main() function, or all externally-visible functions. Inlining does not happen in functions that are not reachable.<br>
 b. Dead code elimination is not perfect. There are cases where a function will become unreachable due to some late optimizations and will still be emitted into the binary.<br>
<br>
This patch changes the way always_inline functions are emitted in the Clang codegen to ensure this never happens. A function F is emitted as a pair of<br>
 a. internal F.inlinefunction() alwaysinline { **original function body** }<br>
and, depending on the function visibility, either<br>
 b1. declare F()<br>
or<br>
 b2. define external F() { musttail call F.inlinefunction() }<br>
<br>
Frontend ensures that all direct calls go to F.inlinefunction().<br>
<br>
This provides a simple invariant that all alwaysinline functions are internal, which can be checked in the IR verifier. Another invariant would be that alwaysinline functions never reach the backend.<br>
<br>
This patch is based on ideas by Chandler Carruth and Richard Smith.<br>
<br>
<br>
Repository:<br>
  rL LLVM<br>
<br>
<a href="http://reviews.llvm.org/D12087" rel="noreferrer" target="_blank">http://reviews.llvm.org/D12087</a><br>
<br>
Files:<br>
  lib/CodeGen/CGCXX.cpp<br>
  lib/CodeGen/CodeGenModule.cpp<br>
  lib/CodeGen/CodeGenModule.h<br>
  lib/CodeGen/ItaniumCXXABI.cpp<br>
  test/CodeGen/2008-05-19-AlwaysInline.c<br>
  test/CodeGen/always-inline.c<br>
  test/CodeGen/always_inline.c<br>
  test/CodeGen/alwaysinline.c<br>
  test/CodeGen/dllimport.c<br>
  test/CodeGen/function-attributes.c<br>
  test/CodeGen/pr9614.c<br>
  test/CodeGenCXX/alwaysinline.cpp<br>
  test/CodeGenCXX/dllimport.cpp<br>
  test/Frontend/optimization-remark-line-directive.c<br>
  test/Frontend/optimization-remark.c<br>
  test/Modules/cxx-irgen.cpp<br>
<br>
<br>_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@lists.llvm.org">cfe-commits@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits</a><br>
<br></blockquote></div><br></div></div>