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