[llvm-commits] [dragonegg] r125666 - /dragonegg/trunk/llvm-backend.cpp

Duncan Sands baldrick at free.fr
Wed Feb 16 09:09:42 PST 2011


Author: baldrick
Date: Wed Feb 16 11:09:42 2011
New Revision: 125666

URL: http://llvm.org/viewvc/llvm-project?rev=125666&view=rev
Log:
Recent GCC has does an (undocumented) optimization by which it generates
"same body aliases" rather than multiple copies of the same function.  If
the aliasee has "extern inline" semantics then GCC discards it along with
all of its aliases after running the inliner.  We were creating a function
with AvailableExternally linkage for the "extern inline" function and weak
aliases for the same body aliases.  At LLVM codegen time the aliasee would
be discarded, leading to unresolved external references for the aliases.
Solve this by arranging for all uses of the aliases to be replaced with the
corresponding use of the aliasee, so when the aliasee is discarded in effect
so are all the aliases.  This fixes the OpenCV version 2.0 build, reported
broken by sabaliauskas g. (gs5g08) on the mailing list.

Modified:
    dragonegg/trunk/llvm-backend.cpp

Modified: dragonegg/trunk/llvm-backend.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/llvm-backend.cpp?rev=125666&r1=125665&r2=125666&view=diff
==============================================================================
--- dragonegg/trunk/llvm-backend.cpp (original)
+++ dragonegg/trunk/llvm-backend.cpp Wed Feb 16 11:09:42 2011
@@ -1859,7 +1859,25 @@
   if (errorcount || sorrycount)
     return; // Do not process broken code.
 
-  emit_alias(alias->decl, alias->thunk.alias);
+  // If the target is not "extern inline" then output an ordinary alias.
+  tree target = alias->thunk.alias;
+  if (!DECL_EXTERNAL(target)) {
+    emit_alias(alias->decl, target);
+    return;
+  }
+
+  // Same body aliases have the property that if the body of the aliasee is not
+  // output then neither are the aliases.  To arrange this for "extern inline"
+  // functions, which have AvailableExternally linkage in LLVM, make all users
+  // of the alias directly use the aliasee instead.
+  GlobalValue *Alias = cast<GlobalValue>(DECL_LLVM(alias->decl));
+  GlobalValue *Aliasee = cast<GlobalValue>(DEFINITION_LLVM(target));
+  Alias->replaceAllUsesWith(ConstantExpr::getBitCast(Aliasee,Alias->getType()));
+  changeLLVMConstant(Alias, Aliasee);
+  Alias->eraseFromParent();
+
+  // Mark the alias as written so gcc doesn't waste time outputting it.
+  TREE_ASM_WRITTEN(alias->decl) = 1;
 }
 
 /// emit_file_scope_asm - Emit the specified string as a file-scope inline





More information about the llvm-commits mailing list