161ba2e39SJustin Bogner //===-- InstrProfiling.cpp - Frontend instrumentation based profiling -----===// 261ba2e39SJustin Bogner // 361ba2e39SJustin Bogner // The LLVM Compiler Infrastructure 461ba2e39SJustin Bogner // 561ba2e39SJustin Bogner // This file is distributed under the University of Illinois Open Source 661ba2e39SJustin Bogner // License. See LICENSE.TXT for details. 761ba2e39SJustin Bogner // 861ba2e39SJustin Bogner //===----------------------------------------------------------------------===// 961ba2e39SJustin Bogner // 1061ba2e39SJustin Bogner // This pass lowers instrprof_increment intrinsics emitted by a frontend for 1161ba2e39SJustin Bogner // profiling. It also builds the data structures and initialization code needed 1261ba2e39SJustin Bogner // for updating execution counts and emitting the profile at runtime. 1361ba2e39SJustin Bogner // 1461ba2e39SJustin Bogner //===----------------------------------------------------------------------===// 1561ba2e39SJustin Bogner 1661ba2e39SJustin Bogner #include "llvm/Transforms/Instrumentation.h" 1761ba2e39SJustin Bogner 1861ba2e39SJustin Bogner #include "llvm/ADT/Triple.h" 1961ba2e39SJustin Bogner #include "llvm/IR/IRBuilder.h" 2061ba2e39SJustin Bogner #include "llvm/IR/IntrinsicInst.h" 2161ba2e39SJustin Bogner #include "llvm/IR/Module.h" 2261ba2e39SJustin Bogner #include "llvm/Transforms/Utils/ModuleUtils.h" 2361ba2e39SJustin Bogner 2461ba2e39SJustin Bogner using namespace llvm; 2561ba2e39SJustin Bogner 2661ba2e39SJustin Bogner #define DEBUG_TYPE "instrprof" 2761ba2e39SJustin Bogner 2861ba2e39SJustin Bogner namespace { 2961ba2e39SJustin Bogner 3061ba2e39SJustin Bogner class InstrProfiling : public ModulePass { 3161ba2e39SJustin Bogner public: 3261ba2e39SJustin Bogner static char ID; 3361ba2e39SJustin Bogner 3461ba2e39SJustin Bogner InstrProfiling() : ModulePass(ID) {} 3561ba2e39SJustin Bogner 3661ba2e39SJustin Bogner InstrProfiling(const InstrProfOptions &Options) 3761ba2e39SJustin Bogner : ModulePass(ID), Options(Options) {} 3861ba2e39SJustin Bogner 3961ba2e39SJustin Bogner const char *getPassName() const override { 4061ba2e39SJustin Bogner return "Frontend instrumentation-based coverage lowering"; 4161ba2e39SJustin Bogner } 4261ba2e39SJustin Bogner 4361ba2e39SJustin Bogner bool runOnModule(Module &M) override; 4461ba2e39SJustin Bogner 4561ba2e39SJustin Bogner void getAnalysisUsage(AnalysisUsage &AU) const override { 4661ba2e39SJustin Bogner AU.setPreservesCFG(); 4761ba2e39SJustin Bogner } 4861ba2e39SJustin Bogner 4961ba2e39SJustin Bogner private: 5061ba2e39SJustin Bogner InstrProfOptions Options; 5161ba2e39SJustin Bogner Module *M; 5261ba2e39SJustin Bogner DenseMap<GlobalVariable *, GlobalVariable *> RegionCounters; 5361ba2e39SJustin Bogner std::vector<Value *> UsedVars; 5461ba2e39SJustin Bogner 5561ba2e39SJustin Bogner bool isMachO() const { 5661ba2e39SJustin Bogner return Triple(M->getTargetTriple()).isOSBinFormatMachO(); 5761ba2e39SJustin Bogner } 5861ba2e39SJustin Bogner 5961ba2e39SJustin Bogner /// Get the section name for the counter variables. 6061ba2e39SJustin Bogner StringRef getCountersSection() const { 6161ba2e39SJustin Bogner return isMachO() ? "__DATA,__llvm_prf_cnts" : "__llvm_prf_cnts"; 6261ba2e39SJustin Bogner } 6361ba2e39SJustin Bogner 6461ba2e39SJustin Bogner /// Get the section name for the name variables. 6561ba2e39SJustin Bogner StringRef getNameSection() const { 6661ba2e39SJustin Bogner return isMachO() ? "__DATA,__llvm_prf_names" : "__llvm_prf_names"; 6761ba2e39SJustin Bogner } 6861ba2e39SJustin Bogner 6961ba2e39SJustin Bogner /// Get the section name for the profile data variables. 7061ba2e39SJustin Bogner StringRef getDataSection() const { 7161ba2e39SJustin Bogner return isMachO() ? "__DATA,__llvm_prf_data" : "__llvm_prf_data"; 7261ba2e39SJustin Bogner } 7361ba2e39SJustin Bogner 74d24e1857SJustin Bogner /// Get the section name for the coverage mapping data. 75d24e1857SJustin Bogner StringRef getCoverageSection() const { 76d24e1857SJustin Bogner return isMachO() ? "__DATA,__llvm_covmap" : "__llvm_covmap"; 77d24e1857SJustin Bogner } 78d24e1857SJustin Bogner 7961ba2e39SJustin Bogner /// Replace instrprof_increment with an increment of the appropriate value. 8061ba2e39SJustin Bogner void lowerIncrement(InstrProfIncrementInst *Inc); 8161ba2e39SJustin Bogner 82d24e1857SJustin Bogner /// Set up the section and uses for coverage data and its references. 83d24e1857SJustin Bogner void lowerCoverageData(GlobalVariable *CoverageData); 84d24e1857SJustin Bogner 8561ba2e39SJustin Bogner /// Get the region counters for an increment, creating them if necessary. 8661ba2e39SJustin Bogner /// 8761ba2e39SJustin Bogner /// If the counter array doesn't yet exist, the profile data variables 8861ba2e39SJustin Bogner /// referring to them will also be created. 8961ba2e39SJustin Bogner GlobalVariable *getOrCreateRegionCounters(InstrProfIncrementInst *Inc); 9061ba2e39SJustin Bogner 9161ba2e39SJustin Bogner /// Emit runtime registration functions for each profile data variable. 9261ba2e39SJustin Bogner void emitRegistration(); 9361ba2e39SJustin Bogner 9461ba2e39SJustin Bogner /// Emit the necessary plumbing to pull in the runtime initialization. 9561ba2e39SJustin Bogner void emitRuntimeHook(); 9661ba2e39SJustin Bogner 9761ba2e39SJustin Bogner /// Add uses of our data variables and runtime hook. 9861ba2e39SJustin Bogner void emitUses(); 9961ba2e39SJustin Bogner 10061ba2e39SJustin Bogner /// Create a static initializer for our data, on platforms that need it. 10161ba2e39SJustin Bogner void emitInitialization(); 10261ba2e39SJustin Bogner }; 10361ba2e39SJustin Bogner 10461ba2e39SJustin Bogner } // anonymous namespace 10561ba2e39SJustin Bogner 10661ba2e39SJustin Bogner char InstrProfiling::ID = 0; 10761ba2e39SJustin Bogner INITIALIZE_PASS(InstrProfiling, "instrprof", 10861ba2e39SJustin Bogner "Frontend instrumentation-based coverage lowering.", false, 10961ba2e39SJustin Bogner false) 11061ba2e39SJustin Bogner 11161ba2e39SJustin Bogner ModulePass *llvm::createInstrProfilingPass(const InstrProfOptions &Options) { 11261ba2e39SJustin Bogner return new InstrProfiling(Options); 11361ba2e39SJustin Bogner } 11461ba2e39SJustin Bogner 11561ba2e39SJustin Bogner bool InstrProfiling::runOnModule(Module &M) { 11661ba2e39SJustin Bogner bool MadeChange = false; 11761ba2e39SJustin Bogner 11861ba2e39SJustin Bogner this->M = &M; 11961ba2e39SJustin Bogner RegionCounters.clear(); 12061ba2e39SJustin Bogner UsedVars.clear(); 12161ba2e39SJustin Bogner 12261ba2e39SJustin Bogner for (Function &F : M) 12361ba2e39SJustin Bogner for (BasicBlock &BB : F) 12461ba2e39SJustin Bogner for (auto I = BB.begin(), E = BB.end(); I != E;) 12561ba2e39SJustin Bogner if (auto *Inc = dyn_cast<InstrProfIncrementInst>(I++)) { 12661ba2e39SJustin Bogner lowerIncrement(Inc); 12761ba2e39SJustin Bogner MadeChange = true; 12861ba2e39SJustin Bogner } 129d24e1857SJustin Bogner if (GlobalVariable *Coverage = M.getNamedGlobal("__llvm_coverage_mapping")) { 130d24e1857SJustin Bogner lowerCoverageData(Coverage); 131d24e1857SJustin Bogner MadeChange = true; 132d24e1857SJustin Bogner } 13361ba2e39SJustin Bogner if (!MadeChange) 13461ba2e39SJustin Bogner return false; 13561ba2e39SJustin Bogner 13661ba2e39SJustin Bogner emitRegistration(); 13761ba2e39SJustin Bogner emitRuntimeHook(); 13861ba2e39SJustin Bogner emitUses(); 13961ba2e39SJustin Bogner emitInitialization(); 14061ba2e39SJustin Bogner return true; 14161ba2e39SJustin Bogner } 14261ba2e39SJustin Bogner 14361ba2e39SJustin Bogner void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) { 14461ba2e39SJustin Bogner GlobalVariable *Counters = getOrCreateRegionCounters(Inc); 14561ba2e39SJustin Bogner 14661ba2e39SJustin Bogner IRBuilder<> Builder(Inc->getParent(), *Inc); 14761ba2e39SJustin Bogner uint64_t Index = Inc->getIndex()->getZExtValue(); 14861ba2e39SJustin Bogner llvm::Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters, 0, Index); 14961ba2e39SJustin Bogner llvm::Value *Count = Builder.CreateLoad(Addr, "pgocount"); 15061ba2e39SJustin Bogner Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 15161ba2e39SJustin Bogner Inc->replaceAllUsesWith(Builder.CreateStore(Count, Addr)); 15261ba2e39SJustin Bogner Inc->eraseFromParent(); 15361ba2e39SJustin Bogner } 15461ba2e39SJustin Bogner 155d24e1857SJustin Bogner void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageData) { 156d24e1857SJustin Bogner CoverageData->setSection(getCoverageSection()); 157d24e1857SJustin Bogner CoverageData->setAlignment(8); 158d24e1857SJustin Bogner 159d24e1857SJustin Bogner Constant *Init = CoverageData->getInitializer(); 160d24e1857SJustin Bogner // We're expecting { i32, i32, i32, i32, [n x { i8*, i32, i32 }], [m x i8] } 161d24e1857SJustin Bogner // for some C. If not, the frontend's given us something broken. 162d24e1857SJustin Bogner assert(Init->getNumOperands() == 6 && "bad number of fields in coverage map"); 163d24e1857SJustin Bogner assert(isa<ConstantArray>(Init->getAggregateElement(4)) && 164d24e1857SJustin Bogner "invalid function list in coverage map"); 165d24e1857SJustin Bogner ConstantArray *Records = cast<ConstantArray>(Init->getAggregateElement(4)); 166d24e1857SJustin Bogner for (unsigned I = 0, E = Records->getNumOperands(); I < E; ++I) { 167d24e1857SJustin Bogner Constant *Record = Records->getOperand(I); 168d24e1857SJustin Bogner Value *V = const_cast<Value *>(Record->getOperand(0))->stripPointerCasts(); 169d24e1857SJustin Bogner 170d24e1857SJustin Bogner assert(isa<GlobalVariable>(V) && "Missing reference to function name"); 171d24e1857SJustin Bogner GlobalVariable *Name = cast<GlobalVariable>(V); 172d24e1857SJustin Bogner 173d24e1857SJustin Bogner // If we have region counters for this name, we've already handled it. 174d24e1857SJustin Bogner auto It = RegionCounters.find(Name); 175d24e1857SJustin Bogner if (It != RegionCounters.end()) 176d24e1857SJustin Bogner continue; 177d24e1857SJustin Bogner 178d24e1857SJustin Bogner // Move the name variable to the right section. 179d24e1857SJustin Bogner Name->setSection(getNameSection()); 180d24e1857SJustin Bogner Name->setAlignment(1); 181d24e1857SJustin Bogner } 182d24e1857SJustin Bogner } 183d24e1857SJustin Bogner 18461ba2e39SJustin Bogner /// Get the name of a profiling variable for a particular function. 18561ba2e39SJustin Bogner static std::string getVarName(InstrProfIncrementInst *Inc, StringRef VarName) { 18661ba2e39SJustin Bogner auto *Arr = cast<ConstantDataArray>(Inc->getName()->getInitializer()); 18761ba2e39SJustin Bogner StringRef Name = Arr->isCString() ? Arr->getAsCString() : Arr->getAsString(); 18861ba2e39SJustin Bogner return ("__llvm_profile_" + VarName + "_" + Name).str(); 18961ba2e39SJustin Bogner } 19061ba2e39SJustin Bogner 19161ba2e39SJustin Bogner GlobalVariable * 19261ba2e39SJustin Bogner InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { 19361ba2e39SJustin Bogner GlobalVariable *Name = Inc->getName(); 19461ba2e39SJustin Bogner auto It = RegionCounters.find(Name); 19561ba2e39SJustin Bogner if (It != RegionCounters.end()) 19661ba2e39SJustin Bogner return It->second; 19761ba2e39SJustin Bogner 19861ba2e39SJustin Bogner // Move the name variable to the right section. 19961ba2e39SJustin Bogner Name->setSection(getNameSection()); 20061ba2e39SJustin Bogner Name->setAlignment(1); 20161ba2e39SJustin Bogner 20261ba2e39SJustin Bogner uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); 20361ba2e39SJustin Bogner LLVMContext &Ctx = M->getContext(); 20461ba2e39SJustin Bogner ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters); 20561ba2e39SJustin Bogner 20661ba2e39SJustin Bogner // Create the counters variable. 20761ba2e39SJustin Bogner auto *Counters = new GlobalVariable(*M, CounterTy, false, Name->getLinkage(), 20861ba2e39SJustin Bogner Constant::getNullValue(CounterTy), 20961ba2e39SJustin Bogner getVarName(Inc, "counters")); 21061ba2e39SJustin Bogner Counters->setVisibility(Name->getVisibility()); 21161ba2e39SJustin Bogner Counters->setSection(getCountersSection()); 21261ba2e39SJustin Bogner Counters->setAlignment(8); 21361ba2e39SJustin Bogner 21461ba2e39SJustin Bogner RegionCounters[Inc->getName()] = Counters; 21561ba2e39SJustin Bogner 21661ba2e39SJustin Bogner // Create data variable. 21761ba2e39SJustin Bogner auto *NameArrayTy = Name->getType()->getPointerElementType(); 21861ba2e39SJustin Bogner auto *Int32Ty = Type::getInt32Ty(Ctx); 21961ba2e39SJustin Bogner auto *Int64Ty = Type::getInt64Ty(Ctx); 22061ba2e39SJustin Bogner auto *Int8PtrTy = Type::getInt8PtrTy(Ctx); 22161ba2e39SJustin Bogner auto *Int64PtrTy = Type::getInt64PtrTy(Ctx); 22261ba2e39SJustin Bogner 22361ba2e39SJustin Bogner Type *DataTypes[] = {Int32Ty, Int32Ty, Int64Ty, Int8PtrTy, Int64PtrTy}; 22461ba2e39SJustin Bogner auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes)); 22561ba2e39SJustin Bogner Constant *DataVals[] = { 22661ba2e39SJustin Bogner ConstantInt::get(Int32Ty, NameArrayTy->getArrayNumElements()), 22761ba2e39SJustin Bogner ConstantInt::get(Int32Ty, NumCounters), 22861ba2e39SJustin Bogner ConstantInt::get(Int64Ty, Inc->getHash()->getZExtValue()), 22961ba2e39SJustin Bogner ConstantExpr::getBitCast(Name, Int8PtrTy), 23061ba2e39SJustin Bogner ConstantExpr::getBitCast(Counters, Int64PtrTy)}; 23161ba2e39SJustin Bogner auto *Data = new GlobalVariable(*M, DataTy, true, Name->getLinkage(), 23261ba2e39SJustin Bogner ConstantStruct::get(DataTy, DataVals), 23361ba2e39SJustin Bogner getVarName(Inc, "data")); 23461ba2e39SJustin Bogner Data->setVisibility(Name->getVisibility()); 23561ba2e39SJustin Bogner Data->setSection(getDataSection()); 23661ba2e39SJustin Bogner Data->setAlignment(8); 23761ba2e39SJustin Bogner 23861ba2e39SJustin Bogner // Mark the data variable as used so that it isn't stripped out. 23961ba2e39SJustin Bogner UsedVars.push_back(Data); 24061ba2e39SJustin Bogner 24161ba2e39SJustin Bogner return Counters; 24261ba2e39SJustin Bogner } 24361ba2e39SJustin Bogner 24461ba2e39SJustin Bogner void InstrProfiling::emitRegistration() { 24561ba2e39SJustin Bogner // Don't do this for Darwin. compiler-rt uses linker magic. 24661ba2e39SJustin Bogner if (Triple(M->getTargetTriple()).isOSDarwin()) 24761ba2e39SJustin Bogner return; 24861ba2e39SJustin Bogner 24961ba2e39SJustin Bogner // Construct the function. 25061ba2e39SJustin Bogner auto *VoidTy = Type::getVoidTy(M->getContext()); 25161ba2e39SJustin Bogner auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext()); 25261ba2e39SJustin Bogner auto *RegisterFTy = FunctionType::get(VoidTy, false); 25361ba2e39SJustin Bogner auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage, 25461ba2e39SJustin Bogner "__llvm_profile_register_functions", M); 25561ba2e39SJustin Bogner RegisterF->setUnnamedAddr(true); 25661ba2e39SJustin Bogner if (Options.NoRedZone) 25761ba2e39SJustin Bogner RegisterF->addFnAttr(Attribute::NoRedZone); 25861ba2e39SJustin Bogner 25961ba2e39SJustin Bogner auto *RuntimeRegisterTy = llvm::FunctionType::get(VoidTy, VoidPtrTy, false); 26061ba2e39SJustin Bogner auto *RuntimeRegisterF = 26161ba2e39SJustin Bogner Function::Create(RuntimeRegisterTy, GlobalVariable::ExternalLinkage, 26261ba2e39SJustin Bogner "__llvm_profile_register_function", M); 26361ba2e39SJustin Bogner 26461ba2e39SJustin Bogner IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", RegisterF)); 26561ba2e39SJustin Bogner for (Value *Data : UsedVars) 26661ba2e39SJustin Bogner IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy)); 26761ba2e39SJustin Bogner IRB.CreateRetVoid(); 26861ba2e39SJustin Bogner } 26961ba2e39SJustin Bogner 27061ba2e39SJustin Bogner void InstrProfiling::emitRuntimeHook() { 27161ba2e39SJustin Bogner const char *const RuntimeVarName = "__llvm_profile_runtime"; 27261ba2e39SJustin Bogner const char *const RuntimeUserName = "__llvm_profile_runtime_user"; 27361ba2e39SJustin Bogner 27461ba2e39SJustin Bogner // If the module's provided its own runtime, we don't need to do anything. 27561ba2e39SJustin Bogner if (M->getGlobalVariable(RuntimeVarName)) 27661ba2e39SJustin Bogner return; 27761ba2e39SJustin Bogner 27861ba2e39SJustin Bogner // Declare an external variable that will pull in the runtime initialization. 27961ba2e39SJustin Bogner auto *Int32Ty = Type::getInt32Ty(M->getContext()); 28061ba2e39SJustin Bogner auto *Var = 28161ba2e39SJustin Bogner new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage, 28261ba2e39SJustin Bogner nullptr, RuntimeVarName); 28361ba2e39SJustin Bogner 28461ba2e39SJustin Bogner // Make a function that uses it. 28561ba2e39SJustin Bogner auto *User = 28661ba2e39SJustin Bogner Function::Create(FunctionType::get(Int32Ty, false), 28761ba2e39SJustin Bogner GlobalValue::LinkOnceODRLinkage, RuntimeUserName, M); 28861ba2e39SJustin Bogner User->addFnAttr(Attribute::NoInline); 28961ba2e39SJustin Bogner if (Options.NoRedZone) 29061ba2e39SJustin Bogner User->addFnAttr(Attribute::NoRedZone); 291*2e427d4dSJustin Bogner User->setVisibility(GlobalValue::HiddenVisibility); 29261ba2e39SJustin Bogner 29361ba2e39SJustin Bogner IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", User)); 29461ba2e39SJustin Bogner auto *Load = IRB.CreateLoad(Var); 29561ba2e39SJustin Bogner IRB.CreateRet(Load); 29661ba2e39SJustin Bogner 29761ba2e39SJustin Bogner // Mark the user variable as used so that it isn't stripped out. 29861ba2e39SJustin Bogner UsedVars.push_back(User); 29961ba2e39SJustin Bogner } 30061ba2e39SJustin Bogner 30161ba2e39SJustin Bogner void InstrProfiling::emitUses() { 30261ba2e39SJustin Bogner if (UsedVars.empty()) 30361ba2e39SJustin Bogner return; 30461ba2e39SJustin Bogner 30561ba2e39SJustin Bogner GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used"); 30661ba2e39SJustin Bogner std::vector<Constant*> MergedVars; 30761ba2e39SJustin Bogner if (LLVMUsed) { 30861ba2e39SJustin Bogner // Collect the existing members of llvm.used. 30961ba2e39SJustin Bogner ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); 31061ba2e39SJustin Bogner for (unsigned I = 0, E = Inits->getNumOperands(); I != E; ++I) 31161ba2e39SJustin Bogner MergedVars.push_back(Inits->getOperand(I)); 31261ba2e39SJustin Bogner LLVMUsed->eraseFromParent(); 31361ba2e39SJustin Bogner } 31461ba2e39SJustin Bogner 31561ba2e39SJustin Bogner Type *i8PTy = Type::getInt8PtrTy(M->getContext()); 31661ba2e39SJustin Bogner // Add uses for our data. 31761ba2e39SJustin Bogner for (auto *Value : UsedVars) 31861ba2e39SJustin Bogner MergedVars.push_back( 31961ba2e39SJustin Bogner ConstantExpr::getBitCast(cast<llvm::Constant>(Value), i8PTy)); 32061ba2e39SJustin Bogner 32161ba2e39SJustin Bogner // Recreate llvm.used. 32261ba2e39SJustin Bogner ArrayType *ATy = ArrayType::get(i8PTy, MergedVars.size()); 32361ba2e39SJustin Bogner LLVMUsed = new llvm::GlobalVariable( 32461ba2e39SJustin Bogner *M, ATy, false, llvm::GlobalValue::AppendingLinkage, 32561ba2e39SJustin Bogner llvm::ConstantArray::get(ATy, MergedVars), "llvm.used"); 32661ba2e39SJustin Bogner 32761ba2e39SJustin Bogner LLVMUsed->setSection("llvm.metadata"); 32861ba2e39SJustin Bogner } 32961ba2e39SJustin Bogner 33061ba2e39SJustin Bogner void InstrProfiling::emitInitialization() { 33161ba2e39SJustin Bogner Constant *RegisterF = M->getFunction("__llvm_profile_register_functions"); 33261ba2e39SJustin Bogner if (!RegisterF) 33361ba2e39SJustin Bogner return; 33461ba2e39SJustin Bogner 33561ba2e39SJustin Bogner // Create the initialization function. 33661ba2e39SJustin Bogner auto *VoidTy = Type::getVoidTy(M->getContext()); 33761ba2e39SJustin Bogner auto *F = 33861ba2e39SJustin Bogner Function::Create(FunctionType::get(VoidTy, false), 33961ba2e39SJustin Bogner GlobalValue::InternalLinkage, "__llvm_profile_init", M); 34061ba2e39SJustin Bogner F->setUnnamedAddr(true); 34161ba2e39SJustin Bogner F->addFnAttr(Attribute::NoInline); 34261ba2e39SJustin Bogner if (Options.NoRedZone) 34361ba2e39SJustin Bogner F->addFnAttr(Attribute::NoRedZone); 34461ba2e39SJustin Bogner 34561ba2e39SJustin Bogner // Add the basic block and the necessary calls. 34661ba2e39SJustin Bogner IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", F)); 34761ba2e39SJustin Bogner IRB.CreateCall(RegisterF); 34861ba2e39SJustin Bogner IRB.CreateRetVoid(); 34961ba2e39SJustin Bogner 35061ba2e39SJustin Bogner appendToGlobalCtors(*M, F, 0); 35161ba2e39SJustin Bogner } 352