From 8728d7a3ea7cad3297f9ab0984358007238ae83a Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Fri, 12 Jun 2009 15:56:56 +0000 Subject: [PATCH] Given two identical weak functions, produce one internal function and two weak thunks. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@73230 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/IPO/MergeFunctions.cpp | 21 +++++++++++++++++---- test/Transforms/MergeFunc/fold-weak.ll | 13 +++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 test/Transforms/MergeFunc/fold-weak.ll diff --git a/lib/Transforms/IPO/MergeFunctions.cpp b/lib/Transforms/IPO/MergeFunctions.cpp index 16083ec7817..e237fcde026 100644 --- a/lib/Transforms/IPO/MergeFunctions.cpp +++ b/lib/Transforms/IPO/MergeFunctions.cpp @@ -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 Args; @@ -539,8 +539,21 @@ static bool fold(std::vector &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 index 00000000000..cea49fb1cec --- /dev/null +++ b/test/Transforms/MergeFunc/fold-weak.ll @@ -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 +}