Given two identical weak functions, produce one internal function and two weak
authorNick Lewycky <nicholas@mxc.ca>
Fri, 12 Jun 2009 15:56:56 +0000 (15:56 +0000)
committerNick Lewycky <nicholas@mxc.ca>
Fri, 12 Jun 2009 15:56:56 +0000 (15:56 +0000)
thunks.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73230 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/MergeFunctions.cpp
test/Transforms/MergeFunc/fold-weak.ll [new file with mode: 0644]

index 16083ec781726ee8b3c7d6177192dc389873b6f1..e237fcde0267cea5faa3e4d07fc4088762990609 100644 (file)
@@ -458,8 +458,8 @@ static LinkageCategory categorize(const Function *F) {
 }
 
 static void ThunkGToF(Function *F, Function *G) {
-  Function *NewG = Function::Create(G->getFunctionType(), G->getLinkage(),
-                                    "", G->getParent());
+  Function *NewG = Function::Create(G->getFunctionType(), G->getLinkage(), "",
+                                    G->getParent());
   BasicBlock *BB = BasicBlock::Create("", NewG);
 
   std::vector<Value *> Args;
@@ -539,8 +539,21 @@ static bool fold(std::vector<Function *> &FnVec, unsigned i, unsigned j) {
       }
       break;
 
-    case ExternalWeak:
-      return false;
+    case ExternalWeak: {
+      assert(catG == ExternalWeak);
+
+      // Make them both thunks to the same internal function.
+      F->setAlignment(std::max(F->getAlignment(), G->getAlignment()));
+      Function *H = Function::Create(F->getFunctionType(), F->getLinkage(), "",
+                                     F->getParent());
+      H->copyAttributesFrom(F);
+      H->takeName(F);
+
+      ThunkGToF(F, G);
+      ThunkGToF(F, H);
+
+      F->setLinkage(GlobalValue::InternalLinkage);
+    } break;
 
     case Internal:
       switch (catG) {
diff --git a/test/Transforms/MergeFunc/fold-weak.ll b/test/Transforms/MergeFunc/fold-weak.ll
new file mode 100644 (file)
index 0000000..cea49fb
--- /dev/null
@@ -0,0 +1,13 @@
+; RUN: llvm-as < %s | opt -mergefunc | llvm-dis > %t
+; RUN: grep {define weak} %t | count 2
+; RUN: grep {call} %t | count 2
+
+define weak i32 @sum(i32 %x, i32 %y) {
+  %sum = add i32 %x, %y
+  ret i32 %sum
+}
+
+define weak i32 @add(i32 %x, i32 %y) {
+  %sum = add i32 %x, %y
+  ret i32 %sum
+}