mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-24 14:33:40 +00:00
Utility functions for appending to llvm.used/llvm.compiler.used.
llvm-svn: 285143
This commit is contained in:
parent
d64a9f9f9d
commit
2be3986f95
@ -44,7 +44,7 @@ private:
|
||||
}
|
||||
};
|
||||
DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap;
|
||||
std::vector<Value *> UsedVars;
|
||||
std::vector<GlobalValue *> UsedVars;
|
||||
std::vector<GlobalVariable *> ReferencedNames;
|
||||
GlobalVariable *NamesVar;
|
||||
size_t NamesSize;
|
||||
|
@ -59,6 +59,12 @@ std::pair<Function *, Function *> createSanitizerCtorAndInitFunctions(
|
||||
/// the list of public globals in the module.
|
||||
bool nameUnamedGlobals(Module &M);
|
||||
|
||||
/// \brief Adds global values to the llvm.used list.
|
||||
void appendToUsed(Module &M, ArrayRef<GlobalValue *> Values);
|
||||
|
||||
/// \brief Adds global values to the llvm.compiler.used list.
|
||||
void appendToCompilerUsed(Module &M, ArrayRef<GlobalValue *> Values);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif // LLVM_TRANSFORMS_UTILS_MODULEUTILS_H
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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() {
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user