diff options
author | Mehdi Amini <mehdi.amini@apple.com> | 2016-05-05 05:14:24 +0000 |
---|---|---|
committer | Mehdi Amini <mehdi.amini@apple.com> | 2016-05-05 05:14:24 +0000 |
commit | 022b5bcb7a19e51c854a39adbd00e25ef1de83b7 (patch) | |
tree | f0b214f245dd8e00b090bc4d15bbfb58e7e635ae /llvm | |
parent | 752ffe9c5f7cab673d4b9a94276e68d4191c601d (diff) | |
download | bcm5719-llvm-022b5bcb7a19e51c854a39adbd00e25ef1de83b7.tar.gz bcm5719-llvm-022b5bcb7a19e51c854a39adbd00e25ef1de83b7.zip |
LTOCodeGenerator: add linkonce(_odr) to "llvm.compiler.used" when present in "MustPreserve" set
If the linker requested to preserve a linkonce function, we should
honor this even if we drop all uses.
We explicitely avoid turning them into weak_odr (unlike the first
version of this patch in r267644), because the codegen can be
different on Darwin: because of `llvm::canBeOmittedFromSymbolTable()`
we may emit the symbol as weak_def_can_be_hidden instead of
weak_definition.
From: Mehdi Amini <mehdi.amini@apple.com>
llvm-svn: 268607
Diffstat (limited to 'llvm')
-rw-r--r-- | llvm/lib/LTO/LTOCodeGenerator.cpp | 84 | ||||
-rw-r--r-- | llvm/test/tools/lto/hide-linkonce-odr.ll | 15 |
2 files changed, 78 insertions, 21 deletions
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp index 30cff727513..cad5d8eda51 100644 --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -348,8 +348,73 @@ std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() { RelocModel, CodeModel::Default, CGOptLevel)); } +// If a linkonce global is present in the MustPreserveSymbols, we need to make +// sure we honor this. To force the compiler to not drop it, we add it to the +// "llvm.compiler.used" global. +static void preserveDiscardableGVs( + Module &TheModule, + llvm::function_ref<bool(const GlobalValue &)> mustPreserveGV) { + SetVector<Constant *> UsedValuesSet; + if (GlobalVariable *LLVMUsed = + TheModule.getGlobalVariable("llvm.compiler.used")) { + ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); + for (auto &V : Inits->operands()) + UsedValuesSet.insert(cast<Constant>(&V)); + LLVMUsed->eraseFromParent(); + } + llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext()); + auto mayPreserveGlobal = [&](GlobalValue &GV) { + if (!GV.isDiscardableIfUnused() || GV.isDeclaration()) + return; + if (!mustPreserveGV(GV)) + return; + assert(!GV.hasAvailableExternallyLinkage() && !GV.hasInternalLinkage()); + UsedValuesSet.insert(ConstantExpr::getBitCast(&GV, i8PTy)); + }; + for (auto &GV : TheModule) + mayPreserveGlobal(GV); + for (auto &GV : TheModule.globals()) + mayPreserveGlobal(GV); + for (auto &GV : TheModule.aliases()) + mayPreserveGlobal(GV); + + if (UsedValuesSet.empty()) + return; + + llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, UsedValuesSet.size()); + auto *LLVMUsed = new llvm::GlobalVariable( + TheModule, ATy, false, llvm::GlobalValue::AppendingLinkage, + llvm::ConstantArray::get(ATy, UsedValuesSet.getArrayRef()), + "llvm.compiler.used"); + LLVMUsed->setSection("llvm.metadata"); +} + void LTOCodeGenerator::applyScopeRestrictions() { - if (ScopeRestrictionsDone || !ShouldInternalize) + if (ScopeRestrictionsDone) + return; + + // Declare a callback for the internalize pass that will ask for every + // candidate GlobalValue if it can be internalized or not. + SmallString<64> MangledName; + auto mustPreserveGV = [&](const GlobalValue &GV) -> bool { + // Unnamed globals can't be mangled, but they can't be preserved either. + if (!GV.hasName()) + return false; + + // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled + // with the linker supplied name, which on Darwin includes a leading + // underscore. + MangledName.clear(); + MangledName.reserve(GV.getName().size() + 1); + Mangler::getNameWithPrefix(MangledName, GV.getName(), + MergedModule->getDataLayout()); + return MustPreserveSymbols.count(MangledName); + }; + + // Preserve linkonce value on linker request + preserveDiscardableGVs(*MergedModule, mustPreserveGV); + + if (!ShouldInternalize) return; if (ShouldRestoreGlobalsLinkage) { @@ -373,22 +438,7 @@ void LTOCodeGenerator::applyScopeRestrictions() { // symbols referenced from asm UpdateCompilerUsed(*MergedModule, *TargetMach, AsmUndefinedRefs); - // Declare a callback for the internalize pass that will ask for every - // candidate GlobalValue if it can be internalized or not. - Mangler Mangler; - SmallString<64> MangledName; - auto MustPreserveGV = [&](const GlobalValue &GV) -> bool { - // Need to mangle the GV as the "MustPreserveSymbols" StringSet is filled - // with the linker supplied name, which on Darwin includes a leading - // underscore. - MangledName.clear(); - MangledName.reserve(GV.getName().size() + 1); - Mangler::getNameWithPrefix(MangledName, GV.getName(), - MergedModule->getDataLayout()); - return MustPreserveSymbols.count(MangledName); - }; - - internalizeModule(*MergedModule, MustPreserveGV); + internalizeModule(*MergedModule, mustPreserveGV); ScopeRestrictionsDone = true; } diff --git a/llvm/test/tools/lto/hide-linkonce-odr.ll b/llvm/test/tools/lto/hide-linkonce-odr.ll index a1de96e8b33..6fbd75764ce 100644 --- a/llvm/test/tools/lto/hide-linkonce-odr.ll +++ b/llvm/test/tools/lto/hide-linkonce-odr.ll @@ -1,21 +1,28 @@ ; RUN: llvm-as %s -o %t.o -; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -lSystem -o %t.dylib %t.o -save-temps -undefined dynamic_lookup +; RUN: %ld64 -lto_library %llvmshlibdir/libLTO.dylib -dylib -arch x86_64 -macosx_version_min 10.10.0 -lSystem -o %t.dylib %t.o -save-temps -undefined dynamic_lookup -exported_symbol _c -exported_symbol _b -exported_symbol _GlobLinkonce ; RUN: llvm-dis %t.dylib.lto.opt.bc -o - | FileCheck --check-prefix=IR %s -; check that @a is still a linkonce_odr definition -; IR: define linkonce_odr void @a() +; check that @a is no longer a linkonce_odr definition +; IR-NOT: define linkonce_odr void @a() +; check that @b is appended in llvm.used +; IR: @llvm.compiler.used = appending global [2 x i8*] [i8* bitcast ([1 x i8*]* @GlobLinkonce to i8*), i8* bitcast (void ()* @b to i8*)], section "llvm.metadata" ; RUN: llvm-nm %t.dylib | FileCheck --check-prefix=NM %s -; check that the linker can hide @a but not @b +; check that the linker can hide @a but not @b, nor @GlobLinkonce +; NM: 0000000000000f48 S _GlobLinkonce ; NM: 0000000000000f10 t _a ; NM: 0000000000000f20 T _b ; NM: 0000000000000f00 T _c + target triple = "x86_64-apple-macosx10.10.0" declare void @external() +@GlobLinkonce = linkonce_odr unnamed_addr constant [1 x i8*] [i8* null], align 8 + define linkonce_odr void @a() noinline { + %use_of_GlobLinkonce = load [1 x i8*], [1 x i8*] *@GlobLinkonce call void @external() ret void } |