summaryrefslogtreecommitdiffstats
path: root/contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp')
-rw-r--r--contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp33
1 files changed, 30 insertions, 3 deletions
diff --git a/contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
index 2a3d154..610ff52 100644
--- a/contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
+++ b/contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp
@@ -97,7 +97,8 @@ private:
/// Add uses of our data variables and runtime hook.
void emitUses();
- /// Create a static initializer for our data, on platforms that need it.
+ /// Create a static initializer for our data, on platforms that need it,
+ /// and for any profile output file that was specified.
void emitInitialization();
};
@@ -202,6 +203,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
uint64_t NumCounters = Inc->getNumCounters()->getZExtValue();
LLVMContext &Ctx = M->getContext();
ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters);
+ Function *Fn = Inc->getParent()->getParent();
// Create the counters variable.
auto *Counters = new GlobalVariable(*M, CounterTy, false, Name->getLinkage(),
@@ -210,6 +212,10 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
Counters->setVisibility(Name->getVisibility());
Counters->setSection(getCountersSection());
Counters->setAlignment(8);
+ // Place the counters in the same comdat section as its parent function.
+ // Otherwise, we may get multiple counters for the same function in certain
+ // cases.
+ Counters->setComdat(Fn->getComdat());
RegionCounters[Inc->getName()] = Counters;
@@ -234,6 +240,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) {
Data->setVisibility(Name->getVisibility());
Data->setSection(getDataSection());
Data->setAlignment(8);
+ Data->setComdat(Fn->getComdat());
// Mark the data variable as used so that it isn't stripped out.
UsedVars.push_back(Data);
@@ -288,6 +295,7 @@ void InstrProfiling::emitRuntimeHook() {
User->addFnAttr(Attribute::NoInline);
if (Options.NoRedZone)
User->addFnAttr(Attribute::NoRedZone);
+ User->setVisibility(GlobalValue::HiddenVisibility);
IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", User));
auto *Load = IRB.CreateLoad(Var);
@@ -327,8 +335,10 @@ void InstrProfiling::emitUses() {
}
void InstrProfiling::emitInitialization() {
+ std::string InstrProfileOutput = Options.InstrProfileOutput;
+
Constant *RegisterF = M->getFunction("__llvm_profile_register_functions");
- if (!RegisterF)
+ if (!RegisterF && InstrProfileOutput.empty())
return;
// Create the initialization function.
@@ -343,7 +353,24 @@ void InstrProfiling::emitInitialization() {
// Add the basic block and the necessary calls.
IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", F));
- IRB.CreateCall(RegisterF);
+ if (RegisterF)
+ IRB.CreateCall(RegisterF, {});
+ if (!InstrProfileOutput.empty()) {
+ auto *Int8PtrTy = Type::getInt8PtrTy(M->getContext());
+ auto *SetNameTy = FunctionType::get(VoidTy, Int8PtrTy, false);
+ auto *SetNameF =
+ Function::Create(SetNameTy, GlobalValue::ExternalLinkage,
+ "__llvm_profile_override_default_filename", M);
+
+ // Create variable for profile name
+ Constant *ProfileNameConst =
+ ConstantDataArray::getString(M->getContext(), InstrProfileOutput, true);
+ GlobalVariable *ProfileName =
+ new GlobalVariable(*M, ProfileNameConst->getType(), true,
+ GlobalValue::PrivateLinkage, ProfileNameConst);
+
+ IRB.CreateCall(SetNameF, IRB.CreatePointerCast(ProfileName, Int8PtrTy));
+ }
IRB.CreateRetVoid();
appendToGlobalCtors(*M, F, 0);
OpenPOWER on IntegriCloud