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