On Mon, Aug 17, 2015 at 1:59 PM, David Blaikie <dblai...@gmail.com> wrote:
> > > On Mon, Aug 17, 2015 at 11:07 AM, Evgeniy Stepanov via cfe-commits < > cfe-commits@lists.llvm.org> wrote: > >> eugenis created this revision. >> eugenis added reviewers: chandlerc, rsmith. >> eugenis added a subscriber: cfe-commits. >> eugenis set the repository for this revision to rL LLVM. >> >> Currently always_inline definitions are emitted as (in most cases) an >> available_externally llvm function with an alwaysinline attribute. > > > Naive dude missing some context here: How can that ^ be correct? > > A basic test case doesn't seem to indicate that that's the case: > > __attribute__((always_inline)) void f1() { } > void f2() { f1(); } > > Compile with LLVM optimizations disabled, etc - the bitcode has no mention > of available_externally in it... > 1) __attribute__((always_inline)) does not imply inline; you need to add 'inline' to f1 or you're not in the "in most cases" case 2) always-inlining is performed even at -O0; you need -mllvm -disable-llvm-optzns to see the always_inline body 3) The "in most cases" case is for C or for C++ functions with __attribute__((gnu_inline)); in plain C++ you get a linkonce_odr function definition instead. > This is not exactly right: always_inline functions are NOT available >> externally, and, for example, libc++ uses this semantics to preserve ABI >> stability. >> >> Emitting an undefined symbol for an always_inline function is always a >> bug. The current code can still do it in certain cases. >> 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. >> 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. >> >> 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 >> a. internal F.inlinefunction() alwaysinline { **original function body** >> } >> and, depending on the function visibility, either >> b1. declare F() >> or >> b2. define external F() { musttail call F.inlinefunction() } >> >> Frontend ensures that all direct calls go to F.inlinefunction(). >> >> 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. >> >> This patch is based on ideas by Chandler Carruth and Richard Smith. >> >> >> Repository: >> rL LLVM >> >> http://reviews.llvm.org/D12087 >> >> Files: >> lib/CodeGen/CGCXX.cpp >> lib/CodeGen/CodeGenModule.cpp >> lib/CodeGen/CodeGenModule.h >> lib/CodeGen/ItaniumCXXABI.cpp >> test/CodeGen/2008-05-19-AlwaysInline.c >> test/CodeGen/always-inline.c >> test/CodeGen/always_inline.c >> test/CodeGen/alwaysinline.c >> test/CodeGen/dllimport.c >> test/CodeGen/function-attributes.c >> test/CodeGen/pr9614.c >> test/CodeGenCXX/alwaysinline.cpp >> test/CodeGenCXX/dllimport.cpp >> test/Frontend/optimization-remark-line-directive.c >> test/Frontend/optimization-remark.c >> test/Modules/cxx-irgen.cpp >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >> >> >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits