summaryrefslogtreecommitdiffstats
path: root/llvm/lib/LTO
diff options
context:
space:
mode:
authorMehdi Amini <mehdi.amini@apple.com>2016-05-05 05:14:24 +0000
committerMehdi Amini <mehdi.amini@apple.com>2016-05-05 05:14:24 +0000
commit022b5bcb7a19e51c854a39adbd00e25ef1de83b7 (patch)
treef0b214f245dd8e00b090bc4d15bbfb58e7e635ae /llvm/lib/LTO
parent752ffe9c5f7cab673d4b9a94276e68d4191c601d (diff)
downloadbcm5719-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/lib/LTO')
-rw-r--r--llvm/lib/LTO/LTOCodeGenerator.cpp84
1 files changed, 67 insertions, 17 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;
}
OpenPOWER on IntegriCloud