diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-10-25 23:53:31 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2016-10-25 23:53:31 +0000 |
commit | ea6d49d3eed5a4c5b7b728e55a7309aad98c746e (patch) | |
tree | b19caf5ec271c32a617a865a116d1d43cfa8cf19 /llvm/lib | |
parent | 275e26025883605aa312521524e2ed9d8ba7e941 (diff) | |
download | bcm5719-llvm-ea6d49d3eed5a4c5b7b728e55a7309aad98c746e.tar.gz bcm5719-llvm-ea6d49d3eed5a4c5b7b728e55a7309aad98c746e.zip |
Utility functions for appending to llvm.used/llvm.compiler.used.
llvm-svn: 285143
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/LTO/LTOCodeGenerator.cpp | 24 | ||||
-rw-r--r-- | llvm/lib/LTO/UpdateCompilerUsed.cpp | 48 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/Transforms/Utils/ModuleUtils.cpp | 38 |
5 files changed, 69 insertions, 99 deletions
diff --git a/llvm/lib/LTO/LTOCodeGenerator.cpp b/llvm/lib/LTO/LTOCodeGenerator.cpp index a07707cd38a..98ce550c7dd 100644 --- a/llvm/lib/LTO/LTOCodeGenerator.cpp +++ b/llvm/lib/LTO/LTOCodeGenerator.cpp @@ -58,6 +58,7 @@ #include "llvm/Transforms/IPO/Internalize.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/ObjCARC.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" #include <system_error> using namespace llvm; @@ -364,18 +365,10 @@ std::unique_ptr<TargetMachine> LTOCodeGenerator::createTargetMachine() { void LTOCodeGenerator::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()); + std::vector<GlobalValue *> Used; auto mayPreserveGlobal = [&](GlobalValue &GV) { if (!GV.isDiscardableIfUnused() || GV.isDeclaration() || - !mustPreserveGV(GV)) + !mustPreserveGV(GV)) return; if (GV.hasAvailableExternallyLinkage()) return emitWarning( @@ -384,7 +377,7 @@ void LTOCodeGenerator::preserveDiscardableGVs( if (GV.hasInternalLinkage()) return emitWarning((Twine("Linker asked to preserve internal global: '") + GV.getName() + "'").str()); - UsedValuesSet.insert(ConstantExpr::getBitCast(&GV, i8PTy)); + Used.push_back(&GV); }; for (auto &GV : TheModule) mayPreserveGlobal(GV); @@ -393,15 +386,10 @@ void LTOCodeGenerator::preserveDiscardableGVs( for (auto &GV : TheModule.aliases()) mayPreserveGlobal(GV); - if (UsedValuesSet.empty()) + if (Used.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"); + appendToCompilerUsed(TheModule, Used); } void LTOCodeGenerator::applyScopeRestrictions() { diff --git a/llvm/lib/LTO/UpdateCompilerUsed.cpp b/llvm/lib/LTO/UpdateCompilerUsed.cpp index a574db6fb5a..b67d9ea5989 100644 --- a/llvm/lib/LTO/UpdateCompilerUsed.cpp +++ b/llvm/lib/LTO/UpdateCompilerUsed.cpp @@ -18,6 +18,7 @@ #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Transforms/IPO/Internalize.h" +#include "llvm/Transforms/Utils/ModuleUtils.h" using namespace llvm; @@ -28,16 +29,16 @@ class PreserveLibCallsAndAsmUsed { public: PreserveLibCallsAndAsmUsed(const StringSet<> &AsmUndefinedRefs, const TargetMachine &TM, - SmallPtrSetImpl<const GlobalValue *> &LLVMUsed) + std::vector<GlobalValue *> &LLVMUsed) : AsmUndefinedRefs(AsmUndefinedRefs), TM(TM), LLVMUsed(LLVMUsed) {} - void findInModule(const Module &TheModule) { + void findInModule(Module &TheModule) { initializeLibCalls(TheModule); - for (const Function &F : TheModule) + for (Function &F : TheModule) findLibCallsAndAsm(F); - for (const GlobalVariable &GV : TheModule.globals()) + for (GlobalVariable &GV : TheModule.globals()) findLibCallsAndAsm(GV); - for (const GlobalAlias &GA : TheModule.aliases()) + for (GlobalAlias &GA : TheModule.aliases()) findLibCallsAndAsm(GA); } @@ -51,7 +52,7 @@ private: StringSet<> Libcalls; // Output - SmallPtrSetImpl<const GlobalValue *> &LLVMUsed; + std::vector<GlobalValue *> &LLVMUsed; // Collect names of runtime library functions. User-defined functions with the // same names are added to llvm.compiler.used to prevent them from being @@ -86,7 +87,7 @@ private: } } - void findLibCallsAndAsm(const GlobalValue &GV) { + void findLibCallsAndAsm(GlobalValue &GV) { // There are no restrictions to apply to declarations. if (GV.isDeclaration()) return; @@ -100,13 +101,15 @@ private: // optimizations like -globalopt, causing problems when later optimizations // add new library calls (e.g., llvm.memset => memset and printf => puts). // Leave it to the linker to remove any dead code (e.g. with -dead_strip). - if (isa<Function>(GV) && Libcalls.count(GV.getName())) - LLVMUsed.insert(&GV); + if (isa<Function>(GV) && Libcalls.count(GV.getName())) { + LLVMUsed.push_back(&GV); + return; + } SmallString<64> Buffer; TM.getNameWithPrefix(Buffer, &GV, Mangler); if (AsmUndefinedRefs.count(Buffer)) - LLVMUsed.insert(&GV); + LLVMUsed.push_back(&GV); } }; @@ -114,33 +117,12 @@ private: void llvm::updateCompilerUsed(Module &TheModule, const TargetMachine &TM, const StringSet<> &AsmUndefinedRefs) { - SmallPtrSet<const GlobalValue *, 8> UsedValues; + std::vector<GlobalValue *> UsedValues; PreserveLibCallsAndAsmUsed(AsmUndefinedRefs, TM, UsedValues) .findInModule(TheModule); if (UsedValues.empty()) return; - llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(TheModule.getContext()); - std::vector<Constant *> UsedValuesList; - for (const auto *GV : UsedValues) { - Constant *c = - ConstantExpr::getBitCast(const_cast<GlobalValue *>(GV), i8PTy); - UsedValuesList.push_back(c); - } - - GlobalVariable *LLVMUsed = TheModule.getGlobalVariable("llvm.compiler.used"); - if (LLVMUsed) { - ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); - for (auto &V : Inits->operands()) - UsedValuesList.push_back(cast<Constant>(&V)); - LLVMUsed->eraseFromParent(); - } - - llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, UsedValuesList.size()); - LLVMUsed = new llvm::GlobalVariable( - TheModule, ATy, false, llvm::GlobalValue::AppendingLinkage, - llvm::ConstantArray::get(ATy, UsedValuesList), "llvm.compiler.used"); - - LLVMUsed->setSection("llvm.metadata"); + appendToCompilerUsed(TheModule, UsedValues); } diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 586c399dbca..d77a0ae31b7 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1624,7 +1624,7 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { StructType *LivenessTy = StructType::get(IntptrTy, IntptrTy, nullptr); // Keep the list of "Liveness" GV created to be added to llvm.compiler.used - SmallVector<Constant *, 16> LivenessGlobals; + SmallVector<GlobalValue *, 16> LivenessGlobals; LivenessGlobals.reserve(n); for (size_t i = 0; i < n; i++) { @@ -1647,30 +1647,15 @@ bool AddressSanitizerModule::InstrumentGlobals(IRBuilder<> &IRB, Module &M) { M, LivenessTy, false, GlobalVariable::InternalLinkage, LivenessBinder, Twine("__asan_binder_") + GVName); Liveness->setSection("__DATA,__asan_liveness,regular,live_support"); - LivenessGlobals.push_back( - ConstantExpr::getBitCast(Liveness, IRB.getInt8PtrTy())); + LivenessGlobals.push_back(Liveness); } - if (!LivenessGlobals.empty()) { - // Update llvm.compiler.used, adding the new liveness globals. This is - // needed so that during LTO these variables stay alive. The alternative - // would be to have the linker handling the LTO symbols, but libLTO - // current - // API does not expose access to the section for each symbol. - if (GlobalVariable *LLVMUsed = - M.getGlobalVariable("llvm.compiler.used")) { - ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); - for (auto &V : Inits->operands()) - LivenessGlobals.push_back(cast<Constant>(&V)); - LLVMUsed->eraseFromParent(); - } - llvm::ArrayType *ATy = - llvm::ArrayType::get(IRB.getInt8PtrTy(), LivenessGlobals.size()); - auto *LLVMUsed = new llvm::GlobalVariable( - M, ATy, false, llvm::GlobalValue::AppendingLinkage, - llvm::ConstantArray::get(ATy, LivenessGlobals), "llvm.compiler.used"); - LLVMUsed->setSection("llvm.metadata"); - } + // Update llvm.compiler.used, adding the new liveness globals. This is + // needed so that during LTO these variables stay alive. The alternative + // would be to have the linker handling the LTO symbols, but libLTO + // current API does not expose access to the section for each symbol. + if (!LivenessGlobals.empty()) + appendToCompilerUsed(M, LivenessGlobals); } else { // On all other platfoms, we just emit an array of global metadata // structures. diff --git a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index f3345a69fe8..8b3e4fc9fe1 100644 --- a/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp @@ -553,31 +553,8 @@ void InstrProfiling::emitRuntimeHook() { } void InstrProfiling::emitUses() { - if (UsedVars.empty()) - return; - - GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used"); - std::vector<Constant *> MergedVars; - if (LLVMUsed) { - // Collect the existing members of llvm.used. - ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); - for (unsigned I = 0, E = Inits->getNumOperands(); I != E; ++I) - MergedVars.push_back(Inits->getOperand(I)); - LLVMUsed->eraseFromParent(); - } - - Type *i8PTy = Type::getInt8PtrTy(M->getContext()); - // Add uses for our data. - for (auto *Value : UsedVars) - MergedVars.push_back( - ConstantExpr::getBitCast(cast<Constant>(Value), i8PTy)); - - // Recreate llvm.used. - ArrayType *ATy = ArrayType::get(i8PTy, MergedVars.size()); - LLVMUsed = - new GlobalVariable(*M, ATy, false, GlobalValue::AppendingLinkage, - ConstantArray::get(ATy, MergedVars), "llvm.used"); - LLVMUsed->setSection("llvm.metadata"); + if (!UsedVars.empty()) + appendToUsed(*M, UsedVars); } void InstrProfiling::emitInitialization() { diff --git a/llvm/lib/Transforms/Utils/ModuleUtils.cpp b/llvm/lib/Transforms/Utils/ModuleUtils.cpp index eb918851862..4f8737e9b93 100644 --- a/llvm/lib/Transforms/Utils/ModuleUtils.cpp +++ b/llvm/lib/Transforms/Utils/ModuleUtils.cpp @@ -89,6 +89,44 @@ void llvm::appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *D appendToGlobalArray("llvm.global_dtors", M, F, Priority, Data); } +static void appendToUsedList(Module &M, StringRef Name, ArrayRef<GlobalValue *> Values) { + GlobalVariable *GV = M.getGlobalVariable(Name); + SmallPtrSet<Constant *, 16> InitAsSet; + SmallVector<Constant *, 16> Init; + if (GV) { + ConstantArray *CA = dyn_cast<ConstantArray>(GV->getInitializer()); + for (auto &Op : CA->operands()) { + Constant *C = cast_or_null<Constant>(Op); + if (InitAsSet.insert(C).second) + Init.push_back(C); + } + GV->eraseFromParent(); + } + + Type *Int8PtrTy = llvm::Type::getInt8PtrTy(M.getContext()); + for (auto *V : Values) { + Constant *C = ConstantExpr::getBitCast(V, Int8PtrTy); + if (InitAsSet.insert(C).second) + Init.push_back(C); + } + + if (Init.empty()) + return; + + ArrayType *ATy = ArrayType::get(Int8PtrTy, Init.size()); + GV = new llvm::GlobalVariable(M, ATy, false, GlobalValue::AppendingLinkage, + ConstantArray::get(ATy, Init), Name); + GV->setSection("llvm.metadata"); +} + +void llvm::appendToUsed(Module &M, ArrayRef<GlobalValue *> Values) { + appendToUsedList(M, "llvm.used", Values); +} + +void llvm::appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values) { + appendToUsedList(M, "llvm.compiler.used", Values); +} + Function *llvm::checkSanitizerInterfaceFunction(Constant *FuncOrBitcast) { if (isa<Function>(FuncOrBitcast)) return cast<Function>(FuncOrBitcast); |