diff options
Diffstat (limited to 'contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp')
-rw-r--r-- | contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp | 51 |
1 files changed, 39 insertions, 12 deletions
diff --git a/contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp b/contrib/llvm/lib/Transforms/Instrumentation/InstrProfiling.cpp index 2a3d154..05a9c8a 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(); }; @@ -145,8 +146,8 @@ void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) { IRBuilder<> Builder(Inc->getParent(), *Inc); uint64_t Index = Inc->getIndex()->getZExtValue(); - llvm::Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters, 0, Index); - llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount"); + Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters, 0, Index); + Value *Count = Builder.CreateLoad(Addr, "pgocount"); Count = Builder.CreateAdd(Count, Builder.getInt64(1)); Inc->replaceAllUsesWith(Builder.CreateStore(Count, Addr)); Inc->eraseFromParent(); @@ -195,9 +196,13 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { if (It != RegionCounters.end()) return It->second; - // Move the name variable to the right section. + // Move the name variable to the right section. Make sure it is placed in the + // same comdat as its associated function. Otherwise, we may get multiple + // counters for the same function in certain cases. + Function *Fn = Inc->getParent()->getParent(); Name->setSection(getNameSection()); Name->setAlignment(1); + Name->setComdat(Fn->getComdat()); uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); LLVMContext &Ctx = M->getContext(); @@ -210,6 +215,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { Counters->setVisibility(Name->getVisibility()); Counters->setSection(getCountersSection()); Counters->setAlignment(8); + 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); @@ -256,7 +263,7 @@ void InstrProfiling::emitRegistration() { if (Options.NoRedZone) RegisterF->addFnAttr(Attribute::NoRedZone); - auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false); + auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false); auto *RuntimeRegisterF = Function::Create(RuntimeRegisterTy, GlobalVariable::ExternalLinkage, "__llvm_profile_register_function", M); @@ -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); @@ -302,7 +310,7 @@ void InstrProfiling::emitUses() { return; GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used"); - std::vector<Constant*> MergedVars; + std::vector<Constant *> MergedVars; if (LLVMUsed) { // Collect the existing members of llvm.used. ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); @@ -315,20 +323,22 @@ void InstrProfiling::emitUses() { // Add uses for our data. for (auto *Value : UsedVars) MergedVars.push_back( - ConstantExpr::getBitCast(cast<llvm::Constant>(Value), i8PTy)); + ConstantExpr::getBitCast(cast<Constant>(Value), i8PTy)); // Recreate llvm.used. ArrayType *ATy = ArrayType::get(i8PTy, MergedVars.size()); - LLVMUsed = new llvm::GlobalVariable( - *M, ATy, false, llvm::GlobalValue::AppendingLinkage, - llvm::ConstantArray::get(ATy, MergedVars), "llvm.used"); + LLVMUsed = + new GlobalVariable(*M, ATy, false, GlobalValue::AppendingLinkage, + ConstantArray::get(ATy, MergedVars), "llvm.used"); LLVMUsed->setSection("llvm.metadata"); } 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); |