diff --git a/lib/Transforms/IPO/ExtractGV.cpp b/lib/Transforms/IPO/ExtractGV.cpp index 07b05ee38a1..fa3d72ddcf1 100644 --- a/lib/Transforms/IPO/ExtractGV.cpp +++ b/lib/Transforms/IPO/ExtractGV.cpp @@ -21,38 +21,6 @@ #include using namespace llvm; -/// Make sure GV is visible from both modules. Delete is true if it is -/// being deleted from this module. -/// This also makes sure GV cannot be dropped so that references from -/// the split module remain valid. -static void makeVisible(GlobalValue &GV, bool Delete) { - bool Local = GV.hasLocalLinkage(); - if (Local) - GV.setVisibility(GlobalValue::HiddenVisibility); - - if (Local || Delete) { - GV.setLinkage(GlobalValue::ExternalLinkage); - return; - } - - if (!GV.hasLinkOnceLinkage()) { - assert(!GV.isDiscardableIfUnused()); - return; - } - - // Map linkonce* to weak* so that llvm doesn't drop this GV. - switch(GV.getLinkage()) { - default: - llvm_unreachable("Unexpected linkage"); - case GlobalValue::LinkOnceAnyLinkage: - GV.setLinkage(GlobalValue::WeakAnyLinkage); - return; - case GlobalValue::LinkOnceODRLinkage: - GV.setLinkage(GlobalValue::WeakODRLinkage); - return; - } -} - namespace { /// @brief A pass to extract specific functions and their dependencies. class GVExtractorPass : public ModulePass { @@ -92,7 +60,12 @@ namespace { continue; } - makeVisible(*I, Delete); + bool Local = I->isDiscardableIfUnused(); + if (Local) + I->setVisibility(GlobalValue::HiddenVisibility); + + if (Local || Delete) + I->setLinkage(GlobalValue::ExternalLinkage); if (Delete) I->setInitializer(0); @@ -107,7 +80,12 @@ namespace { continue; } - makeVisible(*I, Delete); + bool Local = I->isDiscardableIfUnused(); + if (Local) + I->setVisibility(GlobalValue::HiddenVisibility); + + if (Local || Delete) + I->setLinkage(GlobalValue::ExternalLinkage); if (Delete) I->deleteBody(); @@ -119,10 +97,12 @@ namespace { Module::alias_iterator CurI = I; ++I; - bool Delete = deleteStuff == (bool)Named.count(CurI); - makeVisible(*I, Delete); + if (CurI->isDiscardableIfUnused()) { + CurI->setVisibility(GlobalValue::HiddenVisibility); + CurI->setLinkage(GlobalValue::ExternalLinkage); + } - if (Delete) { + if (deleteStuff == (bool)Named.count(CurI)) { Type *Ty = CurI->getType()->getElementType(); CurI->removeFromParent(); diff --git a/test/Other/extract-linkonce.ll b/test/Other/extract-linkonce.ll index 4c6b6b76a4a..31fbf3ac463 100644 --- a/test/Other/extract-linkonce.ll +++ b/test/Other/extract-linkonce.ll @@ -1,16 +1,15 @@ ; RUN: llvm-extract -func foo -S < %s | FileCheck %s ; RUN: llvm-extract -delete -func foo -S < %s | FileCheck --check-prefix=DELETE %s -; Test that linkonce definitions are mapped to weak so that they are not -; dropped. +; Test that we don't convert weak_odr to external definitions. -; CHECK: @bar = external global i32 -; CHECK: define weak i32* @foo() { +; CHECK: @bar = external hidden global i32 +; CHECK: define hidden i32* @foo() { ; CHECK-NEXT: ret i32* @bar ; CHECK-NEXT: } -; DELETE: @bar = weak global i32 42 -; DELETE: declare i32* @foo() +; DELETE: @bar = hidden global i32 42 +; DELETE: declare hidden i32* @foo() @bar = linkonce global i32 42