X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=lib%2FTransforms%2FInstrumentation%2FInstrProfiling.cpp;h=a68fd3db6c2e9238ae04bec683a68c38b73f6d1a;hp=2a3d15421de9dec58b646bbc0377a7449c541ae6;hb=0971eb7364bde89cacbfceebad94a66a638c5046;hpb=167ce4489cabd2cd2a4ea3acc8e2f45b478337a6 diff --git a/lib/Transforms/Instrumentation/InstrProfiling.cpp b/lib/Transforms/Instrumentation/InstrProfiling.cpp index 2a3d15421de..a68fd3db6c2 100644 --- a/lib/Transforms/Instrumentation/InstrProfiling.cpp +++ b/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(); }; @@ -143,10 +144,10 @@ bool InstrProfiling::runOnModule(Module &M) { void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) { GlobalVariable *Counters = getOrCreateRegionCounters(Inc); - IRBuilder<> Builder(Inc->getParent(), *Inc); + IRBuilder<> Builder(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,17 @@ 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. Place them in a COMDAT group + // if the associated function is a COMDAT. This will make sure that + // only one copy of counters of the COMDAT function will be emitted after + // linking. + Function *Fn = Inc->getParent()->getParent(); + Comdat *ProfileVarsComdat = nullptr; + if (Fn->hasComdat()) + ProfileVarsComdat = M->getOrInsertComdat(StringRef(getVarName(Inc, "vars"))); Name->setSection(getNameSection()); Name->setAlignment(1); + Name->setComdat(ProfileVarsComdat); uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); LLVMContext &Ctx = M->getContext(); @@ -210,6 +219,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { Counters->setVisibility(Name->getVisibility()); Counters->setSection(getCountersSection()); Counters->setAlignment(8); + Counters->setComdat(ProfileVarsComdat); RegionCounters[Inc->getName()] = Counters; @@ -234,6 +244,7 @@ InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { Data->setVisibility(Name->getVisibility()); Data->setSection(getDataSection()); Data->setAlignment(8); + Data->setComdat(ProfileVarsComdat); // Mark the data variable as used so that it isn't stripped out. UsedVars.push_back(Data); @@ -246,6 +257,11 @@ void InstrProfiling::emitRegistration() { if (Triple(M->getTargetTriple()).isOSDarwin()) return; + // Use linker script magic to get data/cnts/name start/end. + if (Triple(M->getTargetTriple()).isOSLinux() || + Triple(M->getTargetTriple()).isOSFreeBSD()) + return; + // Construct the function. auto *VoidTy = Type::getVoidTy(M->getContext()); auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext()); @@ -256,7 +272,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 +304,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 +319,7 @@ void InstrProfiling::emitUses() { return; GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used"); - std::vector MergedVars; + std::vector MergedVars; if (LLVMUsed) { // Collect the existing members of llvm.used. ConstantArray *Inits = cast(LLVMUsed->getInitializer()); @@ -315,20 +332,22 @@ void InstrProfiling::emitUses() { // Add uses for our data. for (auto *Value : UsedVars) MergedVars.push_back( - ConstantExpr::getBitCast(cast(Value), i8PTy)); + ConstantExpr::getBitCast(cast(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 +362,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);