summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-10-25 23:53:31 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-10-25 23:53:31 +0000
commitea6d49d3eed5a4c5b7b728e55a7309aad98c746e (patch)
treeb19caf5ec271c32a617a865a116d1d43cfa8cf19 /llvm/lib
parent275e26025883605aa312521524e2ed9d8ba7e941 (diff)
downloadbcm5719-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.cpp24
-rw-r--r--llvm/lib/LTO/UpdateCompilerUsed.cpp48
-rw-r--r--llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp31
-rw-r--r--llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp27
-rw-r--r--llvm/lib/Transforms/Utils/ModuleUtils.cpp38
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);
OpenPOWER on IntegriCloud