1 //===- GCOVProfiling.cpp - Insert edge counters for gcov 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 implements GCOV-style profiling. When this pass is run it emits 11 // "gcno" files next to the existing source, and instruments the code that runs 12 // to records the edges between blocks that run and emit a complementary "gcda" 13 // file on exit. 14 // 15 //===----------------------------------------------------------------------===// 16 17 #include "llvm/ADT/DenseMap.h" 18 #include "llvm/ADT/Hashing.h" 19 #include "llvm/ADT/STLExtras.h" 20 #include "llvm/ADT/Sequence.h" 21 #include "llvm/ADT/Statistic.h" 22 #include "llvm/ADT/StringExtras.h" 23 #include "llvm/ADT/StringMap.h" 24 #include "llvm/ADT/UniqueVector.h" 25 #include "llvm/Analysis/EHPersonalities.h" 26 #include "llvm/Analysis/TargetLibraryInfo.h" 27 #include "llvm/IR/DebugInfo.h" 28 #include "llvm/IR/DebugLoc.h" 29 #include "llvm/IR/IRBuilder.h" 30 #include "llvm/IR/InstIterator.h" 31 #include "llvm/IR/Instructions.h" 32 #include "llvm/IR/IntrinsicInst.h" 33 #include "llvm/IR/Module.h" 34 #include "llvm/Pass.h" 35 #include "llvm/Support/CommandLine.h" 36 #include "llvm/Support/Debug.h" 37 #include "llvm/Support/FileSystem.h" 38 #include "llvm/Support/Path.h" 39 #include "llvm/Support/raw_ostream.h" 40 #include "llvm/Transforms/Instrumentation.h" 41 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h" 42 #include "llvm/Transforms/Utils/ModuleUtils.h" 43 #include <algorithm> 44 #include <memory> 45 #include <string> 46 #include <utility> 47 using namespace llvm; 48 49 #define DEBUG_TYPE "insert-gcov-profiling" 50 51 static cl::opt<std::string> 52 DefaultGCOVVersion("default-gcov-version", cl::init("402*"), cl::Hidden, 53 cl::ValueRequired); 54 static cl::opt<bool> DefaultExitBlockBeforeBody("gcov-exit-block-before-body", 55 cl::init(false), cl::Hidden); 56 57 GCOVOptions GCOVOptions::getDefault() { 58 GCOVOptions Options; 59 Options.EmitNotes = true; 60 Options.EmitData = true; 61 Options.UseCfgChecksum = false; 62 Options.NoRedZone = false; 63 Options.FunctionNamesInData = true; 64 Options.ExitBlockBeforeBody = DefaultExitBlockBeforeBody; 65 66 if (DefaultGCOVVersion.size() != 4) { 67 llvm::report_fatal_error(std::string("Invalid -default-gcov-version: ") + 68 DefaultGCOVVersion); 69 } 70 memcpy(Options.Version, DefaultGCOVVersion.c_str(), 4); 71 return Options; 72 } 73 74 namespace { 75 class GCOVFunction; 76 77 class GCOVProfiler { 78 public: 79 GCOVProfiler() : GCOVProfiler(GCOVOptions::getDefault()) {} 80 GCOVProfiler(const GCOVOptions &Opts) : Options(Opts) { 81 assert((Options.EmitNotes || Options.EmitData) && 82 "GCOVProfiler asked to do nothing?"); 83 ReversedVersion[0] = Options.Version[3]; 84 ReversedVersion[1] = Options.Version[2]; 85 ReversedVersion[2] = Options.Version[1]; 86 ReversedVersion[3] = Options.Version[0]; 87 ReversedVersion[4] = '\0'; 88 } 89 bool runOnModule(Module &M, const TargetLibraryInfo &TLI); 90 91 private: 92 // Create the .gcno files for the Module based on DebugInfo. 93 void emitProfileNotes(); 94 95 // Modify the program to track transitions along edges and call into the 96 // profiling runtime to emit .gcda files when run. 97 bool emitProfileArcs(); 98 99 // Get pointers to the functions in the runtime library. 100 Constant *getStartFileFunc(); 101 Constant *getIncrementIndirectCounterFunc(); 102 Constant *getEmitFunctionFunc(); 103 Constant *getEmitArcsFunc(); 104 Constant *getSummaryInfoFunc(); 105 Constant *getEndFileFunc(); 106 107 // Create or retrieve an i32 state value that is used to represent the 108 // pred block number for certain non-trivial edges. 109 GlobalVariable *getEdgeStateValue(); 110 111 // Produce a table of pointers to counters, by predecessor and successor 112 // block number. 113 GlobalVariable *buildEdgeLookupTable(Function *F, GlobalVariable *Counter, 114 const UniqueVector<BasicBlock *> &Preds, 115 const UniqueVector<BasicBlock *> &Succs); 116 117 // Add the function to write out all our counters to the global destructor 118 // list. 119 Function * 120 insertCounterWriteout(ArrayRef<std::pair<GlobalVariable *, MDNode *>>); 121 Function *insertFlush(ArrayRef<std::pair<GlobalVariable *, MDNode *>>); 122 void insertIndirectCounterIncrement(); 123 124 enum class GCovFileType { GCNO, GCDA }; 125 std::string mangleName(const DICompileUnit *CU, GCovFileType FileType); 126 127 GCOVOptions Options; 128 129 // Reversed, NUL-terminated copy of Options.Version. 130 char ReversedVersion[5]; 131 // Checksum, produced by hash of EdgeDestinations 132 SmallVector<uint32_t, 4> FileChecksums; 133 134 Module *M; 135 const TargetLibraryInfo *TLI; 136 LLVMContext *Ctx; 137 SmallVector<std::unique_ptr<GCOVFunction>, 16> Funcs; 138 }; 139 140 class GCOVProfilerLegacyPass : public ModulePass { 141 public: 142 static char ID; 143 GCOVProfilerLegacyPass() 144 : GCOVProfilerLegacyPass(GCOVOptions::getDefault()) {} 145 GCOVProfilerLegacyPass(const GCOVOptions &Opts) 146 : ModulePass(ID), Profiler(Opts) { 147 initializeGCOVProfilerLegacyPassPass(*PassRegistry::getPassRegistry()); 148 } 149 StringRef getPassName() const override { return "GCOV Profiler"; } 150 151 bool runOnModule(Module &M) override { 152 auto &TLI = getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); 153 return Profiler.runOnModule(M, TLI); 154 } 155 156 void getAnalysisUsage(AnalysisUsage &AU) const override { 157 AU.addRequired<TargetLibraryInfoWrapperPass>(); 158 } 159 160 private: 161 GCOVProfiler Profiler; 162 }; 163 } 164 165 char GCOVProfilerLegacyPass::ID = 0; 166 INITIALIZE_PASS_BEGIN( 167 GCOVProfilerLegacyPass, "insert-gcov-profiling", 168 "Insert instrumentation for GCOV profiling", false, false) 169 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) 170 INITIALIZE_PASS_END( 171 GCOVProfilerLegacyPass, "insert-gcov-profiling", 172 "Insert instrumentation for GCOV profiling", false, false) 173 174 ModulePass *llvm::createGCOVProfilerPass(const GCOVOptions &Options) { 175 return new GCOVProfilerLegacyPass(Options); 176 } 177 178 static StringRef getFunctionName(const DISubprogram *SP) { 179 if (!SP->getLinkageName().empty()) 180 return SP->getLinkageName(); 181 return SP->getName(); 182 } 183 184 namespace { 185 class GCOVRecord { 186 protected: 187 static const char *const LinesTag; 188 static const char *const FunctionTag; 189 static const char *const BlockTag; 190 static const char *const EdgeTag; 191 192 GCOVRecord() = default; 193 194 void writeBytes(const char *Bytes, int Size) { 195 os->write(Bytes, Size); 196 } 197 198 void write(uint32_t i) { 199 writeBytes(reinterpret_cast<char*>(&i), 4); 200 } 201 202 // Returns the length measured in 4-byte blocks that will be used to 203 // represent this string in a GCOV file 204 static unsigned lengthOfGCOVString(StringRef s) { 205 // A GCOV string is a length, followed by a NUL, then between 0 and 3 NULs 206 // padding out to the next 4-byte word. The length is measured in 4-byte 207 // words including padding, not bytes of actual string. 208 return (s.size() / 4) + 1; 209 } 210 211 void writeGCOVString(StringRef s) { 212 uint32_t Len = lengthOfGCOVString(s); 213 write(Len); 214 writeBytes(s.data(), s.size()); 215 216 // Write 1 to 4 bytes of NUL padding. 217 assert((unsigned)(4 - (s.size() % 4)) > 0); 218 assert((unsigned)(4 - (s.size() % 4)) <= 4); 219 writeBytes("\0\0\0\0", 4 - (s.size() % 4)); 220 } 221 222 raw_ostream *os; 223 }; 224 const char *const GCOVRecord::LinesTag = "\0\0\x45\x01"; 225 const char *const GCOVRecord::FunctionTag = "\0\0\0\1"; 226 const char *const GCOVRecord::BlockTag = "\0\0\x41\x01"; 227 const char *const GCOVRecord::EdgeTag = "\0\0\x43\x01"; 228 229 class GCOVFunction; 230 class GCOVBlock; 231 232 // Constructed only by requesting it from a GCOVBlock, this object stores a 233 // list of line numbers and a single filename, representing lines that belong 234 // to the block. 235 class GCOVLines : public GCOVRecord { 236 public: 237 void addLine(uint32_t Line) { 238 assert(Line != 0 && "Line zero is not a valid real line number."); 239 Lines.push_back(Line); 240 } 241 242 uint32_t length() const { 243 // Here 2 = 1 for string length + 1 for '0' id#. 244 return lengthOfGCOVString(Filename) + 2 + Lines.size(); 245 } 246 247 void writeOut() { 248 write(0); 249 writeGCOVString(Filename); 250 for (int i = 0, e = Lines.size(); i != e; ++i) 251 write(Lines[i]); 252 } 253 254 GCOVLines(StringRef F, raw_ostream *os) 255 : Filename(F) { 256 this->os = os; 257 } 258 259 private: 260 StringRef Filename; 261 SmallVector<uint32_t, 32> Lines; 262 }; 263 264 265 // Represent a basic block in GCOV. Each block has a unique number in the 266 // function, number of lines belonging to each block, and a set of edges to 267 // other blocks. 268 class GCOVBlock : public GCOVRecord { 269 public: 270 GCOVLines &getFile(StringRef Filename) { 271 return LinesByFile.try_emplace(Filename, Filename, os).first->second; 272 } 273 274 void addEdge(GCOVBlock &Successor) { 275 OutEdges.push_back(&Successor); 276 } 277 278 void writeOut() { 279 uint32_t Len = 3; 280 SmallVector<StringMapEntry<GCOVLines> *, 32> SortedLinesByFile; 281 for (auto &I : LinesByFile) { 282 Len += I.second.length(); 283 SortedLinesByFile.push_back(&I); 284 } 285 286 writeBytes(LinesTag, 4); 287 write(Len); 288 write(Number); 289 290 llvm::sort( 291 SortedLinesByFile.begin(), SortedLinesByFile.end(), 292 [](StringMapEntry<GCOVLines> *LHS, StringMapEntry<GCOVLines> *RHS) { 293 return LHS->getKey() < RHS->getKey(); 294 }); 295 for (auto &I : SortedLinesByFile) 296 I->getValue().writeOut(); 297 write(0); 298 write(0); 299 } 300 301 GCOVBlock(const GCOVBlock &RHS) : GCOVRecord(RHS), Number(RHS.Number) { 302 // Only allow copy before edges and lines have been added. After that, 303 // there are inter-block pointers (eg: edges) that won't take kindly to 304 // blocks being copied or moved around. 305 assert(LinesByFile.empty()); 306 assert(OutEdges.empty()); 307 } 308 309 private: 310 friend class GCOVFunction; 311 312 GCOVBlock(uint32_t Number, raw_ostream *os) 313 : Number(Number) { 314 this->os = os; 315 } 316 317 uint32_t Number; 318 StringMap<GCOVLines> LinesByFile; 319 SmallVector<GCOVBlock *, 4> OutEdges; 320 }; 321 322 // A function has a unique identifier, a checksum (we leave as zero) and a 323 // set of blocks and a map of edges between blocks. This is the only GCOV 324 // object users can construct, the blocks and lines will be rooted here. 325 class GCOVFunction : public GCOVRecord { 326 public: 327 GCOVFunction(const DISubprogram *SP, Function *F, raw_ostream *os, 328 uint32_t Ident, bool UseCfgChecksum, bool ExitBlockBeforeBody) 329 : SP(SP), Ident(Ident), UseCfgChecksum(UseCfgChecksum), CfgChecksum(0), 330 ReturnBlock(1, os) { 331 this->os = os; 332 333 LLVM_DEBUG(dbgs() << "Function: " << getFunctionName(SP) << "\n"); 334 335 uint32_t i = 0; 336 for (auto &BB : *F) { 337 // Skip index 1 if it's assigned to the ReturnBlock. 338 if (i == 1 && ExitBlockBeforeBody) 339 ++i; 340 Blocks.insert(std::make_pair(&BB, GCOVBlock(i++, os))); 341 } 342 if (!ExitBlockBeforeBody) 343 ReturnBlock.Number = i; 344 345 std::string FunctionNameAndLine; 346 raw_string_ostream FNLOS(FunctionNameAndLine); 347 FNLOS << getFunctionName(SP) << SP->getLine(); 348 FNLOS.flush(); 349 FuncChecksum = hash_value(FunctionNameAndLine); 350 } 351 352 GCOVBlock &getBlock(BasicBlock *BB) { 353 return Blocks.find(BB)->second; 354 } 355 356 GCOVBlock &getReturnBlock() { 357 return ReturnBlock; 358 } 359 360 std::string getEdgeDestinations() { 361 std::string EdgeDestinations; 362 raw_string_ostream EDOS(EdgeDestinations); 363 Function *F = Blocks.begin()->first->getParent(); 364 for (BasicBlock &I : *F) { 365 GCOVBlock &Block = getBlock(&I); 366 for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) 367 EDOS << Block.OutEdges[i]->Number; 368 } 369 return EdgeDestinations; 370 } 371 372 uint32_t getFuncChecksum() { 373 return FuncChecksum; 374 } 375 376 void setCfgChecksum(uint32_t Checksum) { 377 CfgChecksum = Checksum; 378 } 379 380 void writeOut() { 381 writeBytes(FunctionTag, 4); 382 uint32_t BlockLen = 1 + 1 + 1 + lengthOfGCOVString(getFunctionName(SP)) + 383 1 + lengthOfGCOVString(SP->getFilename()) + 1; 384 if (UseCfgChecksum) 385 ++BlockLen; 386 write(BlockLen); 387 write(Ident); 388 write(FuncChecksum); 389 if (UseCfgChecksum) 390 write(CfgChecksum); 391 writeGCOVString(getFunctionName(SP)); 392 writeGCOVString(SP->getFilename()); 393 write(SP->getLine()); 394 395 // Emit count of blocks. 396 writeBytes(BlockTag, 4); 397 write(Blocks.size() + 1); 398 for (int i = 0, e = Blocks.size() + 1; i != e; ++i) { 399 write(0); // No flags on our blocks. 400 } 401 LLVM_DEBUG(dbgs() << Blocks.size() << " blocks.\n"); 402 403 // Emit edges between blocks. 404 if (Blocks.empty()) return; 405 Function *F = Blocks.begin()->first->getParent(); 406 for (BasicBlock &I : *F) { 407 GCOVBlock &Block = getBlock(&I); 408 if (Block.OutEdges.empty()) continue; 409 410 writeBytes(EdgeTag, 4); 411 write(Block.OutEdges.size() * 2 + 1); 412 write(Block.Number); 413 for (int i = 0, e = Block.OutEdges.size(); i != e; ++i) { 414 LLVM_DEBUG(dbgs() << Block.Number << " -> " 415 << Block.OutEdges[i]->Number << "\n"); 416 write(Block.OutEdges[i]->Number); 417 write(0); // no flags 418 } 419 } 420 421 // Emit lines for each block. 422 for (BasicBlock &I : *F) 423 getBlock(&I).writeOut(); 424 } 425 426 private: 427 const DISubprogram *SP; 428 uint32_t Ident; 429 uint32_t FuncChecksum; 430 bool UseCfgChecksum; 431 uint32_t CfgChecksum; 432 DenseMap<BasicBlock *, GCOVBlock> Blocks; 433 GCOVBlock ReturnBlock; 434 }; 435 } 436 437 std::string GCOVProfiler::mangleName(const DICompileUnit *CU, 438 GCovFileType OutputType) { 439 bool Notes = OutputType == GCovFileType::GCNO; 440 441 if (NamedMDNode *GCov = M->getNamedMetadata("llvm.gcov")) { 442 for (int i = 0, e = GCov->getNumOperands(); i != e; ++i) { 443 MDNode *N = GCov->getOperand(i); 444 bool ThreeElement = N->getNumOperands() == 3; 445 if (!ThreeElement && N->getNumOperands() != 2) 446 continue; 447 if (dyn_cast<MDNode>(N->getOperand(ThreeElement ? 2 : 1)) != CU) 448 continue; 449 450 if (ThreeElement) { 451 // These nodes have no mangling to apply, it's stored mangled in the 452 // bitcode. 453 MDString *NotesFile = dyn_cast<MDString>(N->getOperand(0)); 454 MDString *DataFile = dyn_cast<MDString>(N->getOperand(1)); 455 if (!NotesFile || !DataFile) 456 continue; 457 return Notes ? NotesFile->getString() : DataFile->getString(); 458 } 459 460 MDString *GCovFile = dyn_cast<MDString>(N->getOperand(0)); 461 if (!GCovFile) 462 continue; 463 464 SmallString<128> Filename = GCovFile->getString(); 465 sys::path::replace_extension(Filename, Notes ? "gcno" : "gcda"); 466 return Filename.str(); 467 } 468 } 469 470 SmallString<128> Filename = CU->getFilename(); 471 sys::path::replace_extension(Filename, Notes ? "gcno" : "gcda"); 472 StringRef FName = sys::path::filename(Filename); 473 SmallString<128> CurPath; 474 if (sys::fs::current_path(CurPath)) return FName; 475 sys::path::append(CurPath, FName); 476 return CurPath.str(); 477 } 478 479 bool GCOVProfiler::runOnModule(Module &M, const TargetLibraryInfo &TLI) { 480 this->M = &M; 481 this->TLI = &TLI; 482 Ctx = &M.getContext(); 483 484 if (Options.EmitNotes) emitProfileNotes(); 485 if (Options.EmitData) return emitProfileArcs(); 486 return false; 487 } 488 489 PreservedAnalyses GCOVProfilerPass::run(Module &M, 490 ModuleAnalysisManager &AM) { 491 492 GCOVProfiler Profiler(GCOVOpts); 493 494 auto &TLI = AM.getResult<TargetLibraryAnalysis>(M); 495 if (!Profiler.runOnModule(M, TLI)) 496 return PreservedAnalyses::all(); 497 498 return PreservedAnalyses::none(); 499 } 500 501 static bool functionHasLines(Function &F) { 502 // Check whether this function actually has any source lines. Not only 503 // do these waste space, they also can crash gcov. 504 for (auto &BB : F) { 505 for (auto &I : BB) { 506 // Debug intrinsic locations correspond to the location of the 507 // declaration, not necessarily any statements or expressions. 508 if (isa<DbgInfoIntrinsic>(&I)) continue; 509 510 const DebugLoc &Loc = I.getDebugLoc(); 511 if (!Loc) 512 continue; 513 514 // Artificial lines such as calls to the global constructors. 515 if (Loc.getLine() == 0) continue; 516 517 return true; 518 } 519 } 520 return false; 521 } 522 523 static bool isUsingScopeBasedEH(Function &F) { 524 if (!F.hasPersonalityFn()) return false; 525 526 EHPersonality Personality = classifyEHPersonality(F.getPersonalityFn()); 527 return isScopedEHPersonality(Personality); 528 } 529 530 static bool shouldKeepInEntry(BasicBlock::iterator It) { 531 if (isa<AllocaInst>(*It)) return true; 532 if (isa<DbgInfoIntrinsic>(*It)) return true; 533 if (auto *II = dyn_cast<IntrinsicInst>(It)) { 534 if (II->getIntrinsicID() == llvm::Intrinsic::localescape) return true; 535 } 536 537 return false; 538 } 539 540 void GCOVProfiler::emitProfileNotes() { 541 NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 542 if (!CU_Nodes) return; 543 544 for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 545 // Each compile unit gets its own .gcno file. This means that whether we run 546 // this pass over the original .o's as they're produced, or run it after 547 // LTO, we'll generate the same .gcno files. 548 549 auto *CU = cast<DICompileUnit>(CU_Nodes->getOperand(i)); 550 551 // Skip module skeleton (and module) CUs. 552 if (CU->getDWOId()) 553 continue; 554 555 std::error_code EC; 556 raw_fd_ostream out(mangleName(CU, GCovFileType::GCNO), EC, sys::fs::F_None); 557 if (EC) { 558 Ctx->emitError(Twine("failed to open coverage notes file for writing: ") + 559 EC.message()); 560 continue; 561 } 562 563 std::string EdgeDestinations; 564 565 unsigned FunctionIdent = 0; 566 for (auto &F : M->functions()) { 567 DISubprogram *SP = F.getSubprogram(); 568 if (!SP) continue; 569 if (!functionHasLines(F)) continue; 570 // TODO: Functions using scope-based EH are currently not supported. 571 if (isUsingScopeBasedEH(F)) continue; 572 573 // gcov expects every function to start with an entry block that has a 574 // single successor, so split the entry block to make sure of that. 575 BasicBlock &EntryBlock = F.getEntryBlock(); 576 BasicBlock::iterator It = EntryBlock.begin(); 577 while (shouldKeepInEntry(It)) 578 ++It; 579 EntryBlock.splitBasicBlock(It); 580 581 Funcs.push_back(make_unique<GCOVFunction>(SP, &F, &out, FunctionIdent++, 582 Options.UseCfgChecksum, 583 Options.ExitBlockBeforeBody)); 584 GCOVFunction &Func = *Funcs.back(); 585 586 for (auto &BB : F) { 587 GCOVBlock &Block = Func.getBlock(&BB); 588 TerminatorInst *TI = BB.getTerminator(); 589 if (int successors = TI->getNumSuccessors()) { 590 for (int i = 0; i != successors; ++i) { 591 Block.addEdge(Func.getBlock(TI->getSuccessor(i))); 592 } 593 } else if (isa<ReturnInst>(TI)) { 594 Block.addEdge(Func.getReturnBlock()); 595 } 596 597 uint32_t Line = 0; 598 for (auto &I : BB) { 599 // Debug intrinsic locations correspond to the location of the 600 // declaration, not necessarily any statements or expressions. 601 if (isa<DbgInfoIntrinsic>(&I)) continue; 602 603 const DebugLoc &Loc = I.getDebugLoc(); 604 if (!Loc) 605 continue; 606 607 // Artificial lines such as calls to the global constructors. 608 if (Loc.getLine() == 0) continue; 609 610 if (Line == Loc.getLine()) continue; 611 Line = Loc.getLine(); 612 if (SP != getDISubprogram(Loc.getScope())) 613 continue; 614 615 GCOVLines &Lines = Block.getFile(SP->getFilename()); 616 Lines.addLine(Loc.getLine()); 617 } 618 } 619 EdgeDestinations += Func.getEdgeDestinations(); 620 } 621 622 FileChecksums.push_back(hash_value(EdgeDestinations)); 623 out.write("oncg", 4); 624 out.write(ReversedVersion, 4); 625 out.write(reinterpret_cast<char*>(&FileChecksums.back()), 4); 626 627 for (auto &Func : Funcs) { 628 Func->setCfgChecksum(FileChecksums.back()); 629 Func->writeOut(); 630 } 631 632 out.write("\0\0\0\0\0\0\0\0", 8); // EOF 633 out.close(); 634 } 635 } 636 637 bool GCOVProfiler::emitProfileArcs() { 638 NamedMDNode *CU_Nodes = M->getNamedMetadata("llvm.dbg.cu"); 639 if (!CU_Nodes) return false; 640 641 bool Result = false; 642 bool InsertIndCounterIncrCode = false; 643 for (unsigned i = 0, e = CU_Nodes->getNumOperands(); i != e; ++i) { 644 SmallVector<std::pair<GlobalVariable *, MDNode *>, 8> CountersBySP; 645 for (auto &F : M->functions()) { 646 DISubprogram *SP = F.getSubprogram(); 647 if (!SP) continue; 648 if (!functionHasLines(F)) continue; 649 // TODO: Functions using scope-based EH are currently not supported. 650 if (isUsingScopeBasedEH(F)) continue; 651 if (!Result) Result = true; 652 653 unsigned Edges = 0; 654 for (auto &BB : F) { 655 TerminatorInst *TI = BB.getTerminator(); 656 if (isa<ReturnInst>(TI)) 657 ++Edges; 658 else 659 Edges += TI->getNumSuccessors(); 660 } 661 662 ArrayType *CounterTy = 663 ArrayType::get(Type::getInt64Ty(*Ctx), Edges); 664 GlobalVariable *Counters = 665 new GlobalVariable(*M, CounterTy, false, 666 GlobalValue::InternalLinkage, 667 Constant::getNullValue(CounterTy), 668 "__llvm_gcov_ctr"); 669 CountersBySP.push_back(std::make_pair(Counters, SP)); 670 671 UniqueVector<BasicBlock *> ComplexEdgePreds; 672 UniqueVector<BasicBlock *> ComplexEdgeSuccs; 673 674 unsigned Edge = 0; 675 for (auto &BB : F) { 676 TerminatorInst *TI = BB.getTerminator(); 677 int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 678 if (Successors) { 679 if (Successors == 1) { 680 IRBuilder<> Builder(&*BB.getFirstInsertionPt()); 681 Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 682 Edge); 683 Value *Count = Builder.CreateLoad(Counter); 684 Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 685 Builder.CreateStore(Count, Counter); 686 } else if (BranchInst *BI = dyn_cast<BranchInst>(TI)) { 687 IRBuilder<> Builder(BI); 688 Value *Sel = Builder.CreateSelect(BI->getCondition(), 689 Builder.getInt64(Edge), 690 Builder.getInt64(Edge + 1)); 691 Value *Counter = Builder.CreateInBoundsGEP( 692 Counters->getValueType(), Counters, {Builder.getInt64(0), Sel}); 693 Value *Count = Builder.CreateLoad(Counter); 694 Count = Builder.CreateAdd(Count, Builder.getInt64(1)); 695 Builder.CreateStore(Count, Counter); 696 } else { 697 ComplexEdgePreds.insert(&BB); 698 for (int i = 0; i != Successors; ++i) 699 ComplexEdgeSuccs.insert(TI->getSuccessor(i)); 700 } 701 702 Edge += Successors; 703 } 704 } 705 706 if (!ComplexEdgePreds.empty()) { 707 GlobalVariable *EdgeTable = 708 buildEdgeLookupTable(&F, Counters, 709 ComplexEdgePreds, ComplexEdgeSuccs); 710 GlobalVariable *EdgeState = getEdgeStateValue(); 711 712 for (int i = 0, e = ComplexEdgePreds.size(); i != e; ++i) { 713 IRBuilder<> Builder(&*ComplexEdgePreds[i + 1]->getFirstInsertionPt()); 714 Builder.CreateStore(Builder.getInt32(i), EdgeState); 715 } 716 717 for (int i = 0, e = ComplexEdgeSuccs.size(); i != e; ++i) { 718 // Call runtime to perform increment. 719 IRBuilder<> Builder(&*ComplexEdgeSuccs[i + 1]->getFirstInsertionPt()); 720 Value *CounterPtrArray = 721 Builder.CreateConstInBoundsGEP2_64(EdgeTable, 0, 722 i * ComplexEdgePreds.size()); 723 724 // Build code to increment the counter. 725 InsertIndCounterIncrCode = true; 726 Builder.CreateCall(getIncrementIndirectCounterFunc(), 727 {EdgeState, CounterPtrArray}); 728 } 729 } 730 } 731 732 Function *WriteoutF = insertCounterWriteout(CountersBySP); 733 Function *FlushF = insertFlush(CountersBySP); 734 735 // Create a small bit of code that registers the "__llvm_gcov_writeout" to 736 // be executed at exit and the "__llvm_gcov_flush" function to be executed 737 // when "__gcov_flush" is called. 738 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 739 Function *F = Function::Create(FTy, GlobalValue::InternalLinkage, 740 "__llvm_gcov_init", M); 741 F->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 742 F->setLinkage(GlobalValue::InternalLinkage); 743 F->addFnAttr(Attribute::NoInline); 744 if (Options.NoRedZone) 745 F->addFnAttr(Attribute::NoRedZone); 746 747 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", F); 748 IRBuilder<> Builder(BB); 749 750 FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 751 Type *Params[] = { 752 PointerType::get(FTy, 0), 753 PointerType::get(FTy, 0) 754 }; 755 FTy = FunctionType::get(Builder.getVoidTy(), Params, false); 756 757 // Initialize the environment and register the local writeout and flush 758 // functions. 759 Constant *GCOVInit = M->getOrInsertFunction("llvm_gcov_init", FTy); 760 Builder.CreateCall(GCOVInit, {WriteoutF, FlushF}); 761 Builder.CreateRetVoid(); 762 763 appendToGlobalCtors(*M, F, 0); 764 } 765 766 if (InsertIndCounterIncrCode) 767 insertIndirectCounterIncrement(); 768 769 return Result; 770 } 771 772 // All edges with successors that aren't branches are "complex", because it 773 // requires complex logic to pick which counter to update. 774 GlobalVariable *GCOVProfiler::buildEdgeLookupTable( 775 Function *F, 776 GlobalVariable *Counters, 777 const UniqueVector<BasicBlock *> &Preds, 778 const UniqueVector<BasicBlock *> &Succs) { 779 // TODO: support invoke, threads. We rely on the fact that nothing can modify 780 // the whole-Module pred edge# between the time we set it and the time we next 781 // read it. Threads and invoke make this untrue. 782 783 // emit [(succs * preds) x i64*], logically [succ x [pred x i64*]]. 784 size_t TableSize = Succs.size() * Preds.size(); 785 Type *Int64PtrTy = Type::getInt64PtrTy(*Ctx); 786 ArrayType *EdgeTableTy = ArrayType::get(Int64PtrTy, TableSize); 787 788 std::unique_ptr<Constant * []> EdgeTable(new Constant *[TableSize]); 789 Constant *NullValue = Constant::getNullValue(Int64PtrTy); 790 for (size_t i = 0; i != TableSize; ++i) 791 EdgeTable[i] = NullValue; 792 793 unsigned Edge = 0; 794 for (BasicBlock &BB : *F) { 795 TerminatorInst *TI = BB.getTerminator(); 796 int Successors = isa<ReturnInst>(TI) ? 1 : TI->getNumSuccessors(); 797 if (Successors > 1 && !isa<BranchInst>(TI) && !isa<ReturnInst>(TI)) { 798 for (int i = 0; i != Successors; ++i) { 799 BasicBlock *Succ = TI->getSuccessor(i); 800 IRBuilder<> Builder(Succ); 801 Value *Counter = Builder.CreateConstInBoundsGEP2_64(Counters, 0, 802 Edge + i); 803 EdgeTable[((Succs.idFor(Succ) - 1) * Preds.size()) + 804 (Preds.idFor(&BB) - 1)] = cast<Constant>(Counter); 805 } 806 } 807 Edge += Successors; 808 } 809 810 GlobalVariable *EdgeTableGV = 811 new GlobalVariable( 812 *M, EdgeTableTy, true, GlobalValue::InternalLinkage, 813 ConstantArray::get(EdgeTableTy, 814 makeArrayRef(&EdgeTable[0],TableSize)), 815 "__llvm_gcda_edge_table"); 816 EdgeTableGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 817 return EdgeTableGV; 818 } 819 820 Constant *GCOVProfiler::getStartFileFunc() { 821 Type *Args[] = { 822 Type::getInt8PtrTy(*Ctx), // const char *orig_filename 823 Type::getInt8PtrTy(*Ctx), // const char version[4] 824 Type::getInt32Ty(*Ctx), // uint32_t checksum 825 }; 826 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 827 auto *Res = M->getOrInsertFunction("llvm_gcda_start_file", FTy); 828 if (Function *FunRes = dyn_cast<Function>(Res)) 829 if (auto AK = TLI->getExtAttrForI32Param(false)) 830 FunRes->addParamAttr(2, AK); 831 return Res; 832 833 } 834 835 Constant *GCOVProfiler::getIncrementIndirectCounterFunc() { 836 Type *Int32Ty = Type::getInt32Ty(*Ctx); 837 Type *Int64Ty = Type::getInt64Ty(*Ctx); 838 Type *Args[] = { 839 Int32Ty->getPointerTo(), // uint32_t *predecessor 840 Int64Ty->getPointerTo()->getPointerTo() // uint64_t **counters 841 }; 842 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 843 return M->getOrInsertFunction("__llvm_gcov_indirect_counter_increment", FTy); 844 } 845 846 Constant *GCOVProfiler::getEmitFunctionFunc() { 847 Type *Args[] = { 848 Type::getInt32Ty(*Ctx), // uint32_t ident 849 Type::getInt8PtrTy(*Ctx), // const char *function_name 850 Type::getInt32Ty(*Ctx), // uint32_t func_checksum 851 Type::getInt8Ty(*Ctx), // uint8_t use_extra_checksum 852 Type::getInt32Ty(*Ctx), // uint32_t cfg_checksum 853 }; 854 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 855 auto *Res = M->getOrInsertFunction("llvm_gcda_emit_function", FTy); 856 if (Function *FunRes = dyn_cast<Function>(Res)) 857 if (auto AK = TLI->getExtAttrForI32Param(false)) { 858 FunRes->addParamAttr(0, AK); 859 FunRes->addParamAttr(2, AK); 860 FunRes->addParamAttr(3, AK); 861 FunRes->addParamAttr(4, AK); 862 } 863 return Res; 864 } 865 866 Constant *GCOVProfiler::getEmitArcsFunc() { 867 Type *Args[] = { 868 Type::getInt32Ty(*Ctx), // uint32_t num_counters 869 Type::getInt64PtrTy(*Ctx), // uint64_t *counters 870 }; 871 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), Args, false); 872 auto *Res = M->getOrInsertFunction("llvm_gcda_emit_arcs", FTy); 873 if (Function *FunRes = dyn_cast<Function>(Res)) 874 if (auto AK = TLI->getExtAttrForI32Param(false)) 875 FunRes->addParamAttr(0, AK); 876 return Res; 877 } 878 879 Constant *GCOVProfiler::getSummaryInfoFunc() { 880 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 881 return M->getOrInsertFunction("llvm_gcda_summary_info", FTy); 882 } 883 884 Constant *GCOVProfiler::getEndFileFunc() { 885 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 886 return M->getOrInsertFunction("llvm_gcda_end_file", FTy); 887 } 888 889 GlobalVariable *GCOVProfiler::getEdgeStateValue() { 890 GlobalVariable *GV = M->getGlobalVariable("__llvm_gcov_global_state_pred"); 891 if (!GV) { 892 GV = new GlobalVariable(*M, Type::getInt32Ty(*Ctx), false, 893 GlobalValue::InternalLinkage, 894 ConstantInt::get(Type::getInt32Ty(*Ctx), 895 0xffffffff), 896 "__llvm_gcov_global_state_pred"); 897 GV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 898 } 899 return GV; 900 } 901 902 Function *GCOVProfiler::insertCounterWriteout( 903 ArrayRef<std::pair<GlobalVariable *, MDNode *> > CountersBySP) { 904 FunctionType *WriteoutFTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 905 Function *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 906 if (!WriteoutF) 907 WriteoutF = Function::Create(WriteoutFTy, GlobalValue::InternalLinkage, 908 "__llvm_gcov_writeout", M); 909 WriteoutF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 910 WriteoutF->addFnAttr(Attribute::NoInline); 911 if (Options.NoRedZone) 912 WriteoutF->addFnAttr(Attribute::NoRedZone); 913 914 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", WriteoutF); 915 IRBuilder<> Builder(BB); 916 917 Constant *StartFile = getStartFileFunc(); 918 Constant *EmitFunction = getEmitFunctionFunc(); 919 Constant *EmitArcs = getEmitArcsFunc(); 920 Constant *SummaryInfo = getSummaryInfoFunc(); 921 Constant *EndFile = getEndFileFunc(); 922 923 NamedMDNode *CUNodes = M->getNamedMetadata("llvm.dbg.cu"); 924 if (!CUNodes) { 925 Builder.CreateRetVoid(); 926 return WriteoutF; 927 } 928 929 // Collect the relevant data into a large constant data structure that we can 930 // walk to write out everything. 931 StructType *StartFileCallArgsTy = StructType::create( 932 {Builder.getInt8PtrTy(), Builder.getInt8PtrTy(), Builder.getInt32Ty()}); 933 StructType *EmitFunctionCallArgsTy = StructType::create( 934 {Builder.getInt32Ty(), Builder.getInt8PtrTy(), Builder.getInt32Ty(), 935 Builder.getInt8Ty(), Builder.getInt32Ty()}); 936 StructType *EmitArcsCallArgsTy = StructType::create( 937 {Builder.getInt32Ty(), Builder.getInt64Ty()->getPointerTo()}); 938 StructType *FileInfoTy = 939 StructType::create({StartFileCallArgsTy, Builder.getInt32Ty(), 940 EmitFunctionCallArgsTy->getPointerTo(), 941 EmitArcsCallArgsTy->getPointerTo()}); 942 943 Constant *Zero32 = Builder.getInt32(0); 944 // Build an explicit array of two zeros for use in ConstantExpr GEP building. 945 Constant *TwoZero32s[] = {Zero32, Zero32}; 946 947 SmallVector<Constant *, 8> FileInfos; 948 for (int i : llvm::seq<int>(0, CUNodes->getNumOperands())) { 949 auto *CU = cast<DICompileUnit>(CUNodes->getOperand(i)); 950 951 // Skip module skeleton (and module) CUs. 952 if (CU->getDWOId()) 953 continue; 954 955 std::string FilenameGcda = mangleName(CU, GCovFileType::GCDA); 956 uint32_t CfgChecksum = FileChecksums.empty() ? 0 : FileChecksums[i]; 957 auto *StartFileCallArgs = ConstantStruct::get( 958 StartFileCallArgsTy, {Builder.CreateGlobalStringPtr(FilenameGcda), 959 Builder.CreateGlobalStringPtr(ReversedVersion), 960 Builder.getInt32(CfgChecksum)}); 961 962 SmallVector<Constant *, 8> EmitFunctionCallArgsArray; 963 SmallVector<Constant *, 8> EmitArcsCallArgsArray; 964 for (int j : llvm::seq<int>(0, CountersBySP.size())) { 965 auto *SP = cast_or_null<DISubprogram>(CountersBySP[j].second); 966 uint32_t FuncChecksum = Funcs.empty() ? 0 : Funcs[j]->getFuncChecksum(); 967 EmitFunctionCallArgsArray.push_back(ConstantStruct::get( 968 EmitFunctionCallArgsTy, 969 {Builder.getInt32(j), 970 Options.FunctionNamesInData 971 ? Builder.CreateGlobalStringPtr(getFunctionName(SP)) 972 : Constant::getNullValue(Builder.getInt8PtrTy()), 973 Builder.getInt32(FuncChecksum), 974 Builder.getInt8(Options.UseCfgChecksum), 975 Builder.getInt32(CfgChecksum)})); 976 977 GlobalVariable *GV = CountersBySP[j].first; 978 unsigned Arcs = cast<ArrayType>(GV->getValueType())->getNumElements(); 979 EmitArcsCallArgsArray.push_back(ConstantStruct::get( 980 EmitArcsCallArgsTy, 981 {Builder.getInt32(Arcs), ConstantExpr::getInBoundsGetElementPtr( 982 GV->getValueType(), GV, TwoZero32s)})); 983 } 984 // Create global arrays for the two emit calls. 985 int CountersSize = CountersBySP.size(); 986 assert(CountersSize == (int)EmitFunctionCallArgsArray.size() && 987 "Mismatched array size!"); 988 assert(CountersSize == (int)EmitArcsCallArgsArray.size() && 989 "Mismatched array size!"); 990 auto *EmitFunctionCallArgsArrayTy = 991 ArrayType::get(EmitFunctionCallArgsTy, CountersSize); 992 auto *EmitFunctionCallArgsArrayGV = new GlobalVariable( 993 *M, EmitFunctionCallArgsArrayTy, /*isConstant*/ true, 994 GlobalValue::InternalLinkage, 995 ConstantArray::get(EmitFunctionCallArgsArrayTy, 996 EmitFunctionCallArgsArray), 997 Twine("__llvm_internal_gcov_emit_function_args.") + Twine(i)); 998 auto *EmitArcsCallArgsArrayTy = 999 ArrayType::get(EmitArcsCallArgsTy, CountersSize); 1000 EmitFunctionCallArgsArrayGV->setUnnamedAddr( 1001 GlobalValue::UnnamedAddr::Global); 1002 auto *EmitArcsCallArgsArrayGV = new GlobalVariable( 1003 *M, EmitArcsCallArgsArrayTy, /*isConstant*/ true, 1004 GlobalValue::InternalLinkage, 1005 ConstantArray::get(EmitArcsCallArgsArrayTy, EmitArcsCallArgsArray), 1006 Twine("__llvm_internal_gcov_emit_arcs_args.") + Twine(i)); 1007 EmitArcsCallArgsArrayGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 1008 1009 FileInfos.push_back(ConstantStruct::get( 1010 FileInfoTy, 1011 {StartFileCallArgs, Builder.getInt32(CountersSize), 1012 ConstantExpr::getInBoundsGetElementPtr(EmitFunctionCallArgsArrayTy, 1013 EmitFunctionCallArgsArrayGV, 1014 TwoZero32s), 1015 ConstantExpr::getInBoundsGetElementPtr( 1016 EmitArcsCallArgsArrayTy, EmitArcsCallArgsArrayGV, TwoZero32s)})); 1017 } 1018 1019 // If we didn't find anything to actually emit, bail on out. 1020 if (FileInfos.empty()) { 1021 Builder.CreateRetVoid(); 1022 return WriteoutF; 1023 } 1024 1025 // To simplify code, we cap the number of file infos we write out to fit 1026 // easily in a 32-bit signed integer. This gives consistent behavior between 1027 // 32-bit and 64-bit systems without requiring (potentially very slow) 64-bit 1028 // operations on 32-bit systems. It also seems unreasonable to try to handle 1029 // more than 2 billion files. 1030 if ((int64_t)FileInfos.size() > (int64_t)INT_MAX) 1031 FileInfos.resize(INT_MAX); 1032 1033 // Create a global for the entire data structure so we can walk it more 1034 // easily. 1035 auto *FileInfoArrayTy = ArrayType::get(FileInfoTy, FileInfos.size()); 1036 auto *FileInfoArrayGV = new GlobalVariable( 1037 *M, FileInfoArrayTy, /*isConstant*/ true, GlobalValue::InternalLinkage, 1038 ConstantArray::get(FileInfoArrayTy, FileInfos), 1039 "__llvm_internal_gcov_emit_file_info"); 1040 FileInfoArrayGV->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 1041 1042 // Create the CFG for walking this data structure. 1043 auto *FileLoopHeader = 1044 BasicBlock::Create(*Ctx, "file.loop.header", WriteoutF); 1045 auto *CounterLoopHeader = 1046 BasicBlock::Create(*Ctx, "counter.loop.header", WriteoutF); 1047 auto *FileLoopLatch = BasicBlock::Create(*Ctx, "file.loop.latch", WriteoutF); 1048 auto *ExitBB = BasicBlock::Create(*Ctx, "exit", WriteoutF); 1049 1050 // We always have at least one file, so just branch to the header. 1051 Builder.CreateBr(FileLoopHeader); 1052 1053 // The index into the files structure is our loop induction variable. 1054 Builder.SetInsertPoint(FileLoopHeader); 1055 PHINode *IV = 1056 Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2); 1057 IV->addIncoming(Builder.getInt32(0), BB); 1058 auto *FileInfoPtr = 1059 Builder.CreateInBoundsGEP(FileInfoArrayGV, {Builder.getInt32(0), IV}); 1060 auto *StartFileCallArgsPtr = Builder.CreateStructGEP(FileInfoPtr, 0); 1061 auto *StartFileCall = Builder.CreateCall( 1062 StartFile, 1063 {Builder.CreateLoad(Builder.CreateStructGEP(StartFileCallArgsPtr, 0)), 1064 Builder.CreateLoad(Builder.CreateStructGEP(StartFileCallArgsPtr, 1)), 1065 Builder.CreateLoad(Builder.CreateStructGEP(StartFileCallArgsPtr, 2))}); 1066 if (auto AK = TLI->getExtAttrForI32Param(false)) 1067 StartFileCall->addParamAttr(2, AK); 1068 auto *NumCounters = 1069 Builder.CreateLoad(Builder.CreateStructGEP(FileInfoPtr, 1)); 1070 auto *EmitFunctionCallArgsArray = 1071 Builder.CreateLoad(Builder.CreateStructGEP(FileInfoPtr, 2)); 1072 auto *EmitArcsCallArgsArray = 1073 Builder.CreateLoad(Builder.CreateStructGEP(FileInfoPtr, 3)); 1074 auto *EnterCounterLoopCond = 1075 Builder.CreateICmpSLT(Builder.getInt32(0), NumCounters); 1076 Builder.CreateCondBr(EnterCounterLoopCond, CounterLoopHeader, FileLoopLatch); 1077 1078 Builder.SetInsertPoint(CounterLoopHeader); 1079 auto *JV = Builder.CreatePHI(Builder.getInt32Ty(), /*NumReservedValues*/ 2); 1080 JV->addIncoming(Builder.getInt32(0), FileLoopHeader); 1081 auto *EmitFunctionCallArgsPtr = 1082 Builder.CreateInBoundsGEP(EmitFunctionCallArgsArray, {JV}); 1083 auto *EmitFunctionCall = Builder.CreateCall( 1084 EmitFunction, 1085 {Builder.CreateLoad(Builder.CreateStructGEP(EmitFunctionCallArgsPtr, 0)), 1086 Builder.CreateLoad(Builder.CreateStructGEP(EmitFunctionCallArgsPtr, 1)), 1087 Builder.CreateLoad(Builder.CreateStructGEP(EmitFunctionCallArgsPtr, 2)), 1088 Builder.CreateLoad(Builder.CreateStructGEP(EmitFunctionCallArgsPtr, 3)), 1089 Builder.CreateLoad( 1090 Builder.CreateStructGEP(EmitFunctionCallArgsPtr, 4))}); 1091 if (auto AK = TLI->getExtAttrForI32Param(false)) { 1092 EmitFunctionCall->addParamAttr(0, AK); 1093 EmitFunctionCall->addParamAttr(2, AK); 1094 EmitFunctionCall->addParamAttr(3, AK); 1095 EmitFunctionCall->addParamAttr(4, AK); 1096 } 1097 auto *EmitArcsCallArgsPtr = 1098 Builder.CreateInBoundsGEP(EmitArcsCallArgsArray, {JV}); 1099 auto *EmitArcsCall = Builder.CreateCall( 1100 EmitArcs, 1101 {Builder.CreateLoad(Builder.CreateStructGEP(EmitArcsCallArgsPtr, 0)), 1102 Builder.CreateLoad(Builder.CreateStructGEP(EmitArcsCallArgsPtr, 1))}); 1103 if (auto AK = TLI->getExtAttrForI32Param(false)) 1104 EmitArcsCall->addParamAttr(0, AK); 1105 auto *NextJV = Builder.CreateAdd(JV, Builder.getInt32(1)); 1106 auto *CounterLoopCond = Builder.CreateICmpSLT(NextJV, NumCounters); 1107 Builder.CreateCondBr(CounterLoopCond, CounterLoopHeader, FileLoopLatch); 1108 JV->addIncoming(NextJV, CounterLoopHeader); 1109 1110 Builder.SetInsertPoint(FileLoopLatch); 1111 Builder.CreateCall(SummaryInfo, {}); 1112 Builder.CreateCall(EndFile, {}); 1113 auto *NextIV = Builder.CreateAdd(IV, Builder.getInt32(1)); 1114 auto *FileLoopCond = 1115 Builder.CreateICmpSLT(NextIV, Builder.getInt32(FileInfos.size())); 1116 Builder.CreateCondBr(FileLoopCond, FileLoopHeader, ExitBB); 1117 IV->addIncoming(NextIV, FileLoopLatch); 1118 1119 Builder.SetInsertPoint(ExitBB); 1120 Builder.CreateRetVoid(); 1121 1122 return WriteoutF; 1123 } 1124 1125 void GCOVProfiler::insertIndirectCounterIncrement() { 1126 Function *Fn = 1127 cast<Function>(GCOVProfiler::getIncrementIndirectCounterFunc()); 1128 Fn->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 1129 Fn->setLinkage(GlobalValue::InternalLinkage); 1130 Fn->addFnAttr(Attribute::NoInline); 1131 if (Options.NoRedZone) 1132 Fn->addFnAttr(Attribute::NoRedZone); 1133 1134 // Create basic blocks for function. 1135 BasicBlock *BB = BasicBlock::Create(*Ctx, "entry", Fn); 1136 IRBuilder<> Builder(BB); 1137 1138 BasicBlock *PredNotNegOne = BasicBlock::Create(*Ctx, "", Fn); 1139 BasicBlock *CounterEnd = BasicBlock::Create(*Ctx, "", Fn); 1140 BasicBlock *Exit = BasicBlock::Create(*Ctx, "exit", Fn); 1141 1142 // uint32_t pred = *predecessor; 1143 // if (pred == 0xffffffff) return; 1144 Argument *Arg = &*Fn->arg_begin(); 1145 Arg->setName("predecessor"); 1146 Value *Pred = Builder.CreateLoad(Arg, "pred"); 1147 Value *Cond = Builder.CreateICmpEQ(Pred, Builder.getInt32(0xffffffff)); 1148 BranchInst::Create(Exit, PredNotNegOne, Cond, BB); 1149 1150 Builder.SetInsertPoint(PredNotNegOne); 1151 1152 // uint64_t *counter = counters[pred]; 1153 // if (!counter) return; 1154 Value *ZExtPred = Builder.CreateZExt(Pred, Builder.getInt64Ty()); 1155 Arg = &*std::next(Fn->arg_begin()); 1156 Arg->setName("counters"); 1157 Value *GEP = Builder.CreateGEP(Type::getInt64PtrTy(*Ctx), Arg, ZExtPred); 1158 Value *Counter = Builder.CreateLoad(GEP, "counter"); 1159 Cond = Builder.CreateICmpEQ(Counter, 1160 Constant::getNullValue( 1161 Builder.getInt64Ty()->getPointerTo())); 1162 Builder.CreateCondBr(Cond, Exit, CounterEnd); 1163 1164 // ++*counter; 1165 Builder.SetInsertPoint(CounterEnd); 1166 Value *Add = Builder.CreateAdd(Builder.CreateLoad(Counter), 1167 Builder.getInt64(1)); 1168 Builder.CreateStore(Add, Counter); 1169 Builder.CreateBr(Exit); 1170 1171 // Fill in the exit block. 1172 Builder.SetInsertPoint(Exit); 1173 Builder.CreateRetVoid(); 1174 } 1175 1176 Function *GCOVProfiler:: 1177 insertFlush(ArrayRef<std::pair<GlobalVariable*, MDNode*> > CountersBySP) { 1178 FunctionType *FTy = FunctionType::get(Type::getVoidTy(*Ctx), false); 1179 Function *FlushF = M->getFunction("__llvm_gcov_flush"); 1180 if (!FlushF) 1181 FlushF = Function::Create(FTy, GlobalValue::InternalLinkage, 1182 "__llvm_gcov_flush", M); 1183 else 1184 FlushF->setLinkage(GlobalValue::InternalLinkage); 1185 FlushF->setUnnamedAddr(GlobalValue::UnnamedAddr::Global); 1186 FlushF->addFnAttr(Attribute::NoInline); 1187 if (Options.NoRedZone) 1188 FlushF->addFnAttr(Attribute::NoRedZone); 1189 1190 BasicBlock *Entry = BasicBlock::Create(*Ctx, "entry", FlushF); 1191 1192 // Write out the current counters. 1193 Constant *WriteoutF = M->getFunction("__llvm_gcov_writeout"); 1194 assert(WriteoutF && "Need to create the writeout function first!"); 1195 1196 IRBuilder<> Builder(Entry); 1197 Builder.CreateCall(WriteoutF, {}); 1198 1199 // Zero out the counters. 1200 for (const auto &I : CountersBySP) { 1201 GlobalVariable *GV = I.first; 1202 Constant *Null = Constant::getNullValue(GV->getValueType()); 1203 Builder.CreateStore(Null, GV); 1204 } 1205 1206 Type *RetTy = FlushF->getReturnType(); 1207 if (RetTy == Type::getVoidTy(*Ctx)) 1208 Builder.CreateRetVoid(); 1209 else if (RetTy->isIntegerTy()) 1210 // Used if __llvm_gcov_flush was implicitly declared. 1211 Builder.CreateRet(ConstantInt::get(RetTy, 0)); 1212 else 1213 report_fatal_error("invalid return type for __llvm_gcov_flush"); 1214 1215 return FlushF; 1216 } 1217