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