1 //===-- InstrProfiling.cpp - Frontend instrumentation based profiling -----===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This pass lowers instrprof_* intrinsics emitted by a frontend for profiling. 11 // It also builds the data structures and initialization code needed for 12 // updating execution counts and emitting the profile at runtime. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/ADT/Triple.h" 17 #include "llvm/IR/IRBuilder.h" 18 #include "llvm/IR/IntrinsicInst.h" 19 #include "llvm/IR/Module.h" 20 #include "llvm/ProfileData/InstrProf.h" 21 #include "llvm/Transforms/Instrumentation.h" 22 #include "llvm/Transforms/Utils/ModuleUtils.h" 23 24 using namespace llvm; 25 26 #define DEBUG_TYPE "instrprof" 27 28 namespace { 29 30 class InstrProfiling : public ModulePass { 31 public: 32 static char ID; 33 34 InstrProfiling() : ModulePass(ID) {} 35 36 InstrProfiling(const InstrProfOptions &Options) 37 : ModulePass(ID), Options(Options) {} 38 39 const char *getPassName() const override { 40 return "Frontend instrumentation-based coverage lowering"; 41 } 42 43 bool runOnModule(Module &M) override; 44 45 void getAnalysisUsage(AnalysisUsage &AU) const override { 46 AU.setPreservesCFG(); 47 } 48 49 private: 50 InstrProfOptions Options; 51 Module *M; 52 typedef struct PerFunctionProfileData { 53 uint32_t NumValueSites[IPVK_Last+1]; 54 GlobalVariable* RegionCounters; 55 GlobalVariable* DataVar; 56 PerFunctionProfileData() : RegionCounters(nullptr), DataVar(nullptr) { 57 memset(NumValueSites, 0, sizeof(uint32_t) * (IPVK_Last+1)); 58 } 59 } PerFunctionProfileData; 60 DenseMap<GlobalVariable *, PerFunctionProfileData> ProfileDataMap; 61 std::vector<Value *> UsedVars; 62 63 bool isMachO() const { 64 return Triple(M->getTargetTriple()).isOSBinFormatMachO(); 65 } 66 67 /// Get the section name for the counter variables. 68 StringRef getCountersSection() const { 69 return getInstrProfCountersSectionName(isMachO()); 70 } 71 72 /// Get the section name for the name variables. 73 StringRef getNameSection() const { 74 return getInstrProfNameSectionName(isMachO()); 75 } 76 77 /// Get the section name for the profile data variables. 78 StringRef getDataSection() const { 79 return getInstrProfDataSectionName(isMachO()); 80 } 81 82 /// Get the section name for the coverage mapping data. 83 StringRef getCoverageSection() const { 84 return getInstrProfCoverageSectionName(isMachO()); 85 } 86 87 /// Count the number of instrumented value sites for the function. 88 void computeNumValueSiteCounts(InstrProfValueProfileInst *Ins); 89 90 /// Replace instrprof_value_profile with a call to runtime library. 91 void lowerValueProfileInst(InstrProfValueProfileInst *Ins); 92 93 /// Replace instrprof_increment with an increment of the appropriate value. 94 void lowerIncrement(InstrProfIncrementInst *Inc); 95 96 /// Force emitting of name vars for unused functions. 97 void lowerCoverageData(GlobalVariable *CoverageNamesVar); 98 99 /// Get the region counters for an increment, creating them if necessary. 100 /// 101 /// If the counter array doesn't yet exist, the profile data variables 102 /// referring to them will also be created. 103 GlobalVariable *getOrCreateRegionCounters(InstrProfIncrementInst *Inc); 104 105 /// Emit runtime registration functions for each profile data variable. 106 void emitRegistration(); 107 108 /// Emit the necessary plumbing to pull in the runtime initialization. 109 void emitRuntimeHook(); 110 111 /// Add uses of our data variables and runtime hook. 112 void emitUses(); 113 114 /// Create a static initializer for our data, on platforms that need it, 115 /// and for any profile output file that was specified. 116 void emitInitialization(); 117 }; 118 119 } // anonymous namespace 120 121 char InstrProfiling::ID = 0; 122 INITIALIZE_PASS(InstrProfiling, "instrprof", 123 "Frontend instrumentation-based coverage lowering.", false, 124 false) 125 126 ModulePass *llvm::createInstrProfilingPass(const InstrProfOptions &Options) { 127 return new InstrProfiling(Options); 128 } 129 130 bool InstrProfiling::runOnModule(Module &M) { 131 bool MadeChange = false; 132 133 this->M = &M; 134 ProfileDataMap.clear(); 135 UsedVars.clear(); 136 137 // We did not know how many value sites there would be inside 138 // the instrumented function. This is counting the number of instrumented 139 // target value sites to enter it as field in the profile data variable. 140 for (Function &F : M) { 141 InstrProfIncrementInst *FirstProfIncInst = nullptr; 142 for (BasicBlock &BB : F) 143 for (auto I = BB.begin(), E = BB.end(); I != E; I++) 144 if (auto *Ind = dyn_cast<InstrProfValueProfileInst>(I)) 145 computeNumValueSiteCounts(Ind); 146 else if (FirstProfIncInst == nullptr) 147 FirstProfIncInst = dyn_cast<InstrProfIncrementInst>(I); 148 149 // Value profiling intrinsic lowering requires per-function profile data 150 // variable to be created first. 151 if (FirstProfIncInst != nullptr) 152 static_cast<void>(getOrCreateRegionCounters(FirstProfIncInst)); 153 } 154 155 for (Function &F : M) 156 for (BasicBlock &BB : F) 157 for (auto I = BB.begin(), E = BB.end(); I != E;) { 158 auto Instr = I++; 159 if (auto *Inc = dyn_cast<InstrProfIncrementInst>(Instr)) { 160 lowerIncrement(Inc); 161 MadeChange = true; 162 } else if (auto *Ind = dyn_cast<InstrProfValueProfileInst>(Instr)) { 163 lowerValueProfileInst(Ind); 164 MadeChange = true; 165 } 166 } 167 168 if (GlobalVariable *CoverageNamesVar = 169 M.getNamedGlobal(getCoverageUnusedNamesVarName())) { 170 lowerCoverageData(CoverageNamesVar); 171 MadeChange = true; 172 } 173 174 if (!MadeChange) 175 return false; 176 177 emitRegistration(); 178 emitRuntimeHook(); 179 emitUses(); 180 emitInitialization(); 181 return true; 182 } 183 184 static Constant *getOrInsertValueProfilingCall(Module &M) { 185 LLVMContext &Ctx = M.getContext(); 186 auto *ReturnTy = Type::getVoidTy(M.getContext()); 187 Type *ParamTypes[] = { 188 #define VALUE_PROF_FUNC_PARAM(ParamType, ParamName, ParamLLVMType) ParamLLVMType 189 #include "llvm/ProfileData/InstrProfData.inc" 190 }; 191 auto *ValueProfilingCallTy = 192 FunctionType::get(ReturnTy, makeArrayRef(ParamTypes), false); 193 return M.getOrInsertFunction(getInstrProfValueProfFuncName(), 194 ValueProfilingCallTy); 195 } 196 197 void InstrProfiling::computeNumValueSiteCounts(InstrProfValueProfileInst *Ind) { 198 199 GlobalVariable *Name = Ind->getName(); 200 uint64_t ValueKind = Ind->getValueKind()->getZExtValue(); 201 uint64_t Index = Ind->getIndex()->getZExtValue(); 202 auto It = ProfileDataMap.find(Name); 203 if (It == ProfileDataMap.end()) { 204 PerFunctionProfileData PD; 205 PD.NumValueSites[ValueKind] = Index + 1; 206 ProfileDataMap[Name] = PD; 207 } else if (It->second.NumValueSites[ValueKind] <= Index) 208 It->second.NumValueSites[ValueKind] = Index + 1; 209 } 210 211 void InstrProfiling::lowerValueProfileInst(InstrProfValueProfileInst *Ind) { 212 213 GlobalVariable *Name = Ind->getName(); 214 auto It = ProfileDataMap.find(Name); 215 assert(It != ProfileDataMap.end() && It->second.DataVar && 216 "value profiling detected in function with no counter incerement"); 217 218 GlobalVariable *DataVar = It->second.DataVar; 219 uint64_t ValueKind = Ind->getValueKind()->getZExtValue(); 220 uint64_t Index = Ind->getIndex()->getZExtValue(); 221 for (uint32_t Kind = IPVK_First; Kind < ValueKind; ++Kind) 222 Index += It->second.NumValueSites[Kind]; 223 224 IRBuilder<> Builder(Ind); 225 Value* Args[3] = {Ind->getTargetValue(), 226 Builder.CreateBitCast(DataVar, Builder.getInt8PtrTy()), 227 Builder.getInt32(Index)}; 228 Ind->replaceAllUsesWith( 229 Builder.CreateCall(getOrInsertValueProfilingCall(*M), Args)); 230 Ind->eraseFromParent(); 231 } 232 233 void InstrProfiling::lowerIncrement(InstrProfIncrementInst *Inc) { 234 GlobalVariable *Counters = getOrCreateRegionCounters(Inc); 235 236 IRBuilder<> Builder(Inc); 237 uint64_t Index = Inc->getIndex()->getZExtValue(); 238 Value *Addr = Builder.CreateConstInBoundsGEP2_64(Counters, 0, Index); 239 Value *Count = Builder.CreateLoad(Addr, "pgocount"); 240 Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 241 Inc->replaceAllUsesWith(Builder.CreateStore(Count, Addr)); 242 Inc->eraseFromParent(); 243 } 244 245 void InstrProfiling::lowerCoverageData(GlobalVariable *CoverageNamesVar) { 246 247 ConstantArray *Names = 248 cast<ConstantArray>(CoverageNamesVar->getInitializer()); 249 for (unsigned I = 0, E = Names->getNumOperands(); I < E; ++I) { 250 Constant *NC = Names->getOperand(I); 251 Value *V = NC->stripPointerCasts(); 252 assert(isa<GlobalVariable>(V) && "Missing reference to function name"); 253 GlobalVariable *Name = cast<GlobalVariable>(V); 254 255 // Move the name variable to the right section. 256 Name->setSection(getNameSection()); 257 Name->setAlignment(1); 258 } 259 } 260 261 /// Get the name of a profiling variable for a particular function. 262 static std::string getVarName(InstrProfIncrementInst *Inc, StringRef Prefix) { 263 StringRef NamePrefix = getInstrProfNameVarPrefix(); 264 StringRef Name = Inc->getName()->getName().substr(NamePrefix.size()); 265 return (Prefix + Name).str(); 266 } 267 268 static inline bool shouldRecordFunctionAddr(Function *F) { 269 // Check the linkage 270 if (!F->hasLinkOnceLinkage() && !F->hasLocalLinkage() && 271 !F->hasAvailableExternallyLinkage()) 272 return true; 273 // Check uses of this function for other than direct calls or invokes to it. 274 return F->hasAddressTaken(); 275 } 276 277 static inline Comdat *getOrCreateProfileComdat(Module &M, 278 InstrProfIncrementInst *Inc) { 279 // COFF format requires a COMDAT section to have a key symbol with the same 280 // name. The linker targeting COFF also requires that the COMDAT section 281 // a section is associated to must precede the associating section. For this 282 // reason, we must choose the name var's name as the name of the comdat. 283 StringRef ComdatPrefix = (Triple(M.getTargetTriple()).isOSBinFormatCOFF() 284 ? getInstrProfNameVarPrefix() 285 : getInstrProfComdatPrefix()); 286 return M.getOrInsertComdat(StringRef(getVarName(Inc, ComdatPrefix))); 287 } 288 289 GlobalVariable * 290 InstrProfiling::getOrCreateRegionCounters(InstrProfIncrementInst *Inc) { 291 GlobalVariable *NamePtr = Inc->getName(); 292 auto It = ProfileDataMap.find(NamePtr); 293 PerFunctionProfileData PD; 294 if (It != ProfileDataMap.end()) { 295 if (It->second.RegionCounters) 296 return It->second.RegionCounters; 297 PD = It->second; 298 } 299 300 // Move the name variable to the right section. Place them in a COMDAT group 301 // if the associated function is a COMDAT. This will make sure that 302 // only one copy of counters of the COMDAT function will be emitted after 303 // linking. 304 Function *Fn = Inc->getParent()->getParent(); 305 Comdat *ProfileVarsComdat = nullptr; 306 if (Fn->hasComdat()) 307 ProfileVarsComdat = getOrCreateProfileComdat(*M, Inc); 308 NamePtr->setSection(getNameSection()); 309 NamePtr->setAlignment(1); 310 NamePtr->setComdat(ProfileVarsComdat); 311 312 uint64_t NumCounters = Inc->getNumCounters()->getZExtValue(); 313 LLVMContext &Ctx = M->getContext(); 314 ArrayType *CounterTy = ArrayType::get(Type::getInt64Ty(Ctx), NumCounters); 315 316 // Create the counters variable. 317 auto *CounterPtr = 318 new GlobalVariable(*M, CounterTy, false, NamePtr->getLinkage(), 319 Constant::getNullValue(CounterTy), 320 getVarName(Inc, getInstrProfCountersVarPrefix())); 321 CounterPtr->setVisibility(NamePtr->getVisibility()); 322 CounterPtr->setSection(getCountersSection()); 323 CounterPtr->setAlignment(8); 324 CounterPtr->setComdat(ProfileVarsComdat); 325 326 // Create data variable. 327 auto *Int8PtrTy = Type::getInt8PtrTy(Ctx); 328 auto *Int16Ty = Type::getInt16Ty(Ctx); 329 auto *Int16ArrayTy = ArrayType::get(Int16Ty, IPVK_Last+1); 330 Type *DataTypes[] = { 331 #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) LLVMType, 332 #include "llvm/ProfileData/InstrProfData.inc" 333 }; 334 auto *DataTy = StructType::get(Ctx, makeArrayRef(DataTypes)); 335 336 Constant *FunctionAddr = shouldRecordFunctionAddr(Fn) ? 337 ConstantExpr::getBitCast(Fn, Int8PtrTy) : 338 ConstantPointerNull::get(Int8PtrTy); 339 340 Constant *Int16ArrayVals[IPVK_Last+1]; 341 for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) 342 Int16ArrayVals[Kind] = ConstantInt::get(Int16Ty, PD.NumValueSites[Kind]); 343 344 Constant *DataVals[] = { 345 #define INSTR_PROF_DATA(Type, LLVMType, Name, Init) Init, 346 #include "llvm/ProfileData/InstrProfData.inc" 347 }; 348 auto *Data = new GlobalVariable(*M, DataTy, false, NamePtr->getLinkage(), 349 ConstantStruct::get(DataTy, DataVals), 350 getVarName(Inc, getInstrProfDataVarPrefix())); 351 Data->setVisibility(NamePtr->getVisibility()); 352 Data->setSection(getDataSection()); 353 Data->setAlignment(INSTR_PROF_DATA_ALIGNMENT); 354 Data->setComdat(ProfileVarsComdat); 355 356 PD.RegionCounters = CounterPtr; 357 PD.DataVar = Data; 358 ProfileDataMap[NamePtr] = PD; 359 360 // Mark the data variable as used so that it isn't stripped out. 361 UsedVars.push_back(Data); 362 363 return CounterPtr; 364 } 365 366 void InstrProfiling::emitRegistration() { 367 // Don't do this for Darwin. compiler-rt uses linker magic. 368 if (Triple(M->getTargetTriple()).isOSDarwin()) 369 return; 370 371 // Use linker script magic to get data/cnts/name start/end. 372 if (Triple(M->getTargetTriple()).isOSLinux() || 373 Triple(M->getTargetTriple()).isOSFreeBSD()) 374 return; 375 376 // Construct the function. 377 auto *VoidTy = Type::getVoidTy(M->getContext()); 378 auto *VoidPtrTy = Type::getInt8PtrTy(M->getContext()); 379 auto *RegisterFTy = FunctionType::get(VoidTy, false); 380 auto *RegisterF = Function::Create(RegisterFTy, GlobalValue::InternalLinkage, 381 getInstrProfRegFuncsName(), M); 382 RegisterF->setUnnamedAddr(true); 383 if (Options.NoRedZone) RegisterF->addFnAttr(Attribute::NoRedZone); 384 385 auto *RuntimeRegisterTy = FunctionType::get(VoidTy, VoidPtrTy, false); 386 auto *RuntimeRegisterF = 387 Function::Create(RuntimeRegisterTy, GlobalVariable::ExternalLinkage, 388 getInstrProfRegFuncName(), M); 389 390 IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", RegisterF)); 391 for (Value *Data : UsedVars) 392 IRB.CreateCall(RuntimeRegisterF, IRB.CreateBitCast(Data, VoidPtrTy)); 393 IRB.CreateRetVoid(); 394 } 395 396 void InstrProfiling::emitRuntimeHook() { 397 398 // We expect the linker to be invoked with -u<hook_var> flag for linux, 399 // for which case there is no need to emit the user function. 400 if (Triple(M->getTargetTriple()).isOSLinux()) 401 return; 402 403 // If the module's provided its own runtime, we don't need to do anything. 404 if (M->getGlobalVariable(getInstrProfRuntimeHookVarName())) return; 405 406 // Declare an external variable that will pull in the runtime initialization. 407 auto *Int32Ty = Type::getInt32Ty(M->getContext()); 408 auto *Var = 409 new GlobalVariable(*M, Int32Ty, false, GlobalValue::ExternalLinkage, 410 nullptr, getInstrProfRuntimeHookVarName()); 411 412 // Make a function that uses it. 413 auto *User = Function::Create(FunctionType::get(Int32Ty, false), 414 GlobalValue::LinkOnceODRLinkage, 415 getInstrProfRuntimeHookVarUseFuncName(), M); 416 User->addFnAttr(Attribute::NoInline); 417 if (Options.NoRedZone) User->addFnAttr(Attribute::NoRedZone); 418 User->setVisibility(GlobalValue::HiddenVisibility); 419 420 IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", User)); 421 auto *Load = IRB.CreateLoad(Var); 422 IRB.CreateRet(Load); 423 424 // Mark the user variable as used so that it isn't stripped out. 425 UsedVars.push_back(User); 426 } 427 428 void InstrProfiling::emitUses() { 429 if (UsedVars.empty()) 430 return; 431 432 GlobalVariable *LLVMUsed = M->getGlobalVariable("llvm.used"); 433 std::vector<Constant *> MergedVars; 434 if (LLVMUsed) { 435 // Collect the existing members of llvm.used. 436 ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer()); 437 for (unsigned I = 0, E = Inits->getNumOperands(); I != E; ++I) 438 MergedVars.push_back(Inits->getOperand(I)); 439 LLVMUsed->eraseFromParent(); 440 } 441 442 Type *i8PTy = Type::getInt8PtrTy(M->getContext()); 443 // Add uses for our data. 444 for (auto *Value : UsedVars) 445 MergedVars.push_back( 446 ConstantExpr::getBitCast(cast<Constant>(Value), i8PTy)); 447 448 // Recreate llvm.used. 449 ArrayType *ATy = ArrayType::get(i8PTy, MergedVars.size()); 450 LLVMUsed = 451 new GlobalVariable(*M, ATy, false, GlobalValue::AppendingLinkage, 452 ConstantArray::get(ATy, MergedVars), "llvm.used"); 453 LLVMUsed->setSection("llvm.metadata"); 454 } 455 456 void InstrProfiling::emitInitialization() { 457 std::string InstrProfileOutput = Options.InstrProfileOutput; 458 459 Constant *RegisterF = M->getFunction(getInstrProfRegFuncsName()); 460 if (!RegisterF && InstrProfileOutput.empty()) return; 461 462 // Create the initialization function. 463 auto *VoidTy = Type::getVoidTy(M->getContext()); 464 auto *F = Function::Create(FunctionType::get(VoidTy, false), 465 GlobalValue::InternalLinkage, 466 getInstrProfInitFuncName(), M); 467 F->setUnnamedAddr(true); 468 F->addFnAttr(Attribute::NoInline); 469 if (Options.NoRedZone) F->addFnAttr(Attribute::NoRedZone); 470 471 // Add the basic block and the necessary calls. 472 IRBuilder<> IRB(BasicBlock::Create(M->getContext(), "", F)); 473 if (RegisterF) 474 IRB.CreateCall(RegisterF, {}); 475 if (!InstrProfileOutput.empty()) { 476 auto *Int8PtrTy = Type::getInt8PtrTy(M->getContext()); 477 auto *SetNameTy = FunctionType::get(VoidTy, Int8PtrTy, false); 478 auto *SetNameF = Function::Create(SetNameTy, GlobalValue::ExternalLinkage, 479 getInstrProfFileOverriderFuncName(), M); 480 481 // Create variable for profile name. 482 Constant *ProfileNameConst = 483 ConstantDataArray::getString(M->getContext(), InstrProfileOutput, true); 484 GlobalVariable *ProfileName = 485 new GlobalVariable(*M, ProfileNameConst->getType(), true, 486 GlobalValue::PrivateLinkage, ProfileNameConst); 487 488 IRB.CreateCall(SetNameF, IRB.CreatePointerCast(ProfileName, Int8PtrTy)); 489 } 490 IRB.CreateRetVoid(); 491 492 appendToGlobalCtors(*M, F, 0); 493 } 494