1 //===--- CoverageMappingGen.cpp - Coverage mapping generation ---*- C++ -*-===// 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 // Instrumentation-based code coverage mapping generator 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "CoverageMappingGen.h" 14 #include "CodeGenFunction.h" 15 #include "clang/AST/StmtVisitor.h" 16 #include "clang/Basic/Diagnostic.h" 17 #include "clang/Basic/FileManager.h" 18 #include "clang/Frontend/FrontendDiagnostic.h" 19 #include "clang/Lex/Lexer.h" 20 #include "llvm/ADT/SmallSet.h" 21 #include "llvm/ADT/StringExtras.h" 22 #include "llvm/ProfileData/Coverage/CoverageMapping.h" 23 #include "llvm/ProfileData/Coverage/CoverageMappingReader.h" 24 #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h" 25 #include "llvm/ProfileData/InstrProfReader.h" 26 #include "llvm/Support/FileSystem.h" 27 #include "llvm/Support/Path.h" 28 #include <optional> 29 30 // This selects the coverage mapping format defined when `InstrProfData.inc` 31 // is textually included. 32 #define COVMAP_V3 33 34 static llvm::cl::opt<bool> EmptyLineCommentCoverage( 35 "emptyline-comment-coverage", 36 llvm::cl::desc("Emit emptylines and comment lines as skipped regions (only " 37 "disable it on test)"), 38 llvm::cl::init(true), llvm::cl::Hidden); 39 40 static llvm::cl::opt<bool> SystemHeadersCoverage( 41 "system-headers-coverage", 42 llvm::cl::desc("Enable collecting coverage from system headers"), 43 llvm::cl::init(false), llvm::cl::Hidden); 44 45 using namespace clang; 46 using namespace CodeGen; 47 using namespace llvm::coverage; 48 49 CoverageSourceInfo * 50 CoverageMappingModuleGen::setUpCoverageCallbacks(Preprocessor &PP) { 51 CoverageSourceInfo *CoverageInfo = 52 new CoverageSourceInfo(PP.getSourceManager()); 53 PP.addPPCallbacks(std::unique_ptr<PPCallbacks>(CoverageInfo)); 54 if (EmptyLineCommentCoverage) { 55 PP.addCommentHandler(CoverageInfo); 56 PP.setEmptylineHandler(CoverageInfo); 57 PP.setPreprocessToken(true); 58 PP.setTokenWatcher([CoverageInfo](clang::Token Tok) { 59 // Update previous token location. 60 CoverageInfo->PrevTokLoc = Tok.getLocation(); 61 if (Tok.getKind() != clang::tok::eod) 62 CoverageInfo->updateNextTokLoc(Tok.getLocation()); 63 }); 64 } 65 return CoverageInfo; 66 } 67 68 void CoverageSourceInfo::AddSkippedRange(SourceRange Range, 69 SkippedRange::Kind RangeKind) { 70 if (EmptyLineCommentCoverage && !SkippedRanges.empty() && 71 PrevTokLoc == SkippedRanges.back().PrevTokLoc && 72 SourceMgr.isWrittenInSameFile(SkippedRanges.back().Range.getEnd(), 73 Range.getBegin())) 74 SkippedRanges.back().Range.setEnd(Range.getEnd()); 75 else 76 SkippedRanges.push_back({Range, RangeKind, PrevTokLoc}); 77 } 78 79 void CoverageSourceInfo::SourceRangeSkipped(SourceRange Range, SourceLocation) { 80 AddSkippedRange(Range, SkippedRange::PPIfElse); 81 } 82 83 void CoverageSourceInfo::HandleEmptyline(SourceRange Range) { 84 AddSkippedRange(Range, SkippedRange::EmptyLine); 85 } 86 87 bool CoverageSourceInfo::HandleComment(Preprocessor &PP, SourceRange Range) { 88 AddSkippedRange(Range, SkippedRange::Comment); 89 return false; 90 } 91 92 void CoverageSourceInfo::updateNextTokLoc(SourceLocation Loc) { 93 if (!SkippedRanges.empty() && SkippedRanges.back().NextTokLoc.isInvalid()) 94 SkippedRanges.back().NextTokLoc = Loc; 95 } 96 97 namespace { 98 99 /// A region of source code that can be mapped to a counter. 100 class SourceMappingRegion { 101 /// Primary Counter that is also used for Branch Regions for "True" branches. 102 Counter Count; 103 104 /// Secondary Counter used for Branch Regions for "False" branches. 105 std::optional<Counter> FalseCount; 106 107 /// The region's starting location. 108 std::optional<SourceLocation> LocStart; 109 110 /// The region's ending location. 111 std::optional<SourceLocation> LocEnd; 112 113 /// Whether this region is a gap region. The count from a gap region is set 114 /// as the line execution count if there are no other regions on the line. 115 bool GapRegion; 116 117 public: 118 SourceMappingRegion(Counter Count, std::optional<SourceLocation> LocStart, 119 std::optional<SourceLocation> LocEnd, 120 bool GapRegion = false) 121 : Count(Count), LocStart(LocStart), LocEnd(LocEnd), GapRegion(GapRegion) { 122 } 123 124 SourceMappingRegion(Counter Count, std::optional<Counter> FalseCount, 125 std::optional<SourceLocation> LocStart, 126 std::optional<SourceLocation> LocEnd, 127 bool GapRegion = false) 128 : Count(Count), FalseCount(FalseCount), LocStart(LocStart), 129 LocEnd(LocEnd), GapRegion(GapRegion) {} 130 131 const Counter &getCounter() const { return Count; } 132 133 const Counter &getFalseCounter() const { 134 assert(FalseCount && "Region has no alternate counter"); 135 return *FalseCount; 136 } 137 138 void setCounter(Counter C) { Count = C; } 139 140 bool hasStartLoc() const { return LocStart.has_value(); } 141 142 void setStartLoc(SourceLocation Loc) { LocStart = Loc; } 143 144 SourceLocation getBeginLoc() const { 145 assert(LocStart && "Region has no start location"); 146 return *LocStart; 147 } 148 149 bool hasEndLoc() const { return LocEnd.has_value(); } 150 151 void setEndLoc(SourceLocation Loc) { 152 assert(Loc.isValid() && "Setting an invalid end location"); 153 LocEnd = Loc; 154 } 155 156 SourceLocation getEndLoc() const { 157 assert(LocEnd && "Region has no end location"); 158 return *LocEnd; 159 } 160 161 bool isGap() const { return GapRegion; } 162 163 void setGap(bool Gap) { GapRegion = Gap; } 164 165 bool isBranch() const { return FalseCount.has_value(); } 166 }; 167 168 /// Spelling locations for the start and end of a source region. 169 struct SpellingRegion { 170 /// The line where the region starts. 171 unsigned LineStart; 172 173 /// The column where the region starts. 174 unsigned ColumnStart; 175 176 /// The line where the region ends. 177 unsigned LineEnd; 178 179 /// The column where the region ends. 180 unsigned ColumnEnd; 181 182 SpellingRegion(SourceManager &SM, SourceLocation LocStart, 183 SourceLocation LocEnd) { 184 LineStart = SM.getSpellingLineNumber(LocStart); 185 ColumnStart = SM.getSpellingColumnNumber(LocStart); 186 LineEnd = SM.getSpellingLineNumber(LocEnd); 187 ColumnEnd = SM.getSpellingColumnNumber(LocEnd); 188 } 189 190 SpellingRegion(SourceManager &SM, SourceMappingRegion &R) 191 : SpellingRegion(SM, R.getBeginLoc(), R.getEndLoc()) {} 192 193 /// Check if the start and end locations appear in source order, i.e 194 /// top->bottom, left->right. 195 bool isInSourceOrder() const { 196 return (LineStart < LineEnd) || 197 (LineStart == LineEnd && ColumnStart <= ColumnEnd); 198 } 199 }; 200 201 /// Provides the common functionality for the different 202 /// coverage mapping region builders. 203 class CoverageMappingBuilder { 204 public: 205 CoverageMappingModuleGen &CVM; 206 SourceManager &SM; 207 const LangOptions &LangOpts; 208 209 private: 210 /// Map of clang's FileIDs to IDs used for coverage mapping. 211 llvm::SmallDenseMap<FileID, std::pair<unsigned, SourceLocation>, 8> 212 FileIDMapping; 213 214 public: 215 /// The coverage mapping regions for this function 216 llvm::SmallVector<CounterMappingRegion, 32> MappingRegions; 217 /// The source mapping regions for this function. 218 std::vector<SourceMappingRegion> SourceRegions; 219 220 /// A set of regions which can be used as a filter. 221 /// 222 /// It is produced by emitExpansionRegions() and is used in 223 /// emitSourceRegions() to suppress producing code regions if 224 /// the same area is covered by expansion regions. 225 typedef llvm::SmallSet<std::pair<SourceLocation, SourceLocation>, 8> 226 SourceRegionFilter; 227 228 CoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM, 229 const LangOptions &LangOpts) 230 : CVM(CVM), SM(SM), LangOpts(LangOpts) {} 231 232 /// Return the precise end location for the given token. 233 SourceLocation getPreciseTokenLocEnd(SourceLocation Loc) { 234 // We avoid getLocForEndOfToken here, because it doesn't do what we want for 235 // macro locations, which we just treat as expanded files. 236 unsigned TokLen = 237 Lexer::MeasureTokenLength(SM.getSpellingLoc(Loc), SM, LangOpts); 238 return Loc.getLocWithOffset(TokLen); 239 } 240 241 /// Return the start location of an included file or expanded macro. 242 SourceLocation getStartOfFileOrMacro(SourceLocation Loc) { 243 if (Loc.isMacroID()) 244 return Loc.getLocWithOffset(-SM.getFileOffset(Loc)); 245 return SM.getLocForStartOfFile(SM.getFileID(Loc)); 246 } 247 248 /// Return the end location of an included file or expanded macro. 249 SourceLocation getEndOfFileOrMacro(SourceLocation Loc) { 250 if (Loc.isMacroID()) 251 return Loc.getLocWithOffset(SM.getFileIDSize(SM.getFileID(Loc)) - 252 SM.getFileOffset(Loc)); 253 return SM.getLocForEndOfFile(SM.getFileID(Loc)); 254 } 255 256 /// Find out where the current file is included or macro is expanded. 257 SourceLocation getIncludeOrExpansionLoc(SourceLocation Loc) { 258 return Loc.isMacroID() ? SM.getImmediateExpansionRange(Loc).getBegin() 259 : SM.getIncludeLoc(SM.getFileID(Loc)); 260 } 261 262 /// Return true if \c Loc is a location in a built-in macro. 263 bool isInBuiltin(SourceLocation Loc) { 264 return SM.getBufferName(SM.getSpellingLoc(Loc)) == "<built-in>"; 265 } 266 267 /// Check whether \c Loc is included or expanded from \c Parent. 268 bool isNestedIn(SourceLocation Loc, FileID Parent) { 269 do { 270 Loc = getIncludeOrExpansionLoc(Loc); 271 if (Loc.isInvalid()) 272 return false; 273 } while (!SM.isInFileID(Loc, Parent)); 274 return true; 275 } 276 277 /// Get the start of \c S ignoring macro arguments and builtin macros. 278 SourceLocation getStart(const Stmt *S) { 279 SourceLocation Loc = S->getBeginLoc(); 280 while (SM.isMacroArgExpansion(Loc) || isInBuiltin(Loc)) 281 Loc = SM.getImmediateExpansionRange(Loc).getBegin(); 282 return Loc; 283 } 284 285 /// Get the end of \c S ignoring macro arguments and builtin macros. 286 SourceLocation getEnd(const Stmt *S) { 287 SourceLocation Loc = S->getEndLoc(); 288 while (SM.isMacroArgExpansion(Loc) || isInBuiltin(Loc)) 289 Loc = SM.getImmediateExpansionRange(Loc).getBegin(); 290 return getPreciseTokenLocEnd(Loc); 291 } 292 293 /// Find the set of files we have regions for and assign IDs 294 /// 295 /// Fills \c Mapping with the virtual file mapping needed to write out 296 /// coverage and collects the necessary file information to emit source and 297 /// expansion regions. 298 void gatherFileIDs(SmallVectorImpl<unsigned> &Mapping) { 299 FileIDMapping.clear(); 300 301 llvm::SmallSet<FileID, 8> Visited; 302 SmallVector<std::pair<SourceLocation, unsigned>, 8> FileLocs; 303 for (const auto &Region : SourceRegions) { 304 SourceLocation Loc = Region.getBeginLoc(); 305 FileID File = SM.getFileID(Loc); 306 if (!Visited.insert(File).second) 307 continue; 308 309 // Do not map FileID's associated with system headers unless collecting 310 // coverage from system headers is explicitly enabled. 311 if (!SystemHeadersCoverage && SM.isInSystemHeader(SM.getSpellingLoc(Loc))) 312 continue; 313 314 unsigned Depth = 0; 315 for (SourceLocation Parent = getIncludeOrExpansionLoc(Loc); 316 Parent.isValid(); Parent = getIncludeOrExpansionLoc(Parent)) 317 ++Depth; 318 FileLocs.push_back(std::make_pair(Loc, Depth)); 319 } 320 llvm::stable_sort(FileLocs, llvm::less_second()); 321 322 for (const auto &FL : FileLocs) { 323 SourceLocation Loc = FL.first; 324 FileID SpellingFile = SM.getDecomposedSpellingLoc(Loc).first; 325 auto Entry = SM.getFileEntryRefForID(SpellingFile); 326 if (!Entry) 327 continue; 328 329 FileIDMapping[SM.getFileID(Loc)] = std::make_pair(Mapping.size(), Loc); 330 Mapping.push_back(CVM.getFileID(*Entry)); 331 } 332 } 333 334 /// Get the coverage mapping file ID for \c Loc. 335 /// 336 /// If such file id doesn't exist, return std::nullopt. 337 std::optional<unsigned> getCoverageFileID(SourceLocation Loc) { 338 auto Mapping = FileIDMapping.find(SM.getFileID(Loc)); 339 if (Mapping != FileIDMapping.end()) 340 return Mapping->second.first; 341 return std::nullopt; 342 } 343 344 /// This shrinks the skipped range if it spans a line that contains a 345 /// non-comment token. If shrinking the skipped range would make it empty, 346 /// this returns std::nullopt. 347 /// Note this function can potentially be expensive because 348 /// getSpellingLineNumber uses getLineNumber, which is expensive. 349 std::optional<SpellingRegion> adjustSkippedRange(SourceManager &SM, 350 SourceLocation LocStart, 351 SourceLocation LocEnd, 352 SourceLocation PrevTokLoc, 353 SourceLocation NextTokLoc) { 354 SpellingRegion SR{SM, LocStart, LocEnd}; 355 SR.ColumnStart = 1; 356 if (PrevTokLoc.isValid() && SM.isWrittenInSameFile(LocStart, PrevTokLoc) && 357 SR.LineStart == SM.getSpellingLineNumber(PrevTokLoc)) 358 SR.LineStart++; 359 if (NextTokLoc.isValid() && SM.isWrittenInSameFile(LocEnd, NextTokLoc) && 360 SR.LineEnd == SM.getSpellingLineNumber(NextTokLoc)) { 361 SR.LineEnd--; 362 SR.ColumnEnd++; 363 } 364 if (SR.isInSourceOrder()) 365 return SR; 366 return std::nullopt; 367 } 368 369 /// Gather all the regions that were skipped by the preprocessor 370 /// using the constructs like #if or comments. 371 void gatherSkippedRegions() { 372 /// An array of the minimum lineStarts and the maximum lineEnds 373 /// for mapping regions from the appropriate source files. 374 llvm::SmallVector<std::pair<unsigned, unsigned>, 8> FileLineRanges; 375 FileLineRanges.resize( 376 FileIDMapping.size(), 377 std::make_pair(std::numeric_limits<unsigned>::max(), 0)); 378 for (const auto &R : MappingRegions) { 379 FileLineRanges[R.FileID].first = 380 std::min(FileLineRanges[R.FileID].first, R.LineStart); 381 FileLineRanges[R.FileID].second = 382 std::max(FileLineRanges[R.FileID].second, R.LineEnd); 383 } 384 385 auto SkippedRanges = CVM.getSourceInfo().getSkippedRanges(); 386 for (auto &I : SkippedRanges) { 387 SourceRange Range = I.Range; 388 auto LocStart = Range.getBegin(); 389 auto LocEnd = Range.getEnd(); 390 assert(SM.isWrittenInSameFile(LocStart, LocEnd) && 391 "region spans multiple files"); 392 393 auto CovFileID = getCoverageFileID(LocStart); 394 if (!CovFileID) 395 continue; 396 std::optional<SpellingRegion> SR; 397 if (I.isComment()) 398 SR = adjustSkippedRange(SM, LocStart, LocEnd, I.PrevTokLoc, 399 I.NextTokLoc); 400 else if (I.isPPIfElse() || I.isEmptyLine()) 401 SR = {SM, LocStart, LocEnd}; 402 403 if (!SR) 404 continue; 405 auto Region = CounterMappingRegion::makeSkipped( 406 *CovFileID, SR->LineStart, SR->ColumnStart, SR->LineEnd, 407 SR->ColumnEnd); 408 // Make sure that we only collect the regions that are inside 409 // the source code of this function. 410 if (Region.LineStart >= FileLineRanges[*CovFileID].first && 411 Region.LineEnd <= FileLineRanges[*CovFileID].second) 412 MappingRegions.push_back(Region); 413 } 414 } 415 416 /// Generate the coverage counter mapping regions from collected 417 /// source regions. 418 void emitSourceRegions(const SourceRegionFilter &Filter) { 419 for (const auto &Region : SourceRegions) { 420 assert(Region.hasEndLoc() && "incomplete region"); 421 422 SourceLocation LocStart = Region.getBeginLoc(); 423 assert(SM.getFileID(LocStart).isValid() && "region in invalid file"); 424 425 // Ignore regions from system headers unless collecting coverage from 426 // system headers is explicitly enabled. 427 if (!SystemHeadersCoverage && 428 SM.isInSystemHeader(SM.getSpellingLoc(LocStart))) 429 continue; 430 431 auto CovFileID = getCoverageFileID(LocStart); 432 // Ignore regions that don't have a file, such as builtin macros. 433 if (!CovFileID) 434 continue; 435 436 SourceLocation LocEnd = Region.getEndLoc(); 437 assert(SM.isWrittenInSameFile(LocStart, LocEnd) && 438 "region spans multiple files"); 439 440 // Don't add code regions for the area covered by expansion regions. 441 // This not only suppresses redundant regions, but sometimes prevents 442 // creating regions with wrong counters if, for example, a statement's 443 // body ends at the end of a nested macro. 444 if (Filter.count(std::make_pair(LocStart, LocEnd))) 445 continue; 446 447 // Find the spelling locations for the mapping region. 448 SpellingRegion SR{SM, LocStart, LocEnd}; 449 assert(SR.isInSourceOrder() && "region start and end out of order"); 450 451 if (Region.isGap()) { 452 MappingRegions.push_back(CounterMappingRegion::makeGapRegion( 453 Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart, 454 SR.LineEnd, SR.ColumnEnd)); 455 } else if (Region.isBranch()) { 456 MappingRegions.push_back(CounterMappingRegion::makeBranchRegion( 457 Region.getCounter(), Region.getFalseCounter(), *CovFileID, 458 SR.LineStart, SR.ColumnStart, SR.LineEnd, SR.ColumnEnd)); 459 } else { 460 MappingRegions.push_back(CounterMappingRegion::makeRegion( 461 Region.getCounter(), *CovFileID, SR.LineStart, SR.ColumnStart, 462 SR.LineEnd, SR.ColumnEnd)); 463 } 464 } 465 } 466 467 /// Generate expansion regions for each virtual file we've seen. 468 SourceRegionFilter emitExpansionRegions() { 469 SourceRegionFilter Filter; 470 for (const auto &FM : FileIDMapping) { 471 SourceLocation ExpandedLoc = FM.second.second; 472 SourceLocation ParentLoc = getIncludeOrExpansionLoc(ExpandedLoc); 473 if (ParentLoc.isInvalid()) 474 continue; 475 476 auto ParentFileID = getCoverageFileID(ParentLoc); 477 if (!ParentFileID) 478 continue; 479 auto ExpandedFileID = getCoverageFileID(ExpandedLoc); 480 assert(ExpandedFileID && "expansion in uncovered file"); 481 482 SourceLocation LocEnd = getPreciseTokenLocEnd(ParentLoc); 483 assert(SM.isWrittenInSameFile(ParentLoc, LocEnd) && 484 "region spans multiple files"); 485 Filter.insert(std::make_pair(ParentLoc, LocEnd)); 486 487 SpellingRegion SR{SM, ParentLoc, LocEnd}; 488 assert(SR.isInSourceOrder() && "region start and end out of order"); 489 MappingRegions.push_back(CounterMappingRegion::makeExpansion( 490 *ParentFileID, *ExpandedFileID, SR.LineStart, SR.ColumnStart, 491 SR.LineEnd, SR.ColumnEnd)); 492 } 493 return Filter; 494 } 495 }; 496 497 /// Creates unreachable coverage regions for the functions that 498 /// are not emitted. 499 struct EmptyCoverageMappingBuilder : public CoverageMappingBuilder { 500 EmptyCoverageMappingBuilder(CoverageMappingModuleGen &CVM, SourceManager &SM, 501 const LangOptions &LangOpts) 502 : CoverageMappingBuilder(CVM, SM, LangOpts) {} 503 504 void VisitDecl(const Decl *D) { 505 if (!D->hasBody()) 506 return; 507 auto Body = D->getBody(); 508 SourceLocation Start = getStart(Body); 509 SourceLocation End = getEnd(Body); 510 if (!SM.isWrittenInSameFile(Start, End)) { 511 // Walk up to find the common ancestor. 512 // Correct the locations accordingly. 513 FileID StartFileID = SM.getFileID(Start); 514 FileID EndFileID = SM.getFileID(End); 515 while (StartFileID != EndFileID && !isNestedIn(End, StartFileID)) { 516 Start = getIncludeOrExpansionLoc(Start); 517 assert(Start.isValid() && 518 "Declaration start location not nested within a known region"); 519 StartFileID = SM.getFileID(Start); 520 } 521 while (StartFileID != EndFileID) { 522 End = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(End)); 523 assert(End.isValid() && 524 "Declaration end location not nested within a known region"); 525 EndFileID = SM.getFileID(End); 526 } 527 } 528 SourceRegions.emplace_back(Counter(), Start, End); 529 } 530 531 /// Write the mapping data to the output stream 532 void write(llvm::raw_ostream &OS) { 533 SmallVector<unsigned, 16> FileIDMapping; 534 gatherFileIDs(FileIDMapping); 535 emitSourceRegions(SourceRegionFilter()); 536 537 if (MappingRegions.empty()) 538 return; 539 540 CoverageMappingWriter Writer(FileIDMapping, std::nullopt, MappingRegions); 541 Writer.write(OS); 542 } 543 }; 544 545 /// A StmtVisitor that creates coverage mapping regions which map 546 /// from the source code locations to the PGO counters. 547 struct CounterCoverageMappingBuilder 548 : public CoverageMappingBuilder, 549 public ConstStmtVisitor<CounterCoverageMappingBuilder> { 550 /// The map of statements to count values. 551 llvm::DenseMap<const Stmt *, unsigned> &CounterMap; 552 553 /// A stack of currently live regions. 554 std::vector<SourceMappingRegion> RegionStack; 555 556 CounterExpressionBuilder Builder; 557 558 /// A location in the most recently visited file or macro. 559 /// 560 /// This is used to adjust the active source regions appropriately when 561 /// expressions cross file or macro boundaries. 562 SourceLocation MostRecentLocation; 563 564 /// Whether the visitor at a terminate statement. 565 bool HasTerminateStmt = false; 566 567 /// Gap region counter after terminate statement. 568 Counter GapRegionCounter; 569 570 /// Return a counter for the subtraction of \c RHS from \c LHS 571 Counter subtractCounters(Counter LHS, Counter RHS, bool Simplify = true) { 572 return Builder.subtract(LHS, RHS, Simplify); 573 } 574 575 /// Return a counter for the sum of \c LHS and \c RHS. 576 Counter addCounters(Counter LHS, Counter RHS, bool Simplify = true) { 577 return Builder.add(LHS, RHS, Simplify); 578 } 579 580 Counter addCounters(Counter C1, Counter C2, Counter C3, 581 bool Simplify = true) { 582 return addCounters(addCounters(C1, C2, Simplify), C3, Simplify); 583 } 584 585 /// Return the region counter for the given statement. 586 /// 587 /// This should only be called on statements that have a dedicated counter. 588 Counter getRegionCounter(const Stmt *S) { 589 return Counter::getCounter(CounterMap[S]); 590 } 591 592 /// Push a region onto the stack. 593 /// 594 /// Returns the index on the stack where the region was pushed. This can be 595 /// used with popRegions to exit a "scope", ending the region that was pushed. 596 size_t pushRegion(Counter Count, 597 std::optional<SourceLocation> StartLoc = std::nullopt, 598 std::optional<SourceLocation> EndLoc = std::nullopt, 599 std::optional<Counter> FalseCount = std::nullopt) { 600 601 if (StartLoc && !FalseCount) { 602 MostRecentLocation = *StartLoc; 603 } 604 605 // If either of these locations is invalid, something elsewhere in the 606 // compiler has broken. 607 assert((!StartLoc || StartLoc->isValid()) && "Start location is not valid"); 608 assert((!EndLoc || EndLoc->isValid()) && "End location is not valid"); 609 610 // However, we can still recover without crashing. 611 // If either location is invalid, set it to std::nullopt to avoid 612 // letting users of RegionStack think that region has a valid start/end 613 // location. 614 if (StartLoc && StartLoc->isInvalid()) 615 StartLoc = std::nullopt; 616 if (EndLoc && EndLoc->isInvalid()) 617 EndLoc = std::nullopt; 618 RegionStack.emplace_back(Count, FalseCount, StartLoc, EndLoc); 619 620 return RegionStack.size() - 1; 621 } 622 623 size_t locationDepth(SourceLocation Loc) { 624 size_t Depth = 0; 625 while (Loc.isValid()) { 626 Loc = getIncludeOrExpansionLoc(Loc); 627 Depth++; 628 } 629 return Depth; 630 } 631 632 /// Pop regions from the stack into the function's list of regions. 633 /// 634 /// Adds all regions from \c ParentIndex to the top of the stack to the 635 /// function's \c SourceRegions. 636 void popRegions(size_t ParentIndex) { 637 assert(RegionStack.size() >= ParentIndex && "parent not in stack"); 638 while (RegionStack.size() > ParentIndex) { 639 SourceMappingRegion &Region = RegionStack.back(); 640 if (Region.hasStartLoc() && 641 (Region.hasEndLoc() || RegionStack[ParentIndex].hasEndLoc())) { 642 SourceLocation StartLoc = Region.getBeginLoc(); 643 SourceLocation EndLoc = Region.hasEndLoc() 644 ? Region.getEndLoc() 645 : RegionStack[ParentIndex].getEndLoc(); 646 bool isBranch = Region.isBranch(); 647 size_t StartDepth = locationDepth(StartLoc); 648 size_t EndDepth = locationDepth(EndLoc); 649 while (!SM.isWrittenInSameFile(StartLoc, EndLoc)) { 650 bool UnnestStart = StartDepth >= EndDepth; 651 bool UnnestEnd = EndDepth >= StartDepth; 652 if (UnnestEnd) { 653 // The region ends in a nested file or macro expansion. If the 654 // region is not a branch region, create a separate region for each 655 // expansion, and for all regions, update the EndLoc. Branch 656 // regions should not be split in order to keep a straightforward 657 // correspondance between the region and its associated branch 658 // condition, even if the condition spans multiple depths. 659 SourceLocation NestedLoc = getStartOfFileOrMacro(EndLoc); 660 assert(SM.isWrittenInSameFile(NestedLoc, EndLoc)); 661 662 if (!isBranch && !isRegionAlreadyAdded(NestedLoc, EndLoc)) 663 SourceRegions.emplace_back(Region.getCounter(), NestedLoc, 664 EndLoc); 665 666 EndLoc = getPreciseTokenLocEnd(getIncludeOrExpansionLoc(EndLoc)); 667 if (EndLoc.isInvalid()) 668 llvm::report_fatal_error( 669 "File exit not handled before popRegions"); 670 EndDepth--; 671 } 672 if (UnnestStart) { 673 // The region ends in a nested file or macro expansion. If the 674 // region is not a branch region, create a separate region for each 675 // expansion, and for all regions, update the StartLoc. Branch 676 // regions should not be split in order to keep a straightforward 677 // correspondance between the region and its associated branch 678 // condition, even if the condition spans multiple depths. 679 SourceLocation NestedLoc = getEndOfFileOrMacro(StartLoc); 680 assert(SM.isWrittenInSameFile(StartLoc, NestedLoc)); 681 682 if (!isBranch && !isRegionAlreadyAdded(StartLoc, NestedLoc)) 683 SourceRegions.emplace_back(Region.getCounter(), StartLoc, 684 NestedLoc); 685 686 StartLoc = getIncludeOrExpansionLoc(StartLoc); 687 if (StartLoc.isInvalid()) 688 llvm::report_fatal_error( 689 "File exit not handled before popRegions"); 690 StartDepth--; 691 } 692 } 693 Region.setStartLoc(StartLoc); 694 Region.setEndLoc(EndLoc); 695 696 if (!isBranch) { 697 MostRecentLocation = EndLoc; 698 // If this region happens to span an entire expansion, we need to 699 // make sure we don't overlap the parent region with it. 700 if (StartLoc == getStartOfFileOrMacro(StartLoc) && 701 EndLoc == getEndOfFileOrMacro(EndLoc)) 702 MostRecentLocation = getIncludeOrExpansionLoc(EndLoc); 703 } 704 705 assert(SM.isWrittenInSameFile(Region.getBeginLoc(), EndLoc)); 706 assert(SpellingRegion(SM, Region).isInSourceOrder()); 707 SourceRegions.push_back(Region); 708 } 709 RegionStack.pop_back(); 710 } 711 } 712 713 /// Return the currently active region. 714 SourceMappingRegion &getRegion() { 715 assert(!RegionStack.empty() && "statement has no region"); 716 return RegionStack.back(); 717 } 718 719 /// Propagate counts through the children of \p S if \p VisitChildren is true. 720 /// Otherwise, only emit a count for \p S itself. 721 Counter propagateCounts(Counter TopCount, const Stmt *S, 722 bool VisitChildren = true) { 723 SourceLocation StartLoc = getStart(S); 724 SourceLocation EndLoc = getEnd(S); 725 size_t Index = pushRegion(TopCount, StartLoc, EndLoc); 726 if (VisitChildren) 727 Visit(S); 728 Counter ExitCount = getRegion().getCounter(); 729 popRegions(Index); 730 731 // The statement may be spanned by an expansion. Make sure we handle a file 732 // exit out of this expansion before moving to the next statement. 733 if (SM.isBeforeInTranslationUnit(StartLoc, S->getBeginLoc())) 734 MostRecentLocation = EndLoc; 735 736 return ExitCount; 737 } 738 739 /// Determine whether the given condition can be constant folded. 740 bool ConditionFoldsToBool(const Expr *Cond) { 741 Expr::EvalResult Result; 742 return (Cond->EvaluateAsInt(Result, CVM.getCodeGenModule().getContext())); 743 } 744 745 /// Create a Branch Region around an instrumentable condition for coverage 746 /// and add it to the function's SourceRegions. A branch region tracks a 747 /// "True" counter and a "False" counter for boolean expressions that 748 /// result in the generation of a branch. 749 void createBranchRegion(const Expr *C, Counter TrueCnt, Counter FalseCnt) { 750 // Check for NULL conditions. 751 if (!C) 752 return; 753 754 // Ensure we are an instrumentable condition (i.e. no "&&" or "||"). Push 755 // region onto RegionStack but immediately pop it (which adds it to the 756 // function's SourceRegions) because it doesn't apply to any other source 757 // code other than the Condition. 758 if (CodeGenFunction::isInstrumentedCondition(C)) { 759 // If a condition can fold to true or false, the corresponding branch 760 // will be removed. Create a region with both counters hard-coded to 761 // zero. This allows us to visualize them in a special way. 762 // Alternatively, we can prevent any optimization done via 763 // constant-folding by ensuring that ConstantFoldsToSimpleInteger() in 764 // CodeGenFunction.c always returns false, but that is very heavy-handed. 765 if (ConditionFoldsToBool(C)) 766 popRegions(pushRegion(Counter::getZero(), getStart(C), getEnd(C), 767 Counter::getZero())); 768 else 769 // Otherwise, create a region with the True counter and False counter. 770 popRegions(pushRegion(TrueCnt, getStart(C), getEnd(C), FalseCnt)); 771 } 772 } 773 774 /// Create a Branch Region around a SwitchCase for code coverage 775 /// and add it to the function's SourceRegions. 776 void createSwitchCaseRegion(const SwitchCase *SC, Counter TrueCnt, 777 Counter FalseCnt) { 778 // Push region onto RegionStack but immediately pop it (which adds it to 779 // the function's SourceRegions) because it doesn't apply to any other 780 // source other than the SwitchCase. 781 popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(), FalseCnt)); 782 } 783 784 /// Check whether a region with bounds \c StartLoc and \c EndLoc 785 /// is already added to \c SourceRegions. 786 bool isRegionAlreadyAdded(SourceLocation StartLoc, SourceLocation EndLoc, 787 bool isBranch = false) { 788 return llvm::any_of( 789 llvm::reverse(SourceRegions), [&](const SourceMappingRegion &Region) { 790 return Region.getBeginLoc() == StartLoc && 791 Region.getEndLoc() == EndLoc && Region.isBranch() == isBranch; 792 }); 793 } 794 795 /// Adjust the most recently visited location to \c EndLoc. 796 /// 797 /// This should be used after visiting any statements in non-source order. 798 void adjustForOutOfOrderTraversal(SourceLocation EndLoc) { 799 MostRecentLocation = EndLoc; 800 // The code region for a whole macro is created in handleFileExit() when 801 // it detects exiting of the virtual file of that macro. If we visited 802 // statements in non-source order, we might already have such a region 803 // added, for example, if a body of a loop is divided among multiple 804 // macros. Avoid adding duplicate regions in such case. 805 if (getRegion().hasEndLoc() && 806 MostRecentLocation == getEndOfFileOrMacro(MostRecentLocation) && 807 isRegionAlreadyAdded(getStartOfFileOrMacro(MostRecentLocation), 808 MostRecentLocation, getRegion().isBranch())) 809 MostRecentLocation = getIncludeOrExpansionLoc(MostRecentLocation); 810 } 811 812 /// Adjust regions and state when \c NewLoc exits a file. 813 /// 814 /// If moving from our most recently tracked location to \c NewLoc exits any 815 /// files, this adjusts our current region stack and creates the file regions 816 /// for the exited file. 817 void handleFileExit(SourceLocation NewLoc) { 818 if (NewLoc.isInvalid() || 819 SM.isWrittenInSameFile(MostRecentLocation, NewLoc)) 820 return; 821 822 // If NewLoc is not in a file that contains MostRecentLocation, walk up to 823 // find the common ancestor. 824 SourceLocation LCA = NewLoc; 825 FileID ParentFile = SM.getFileID(LCA); 826 while (!isNestedIn(MostRecentLocation, ParentFile)) { 827 LCA = getIncludeOrExpansionLoc(LCA); 828 if (LCA.isInvalid() || SM.isWrittenInSameFile(LCA, MostRecentLocation)) { 829 // Since there isn't a common ancestor, no file was exited. We just need 830 // to adjust our location to the new file. 831 MostRecentLocation = NewLoc; 832 return; 833 } 834 ParentFile = SM.getFileID(LCA); 835 } 836 837 llvm::SmallSet<SourceLocation, 8> StartLocs; 838 std::optional<Counter> ParentCounter; 839 for (SourceMappingRegion &I : llvm::reverse(RegionStack)) { 840 if (!I.hasStartLoc()) 841 continue; 842 SourceLocation Loc = I.getBeginLoc(); 843 if (!isNestedIn(Loc, ParentFile)) { 844 ParentCounter = I.getCounter(); 845 break; 846 } 847 848 while (!SM.isInFileID(Loc, ParentFile)) { 849 // The most nested region for each start location is the one with the 850 // correct count. We avoid creating redundant regions by stopping once 851 // we've seen this region. 852 if (StartLocs.insert(Loc).second) { 853 if (I.isBranch()) 854 SourceRegions.emplace_back(I.getCounter(), I.getFalseCounter(), Loc, 855 getEndOfFileOrMacro(Loc), I.isBranch()); 856 else 857 SourceRegions.emplace_back(I.getCounter(), Loc, 858 getEndOfFileOrMacro(Loc)); 859 } 860 Loc = getIncludeOrExpansionLoc(Loc); 861 } 862 I.setStartLoc(getPreciseTokenLocEnd(Loc)); 863 } 864 865 if (ParentCounter) { 866 // If the file is contained completely by another region and doesn't 867 // immediately start its own region, the whole file gets a region 868 // corresponding to the parent. 869 SourceLocation Loc = MostRecentLocation; 870 while (isNestedIn(Loc, ParentFile)) { 871 SourceLocation FileStart = getStartOfFileOrMacro(Loc); 872 if (StartLocs.insert(FileStart).second) { 873 SourceRegions.emplace_back(*ParentCounter, FileStart, 874 getEndOfFileOrMacro(Loc)); 875 assert(SpellingRegion(SM, SourceRegions.back()).isInSourceOrder()); 876 } 877 Loc = getIncludeOrExpansionLoc(Loc); 878 } 879 } 880 881 MostRecentLocation = NewLoc; 882 } 883 884 /// Ensure that \c S is included in the current region. 885 void extendRegion(const Stmt *S) { 886 SourceMappingRegion &Region = getRegion(); 887 SourceLocation StartLoc = getStart(S); 888 889 handleFileExit(StartLoc); 890 if (!Region.hasStartLoc()) 891 Region.setStartLoc(StartLoc); 892 } 893 894 /// Mark \c S as a terminator, starting a zero region. 895 void terminateRegion(const Stmt *S) { 896 extendRegion(S); 897 SourceMappingRegion &Region = getRegion(); 898 SourceLocation EndLoc = getEnd(S); 899 if (!Region.hasEndLoc()) 900 Region.setEndLoc(EndLoc); 901 pushRegion(Counter::getZero()); 902 HasTerminateStmt = true; 903 } 904 905 /// Find a valid gap range between \p AfterLoc and \p BeforeLoc. 906 std::optional<SourceRange> findGapAreaBetween(SourceLocation AfterLoc, 907 SourceLocation BeforeLoc) { 908 // If AfterLoc is in function-like macro, use the right parenthesis 909 // location. 910 if (AfterLoc.isMacroID()) { 911 FileID FID = SM.getFileID(AfterLoc); 912 const SrcMgr::ExpansionInfo *EI = &SM.getSLocEntry(FID).getExpansion(); 913 if (EI->isFunctionMacroExpansion()) 914 AfterLoc = EI->getExpansionLocEnd(); 915 } 916 917 size_t StartDepth = locationDepth(AfterLoc); 918 size_t EndDepth = locationDepth(BeforeLoc); 919 while (!SM.isWrittenInSameFile(AfterLoc, BeforeLoc)) { 920 bool UnnestStart = StartDepth >= EndDepth; 921 bool UnnestEnd = EndDepth >= StartDepth; 922 if (UnnestEnd) { 923 assert(SM.isWrittenInSameFile(getStartOfFileOrMacro(BeforeLoc), 924 BeforeLoc)); 925 926 BeforeLoc = getIncludeOrExpansionLoc(BeforeLoc); 927 assert(BeforeLoc.isValid()); 928 EndDepth--; 929 } 930 if (UnnestStart) { 931 assert(SM.isWrittenInSameFile(AfterLoc, 932 getEndOfFileOrMacro(AfterLoc))); 933 934 AfterLoc = getIncludeOrExpansionLoc(AfterLoc); 935 assert(AfterLoc.isValid()); 936 AfterLoc = getPreciseTokenLocEnd(AfterLoc); 937 assert(AfterLoc.isValid()); 938 StartDepth--; 939 } 940 } 941 AfterLoc = getPreciseTokenLocEnd(AfterLoc); 942 // If the start and end locations of the gap are both within the same macro 943 // file, the range may not be in source order. 944 if (AfterLoc.isMacroID() || BeforeLoc.isMacroID()) 945 return std::nullopt; 946 if (!SM.isWrittenInSameFile(AfterLoc, BeforeLoc) || 947 !SpellingRegion(SM, AfterLoc, BeforeLoc).isInSourceOrder()) 948 return std::nullopt; 949 return {{AfterLoc, BeforeLoc}}; 950 } 951 952 /// Emit a gap region between \p StartLoc and \p EndLoc with the given count. 953 void fillGapAreaWithCount(SourceLocation StartLoc, SourceLocation EndLoc, 954 Counter Count) { 955 if (StartLoc == EndLoc) 956 return; 957 assert(SpellingRegion(SM, StartLoc, EndLoc).isInSourceOrder()); 958 handleFileExit(StartLoc); 959 size_t Index = pushRegion(Count, StartLoc, EndLoc); 960 getRegion().setGap(true); 961 handleFileExit(EndLoc); 962 popRegions(Index); 963 } 964 965 /// Keep counts of breaks and continues inside loops. 966 struct BreakContinue { 967 Counter BreakCount; 968 Counter ContinueCount; 969 }; 970 SmallVector<BreakContinue, 8> BreakContinueStack; 971 972 CounterCoverageMappingBuilder( 973 CoverageMappingModuleGen &CVM, 974 llvm::DenseMap<const Stmt *, unsigned> &CounterMap, SourceManager &SM, 975 const LangOptions &LangOpts) 976 : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap) {} 977 978 /// Write the mapping data to the output stream 979 void write(llvm::raw_ostream &OS) { 980 llvm::SmallVector<unsigned, 8> VirtualFileMapping; 981 gatherFileIDs(VirtualFileMapping); 982 SourceRegionFilter Filter = emitExpansionRegions(); 983 emitSourceRegions(Filter); 984 gatherSkippedRegions(); 985 986 if (MappingRegions.empty()) 987 return; 988 989 CoverageMappingWriter Writer(VirtualFileMapping, Builder.getExpressions(), 990 MappingRegions); 991 Writer.write(OS); 992 } 993 994 void VisitStmt(const Stmt *S) { 995 if (S->getBeginLoc().isValid()) 996 extendRegion(S); 997 const Stmt *LastStmt = nullptr; 998 bool SaveTerminateStmt = HasTerminateStmt; 999 HasTerminateStmt = false; 1000 GapRegionCounter = Counter::getZero(); 1001 for (const Stmt *Child : S->children()) 1002 if (Child) { 1003 // If last statement contains terminate statements, add a gap area 1004 // between the two statements. Skipping attributed statements, because 1005 // they don't have valid start location. 1006 if (LastStmt && HasTerminateStmt && !isa<AttributedStmt>(Child)) { 1007 auto Gap = findGapAreaBetween(getEnd(LastStmt), getStart(Child)); 1008 if (Gap) 1009 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), 1010 GapRegionCounter); 1011 SaveTerminateStmt = true; 1012 HasTerminateStmt = false; 1013 } 1014 this->Visit(Child); 1015 LastStmt = Child; 1016 } 1017 if (SaveTerminateStmt) 1018 HasTerminateStmt = true; 1019 handleFileExit(getEnd(S)); 1020 } 1021 1022 void VisitDecl(const Decl *D) { 1023 Stmt *Body = D->getBody(); 1024 1025 // Do not propagate region counts into system headers unless collecting 1026 // coverage from system headers is explicitly enabled. 1027 if (!SystemHeadersCoverage && Body && 1028 SM.isInSystemHeader(SM.getSpellingLoc(getStart(Body)))) 1029 return; 1030 1031 // Do not visit the artificial children nodes of defaulted methods. The 1032 // lexer may not be able to report back precise token end locations for 1033 // these children nodes (llvm.org/PR39822), and moreover users will not be 1034 // able to see coverage for them. 1035 Counter BodyCounter = getRegionCounter(Body); 1036 bool Defaulted = false; 1037 if (auto *Method = dyn_cast<CXXMethodDecl>(D)) 1038 Defaulted = Method->isDefaulted(); 1039 if (auto *Ctor = dyn_cast<CXXConstructorDecl>(D)) { 1040 for (auto *Initializer : Ctor->inits()) { 1041 if (Initializer->isWritten()) { 1042 auto *Init = Initializer->getInit(); 1043 if (getStart(Init).isValid() && getEnd(Init).isValid()) 1044 propagateCounts(BodyCounter, Init); 1045 } 1046 } 1047 } 1048 1049 propagateCounts(BodyCounter, Body, 1050 /*VisitChildren=*/!Defaulted); 1051 assert(RegionStack.empty() && "Regions entered but never exited"); 1052 } 1053 1054 void VisitReturnStmt(const ReturnStmt *S) { 1055 extendRegion(S); 1056 if (S->getRetValue()) 1057 Visit(S->getRetValue()); 1058 terminateRegion(S); 1059 } 1060 1061 void VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) { 1062 extendRegion(S); 1063 Visit(S->getBody()); 1064 } 1065 1066 void VisitCoreturnStmt(const CoreturnStmt *S) { 1067 extendRegion(S); 1068 if (S->getOperand()) 1069 Visit(S->getOperand()); 1070 terminateRegion(S); 1071 } 1072 1073 void VisitCXXThrowExpr(const CXXThrowExpr *E) { 1074 extendRegion(E); 1075 if (E->getSubExpr()) 1076 Visit(E->getSubExpr()); 1077 terminateRegion(E); 1078 } 1079 1080 void VisitGotoStmt(const GotoStmt *S) { terminateRegion(S); } 1081 1082 void VisitLabelStmt(const LabelStmt *S) { 1083 Counter LabelCount = getRegionCounter(S); 1084 SourceLocation Start = getStart(S); 1085 // We can't extendRegion here or we risk overlapping with our new region. 1086 handleFileExit(Start); 1087 pushRegion(LabelCount, Start); 1088 Visit(S->getSubStmt()); 1089 } 1090 1091 void VisitBreakStmt(const BreakStmt *S) { 1092 assert(!BreakContinueStack.empty() && "break not in a loop or switch!"); 1093 BreakContinueStack.back().BreakCount = addCounters( 1094 BreakContinueStack.back().BreakCount, getRegion().getCounter()); 1095 // FIXME: a break in a switch should terminate regions for all preceding 1096 // case statements, not just the most recent one. 1097 terminateRegion(S); 1098 } 1099 1100 void VisitContinueStmt(const ContinueStmt *S) { 1101 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 1102 BreakContinueStack.back().ContinueCount = addCounters( 1103 BreakContinueStack.back().ContinueCount, getRegion().getCounter()); 1104 terminateRegion(S); 1105 } 1106 1107 void VisitCallExpr(const CallExpr *E) { 1108 VisitStmt(E); 1109 1110 // Terminate the region when we hit a noreturn function. 1111 // (This is helpful dealing with switch statements.) 1112 QualType CalleeType = E->getCallee()->getType(); 1113 if (getFunctionExtInfo(*CalleeType).getNoReturn()) 1114 terminateRegion(E); 1115 } 1116 1117 void VisitWhileStmt(const WhileStmt *S) { 1118 extendRegion(S); 1119 1120 Counter ParentCount = getRegion().getCounter(); 1121 Counter BodyCount = getRegionCounter(S); 1122 1123 // Handle the body first so that we can get the backedge count. 1124 BreakContinueStack.push_back(BreakContinue()); 1125 extendRegion(S->getBody()); 1126 Counter BackedgeCount = propagateCounts(BodyCount, S->getBody()); 1127 BreakContinue BC = BreakContinueStack.pop_back_val(); 1128 1129 bool BodyHasTerminateStmt = HasTerminateStmt; 1130 HasTerminateStmt = false; 1131 1132 // Go back to handle the condition. 1133 Counter CondCount = 1134 addCounters(ParentCount, BackedgeCount, BC.ContinueCount); 1135 propagateCounts(CondCount, S->getCond()); 1136 adjustForOutOfOrderTraversal(getEnd(S)); 1137 1138 // The body count applies to the area immediately after the increment. 1139 auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody())); 1140 if (Gap) 1141 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); 1142 1143 Counter OutCount = 1144 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount)); 1145 if (OutCount != ParentCount) { 1146 pushRegion(OutCount); 1147 GapRegionCounter = OutCount; 1148 if (BodyHasTerminateStmt) 1149 HasTerminateStmt = true; 1150 } 1151 1152 // Create Branch Region around condition. 1153 createBranchRegion(S->getCond(), BodyCount, 1154 subtractCounters(CondCount, BodyCount)); 1155 } 1156 1157 void VisitDoStmt(const DoStmt *S) { 1158 extendRegion(S); 1159 1160 Counter ParentCount = getRegion().getCounter(); 1161 Counter BodyCount = getRegionCounter(S); 1162 1163 BreakContinueStack.push_back(BreakContinue()); 1164 extendRegion(S->getBody()); 1165 Counter BackedgeCount = 1166 propagateCounts(addCounters(ParentCount, BodyCount), S->getBody()); 1167 BreakContinue BC = BreakContinueStack.pop_back_val(); 1168 1169 bool BodyHasTerminateStmt = HasTerminateStmt; 1170 HasTerminateStmt = false; 1171 1172 Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount); 1173 propagateCounts(CondCount, S->getCond()); 1174 1175 Counter OutCount = 1176 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount)); 1177 if (OutCount != ParentCount) { 1178 pushRegion(OutCount); 1179 GapRegionCounter = OutCount; 1180 } 1181 1182 // Create Branch Region around condition. 1183 createBranchRegion(S->getCond(), BodyCount, 1184 subtractCounters(CondCount, BodyCount)); 1185 1186 if (BodyHasTerminateStmt) 1187 HasTerminateStmt = true; 1188 } 1189 1190 void VisitForStmt(const ForStmt *S) { 1191 extendRegion(S); 1192 if (S->getInit()) 1193 Visit(S->getInit()); 1194 1195 Counter ParentCount = getRegion().getCounter(); 1196 Counter BodyCount = getRegionCounter(S); 1197 1198 // The loop increment may contain a break or continue. 1199 if (S->getInc()) 1200 BreakContinueStack.emplace_back(); 1201 1202 // Handle the body first so that we can get the backedge count. 1203 BreakContinueStack.emplace_back(); 1204 extendRegion(S->getBody()); 1205 Counter BackedgeCount = propagateCounts(BodyCount, S->getBody()); 1206 BreakContinue BodyBC = BreakContinueStack.pop_back_val(); 1207 1208 bool BodyHasTerminateStmt = HasTerminateStmt; 1209 HasTerminateStmt = false; 1210 1211 // The increment is essentially part of the body but it needs to include 1212 // the count for all the continue statements. 1213 BreakContinue IncrementBC; 1214 if (const Stmt *Inc = S->getInc()) { 1215 propagateCounts(addCounters(BackedgeCount, BodyBC.ContinueCount), Inc); 1216 IncrementBC = BreakContinueStack.pop_back_val(); 1217 } 1218 1219 // Go back to handle the condition. 1220 Counter CondCount = addCounters( 1221 addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount), 1222 IncrementBC.ContinueCount); 1223 if (const Expr *Cond = S->getCond()) { 1224 propagateCounts(CondCount, Cond); 1225 adjustForOutOfOrderTraversal(getEnd(S)); 1226 } 1227 1228 // The body count applies to the area immediately after the increment. 1229 auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody())); 1230 if (Gap) 1231 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); 1232 1233 Counter OutCount = addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, 1234 subtractCounters(CondCount, BodyCount)); 1235 if (OutCount != ParentCount) { 1236 pushRegion(OutCount); 1237 GapRegionCounter = OutCount; 1238 if (BodyHasTerminateStmt) 1239 HasTerminateStmt = true; 1240 } 1241 1242 // Create Branch Region around condition. 1243 createBranchRegion(S->getCond(), BodyCount, 1244 subtractCounters(CondCount, BodyCount)); 1245 } 1246 1247 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 1248 extendRegion(S); 1249 if (S->getInit()) 1250 Visit(S->getInit()); 1251 Visit(S->getLoopVarStmt()); 1252 Visit(S->getRangeStmt()); 1253 1254 Counter ParentCount = getRegion().getCounter(); 1255 Counter BodyCount = getRegionCounter(S); 1256 1257 BreakContinueStack.push_back(BreakContinue()); 1258 extendRegion(S->getBody()); 1259 Counter BackedgeCount = propagateCounts(BodyCount, S->getBody()); 1260 BreakContinue BC = BreakContinueStack.pop_back_val(); 1261 1262 bool BodyHasTerminateStmt = HasTerminateStmt; 1263 HasTerminateStmt = false; 1264 1265 // The body count applies to the area immediately after the range. 1266 auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody())); 1267 if (Gap) 1268 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); 1269 1270 Counter LoopCount = 1271 addCounters(ParentCount, BackedgeCount, BC.ContinueCount); 1272 Counter OutCount = 1273 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount)); 1274 if (OutCount != ParentCount) { 1275 pushRegion(OutCount); 1276 GapRegionCounter = OutCount; 1277 if (BodyHasTerminateStmt) 1278 HasTerminateStmt = true; 1279 } 1280 1281 // Create Branch Region around condition. 1282 createBranchRegion(S->getCond(), BodyCount, 1283 subtractCounters(LoopCount, BodyCount)); 1284 } 1285 1286 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { 1287 extendRegion(S); 1288 Visit(S->getElement()); 1289 1290 Counter ParentCount = getRegion().getCounter(); 1291 Counter BodyCount = getRegionCounter(S); 1292 1293 BreakContinueStack.push_back(BreakContinue()); 1294 extendRegion(S->getBody()); 1295 Counter BackedgeCount = propagateCounts(BodyCount, S->getBody()); 1296 BreakContinue BC = BreakContinueStack.pop_back_val(); 1297 1298 // The body count applies to the area immediately after the collection. 1299 auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody())); 1300 if (Gap) 1301 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); 1302 1303 Counter LoopCount = 1304 addCounters(ParentCount, BackedgeCount, BC.ContinueCount); 1305 Counter OutCount = 1306 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount)); 1307 if (OutCount != ParentCount) { 1308 pushRegion(OutCount); 1309 GapRegionCounter = OutCount; 1310 } 1311 } 1312 1313 void VisitSwitchStmt(const SwitchStmt *S) { 1314 extendRegion(S); 1315 if (S->getInit()) 1316 Visit(S->getInit()); 1317 Visit(S->getCond()); 1318 1319 BreakContinueStack.push_back(BreakContinue()); 1320 1321 const Stmt *Body = S->getBody(); 1322 extendRegion(Body); 1323 if (const auto *CS = dyn_cast<CompoundStmt>(Body)) { 1324 if (!CS->body_empty()) { 1325 // Make a region for the body of the switch. If the body starts with 1326 // a case, that case will reuse this region; otherwise, this covers 1327 // the unreachable code at the beginning of the switch body. 1328 size_t Index = pushRegion(Counter::getZero(), getStart(CS)); 1329 getRegion().setGap(true); 1330 Visit(Body); 1331 1332 // Set the end for the body of the switch, if it isn't already set. 1333 for (size_t i = RegionStack.size(); i != Index; --i) { 1334 if (!RegionStack[i - 1].hasEndLoc()) 1335 RegionStack[i - 1].setEndLoc(getEnd(CS->body_back())); 1336 } 1337 1338 popRegions(Index); 1339 } 1340 } else 1341 propagateCounts(Counter::getZero(), Body); 1342 BreakContinue BC = BreakContinueStack.pop_back_val(); 1343 1344 if (!BreakContinueStack.empty()) 1345 BreakContinueStack.back().ContinueCount = addCounters( 1346 BreakContinueStack.back().ContinueCount, BC.ContinueCount); 1347 1348 Counter ParentCount = getRegion().getCounter(); 1349 Counter ExitCount = getRegionCounter(S); 1350 SourceLocation ExitLoc = getEnd(S); 1351 pushRegion(ExitCount); 1352 GapRegionCounter = ExitCount; 1353 1354 // Ensure that handleFileExit recognizes when the end location is located 1355 // in a different file. 1356 MostRecentLocation = getStart(S); 1357 handleFileExit(ExitLoc); 1358 1359 // Create a Branch Region around each Case. Subtract the case's 1360 // counter from the Parent counter to track the "False" branch count. 1361 Counter CaseCountSum; 1362 bool HasDefaultCase = false; 1363 const SwitchCase *Case = S->getSwitchCaseList(); 1364 for (; Case; Case = Case->getNextSwitchCase()) { 1365 HasDefaultCase = HasDefaultCase || isa<DefaultStmt>(Case); 1366 CaseCountSum = 1367 addCounters(CaseCountSum, getRegionCounter(Case), /*Simplify=*/false); 1368 createSwitchCaseRegion( 1369 Case, getRegionCounter(Case), 1370 subtractCounters(ParentCount, getRegionCounter(Case))); 1371 } 1372 // Simplify is skipped while building the counters above: it can get really 1373 // slow on top of switches with thousands of cases. Instead, trigger 1374 // simplification by adding zero to the last counter. 1375 CaseCountSum = addCounters(CaseCountSum, Counter::getZero()); 1376 1377 // If no explicit default case exists, create a branch region to represent 1378 // the hidden branch, which will be added later by the CodeGen. This region 1379 // will be associated with the switch statement's condition. 1380 if (!HasDefaultCase) { 1381 Counter DefaultTrue = subtractCounters(ParentCount, CaseCountSum); 1382 Counter DefaultFalse = subtractCounters(ParentCount, DefaultTrue); 1383 createBranchRegion(S->getCond(), DefaultTrue, DefaultFalse); 1384 } 1385 } 1386 1387 void VisitSwitchCase(const SwitchCase *S) { 1388 extendRegion(S); 1389 1390 SourceMappingRegion &Parent = getRegion(); 1391 1392 Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S)); 1393 // Reuse the existing region if it starts at our label. This is typical of 1394 // the first case in a switch. 1395 if (Parent.hasStartLoc() && Parent.getBeginLoc() == getStart(S)) 1396 Parent.setCounter(Count); 1397 else 1398 pushRegion(Count, getStart(S)); 1399 1400 GapRegionCounter = Count; 1401 1402 if (const auto *CS = dyn_cast<CaseStmt>(S)) { 1403 Visit(CS->getLHS()); 1404 if (const Expr *RHS = CS->getRHS()) 1405 Visit(RHS); 1406 } 1407 Visit(S->getSubStmt()); 1408 } 1409 1410 void VisitIfStmt(const IfStmt *S) { 1411 extendRegion(S); 1412 if (S->getInit()) 1413 Visit(S->getInit()); 1414 1415 // Extend into the condition before we propagate through it below - this is 1416 // needed to handle macros that generate the "if" but not the condition. 1417 if (!S->isConsteval()) 1418 extendRegion(S->getCond()); 1419 1420 Counter ParentCount = getRegion().getCounter(); 1421 Counter ThenCount = getRegionCounter(S); 1422 1423 if (!S->isConsteval()) { 1424 // Emitting a counter for the condition makes it easier to interpret the 1425 // counter for the body when looking at the coverage. 1426 propagateCounts(ParentCount, S->getCond()); 1427 1428 // The 'then' count applies to the area immediately after the condition. 1429 std::optional<SourceRange> Gap = 1430 findGapAreaBetween(S->getRParenLoc(), getStart(S->getThen())); 1431 if (Gap) 1432 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ThenCount); 1433 } 1434 1435 extendRegion(S->getThen()); 1436 Counter OutCount = propagateCounts(ThenCount, S->getThen()); 1437 1438 Counter ElseCount = subtractCounters(ParentCount, ThenCount); 1439 if (const Stmt *Else = S->getElse()) { 1440 bool ThenHasTerminateStmt = HasTerminateStmt; 1441 HasTerminateStmt = false; 1442 // The 'else' count applies to the area immediately after the 'then'. 1443 std::optional<SourceRange> Gap = 1444 findGapAreaBetween(getEnd(S->getThen()), getStart(Else)); 1445 if (Gap) 1446 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ElseCount); 1447 extendRegion(Else); 1448 OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else)); 1449 1450 if (ThenHasTerminateStmt) 1451 HasTerminateStmt = true; 1452 } else 1453 OutCount = addCounters(OutCount, ElseCount); 1454 1455 if (OutCount != ParentCount) { 1456 pushRegion(OutCount); 1457 GapRegionCounter = OutCount; 1458 } 1459 1460 if (!S->isConsteval()) { 1461 // Create Branch Region around condition. 1462 createBranchRegion(S->getCond(), ThenCount, 1463 subtractCounters(ParentCount, ThenCount)); 1464 } 1465 } 1466 1467 void VisitCXXTryStmt(const CXXTryStmt *S) { 1468 extendRegion(S); 1469 // Handle macros that generate the "try" but not the rest. 1470 extendRegion(S->getTryBlock()); 1471 1472 Counter ParentCount = getRegion().getCounter(); 1473 propagateCounts(ParentCount, S->getTryBlock()); 1474 1475 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I) 1476 Visit(S->getHandler(I)); 1477 1478 Counter ExitCount = getRegionCounter(S); 1479 pushRegion(ExitCount); 1480 } 1481 1482 void VisitCXXCatchStmt(const CXXCatchStmt *S) { 1483 propagateCounts(getRegionCounter(S), S->getHandlerBlock()); 1484 } 1485 1486 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 1487 extendRegion(E); 1488 1489 Counter ParentCount = getRegion().getCounter(); 1490 Counter TrueCount = getRegionCounter(E); 1491 1492 propagateCounts(ParentCount, E->getCond()); 1493 Counter OutCount; 1494 1495 if (!isa<BinaryConditionalOperator>(E)) { 1496 // The 'then' count applies to the area immediately after the condition. 1497 auto Gap = 1498 findGapAreaBetween(E->getQuestionLoc(), getStart(E->getTrueExpr())); 1499 if (Gap) 1500 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), TrueCount); 1501 1502 extendRegion(E->getTrueExpr()); 1503 OutCount = propagateCounts(TrueCount, E->getTrueExpr()); 1504 } 1505 1506 extendRegion(E->getFalseExpr()); 1507 OutCount = addCounters( 1508 OutCount, propagateCounts(subtractCounters(ParentCount, TrueCount), 1509 E->getFalseExpr())); 1510 1511 if (OutCount != ParentCount) { 1512 pushRegion(OutCount); 1513 GapRegionCounter = OutCount; 1514 } 1515 1516 // Create Branch Region around condition. 1517 createBranchRegion(E->getCond(), TrueCount, 1518 subtractCounters(ParentCount, TrueCount)); 1519 } 1520 1521 void VisitBinLAnd(const BinaryOperator *E) { 1522 extendRegion(E->getLHS()); 1523 propagateCounts(getRegion().getCounter(), E->getLHS()); 1524 handleFileExit(getEnd(E->getLHS())); 1525 1526 // Counter tracks the right hand side of a logical and operator. 1527 extendRegion(E->getRHS()); 1528 propagateCounts(getRegionCounter(E), E->getRHS()); 1529 1530 // Extract the RHS's Execution Counter. 1531 Counter RHSExecCnt = getRegionCounter(E); 1532 1533 // Extract the RHS's "True" Instance Counter. 1534 Counter RHSTrueCnt = getRegionCounter(E->getRHS()); 1535 1536 // Extract the Parent Region Counter. 1537 Counter ParentCnt = getRegion().getCounter(); 1538 1539 // Create Branch Region around LHS condition. 1540 createBranchRegion(E->getLHS(), RHSExecCnt, 1541 subtractCounters(ParentCnt, RHSExecCnt)); 1542 1543 // Create Branch Region around RHS condition. 1544 createBranchRegion(E->getRHS(), RHSTrueCnt, 1545 subtractCounters(RHSExecCnt, RHSTrueCnt)); 1546 } 1547 1548 // Determine whether the right side of OR operation need to be visited. 1549 bool shouldVisitRHS(const Expr *LHS) { 1550 bool LHSIsTrue = false; 1551 bool LHSIsConst = false; 1552 if (!LHS->isValueDependent()) 1553 LHSIsConst = LHS->EvaluateAsBooleanCondition( 1554 LHSIsTrue, CVM.getCodeGenModule().getContext()); 1555 return !LHSIsConst || (LHSIsConst && !LHSIsTrue); 1556 } 1557 1558 void VisitBinLOr(const BinaryOperator *E) { 1559 extendRegion(E->getLHS()); 1560 Counter OutCount = propagateCounts(getRegion().getCounter(), E->getLHS()); 1561 handleFileExit(getEnd(E->getLHS())); 1562 1563 // Counter tracks the right hand side of a logical or operator. 1564 extendRegion(E->getRHS()); 1565 propagateCounts(getRegionCounter(E), E->getRHS()); 1566 1567 // Extract the RHS's Execution Counter. 1568 Counter RHSExecCnt = getRegionCounter(E); 1569 1570 // Extract the RHS's "False" Instance Counter. 1571 Counter RHSFalseCnt = getRegionCounter(E->getRHS()); 1572 1573 if (!shouldVisitRHS(E->getLHS())) { 1574 GapRegionCounter = OutCount; 1575 } 1576 1577 // Extract the Parent Region Counter. 1578 Counter ParentCnt = getRegion().getCounter(); 1579 1580 // Create Branch Region around LHS condition. 1581 createBranchRegion(E->getLHS(), subtractCounters(ParentCnt, RHSExecCnt), 1582 RHSExecCnt); 1583 1584 // Create Branch Region around RHS condition. 1585 createBranchRegion(E->getRHS(), subtractCounters(RHSExecCnt, RHSFalseCnt), 1586 RHSFalseCnt); 1587 } 1588 1589 void VisitLambdaExpr(const LambdaExpr *LE) { 1590 // Lambdas are treated as their own functions for now, so we shouldn't 1591 // propagate counts into them. 1592 } 1593 1594 void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) { 1595 // Just visit syntatic expression as this is what users actually write. 1596 VisitStmt(POE->getSyntacticForm()); 1597 } 1598 1599 void VisitOpaqueValueExpr(const OpaqueValueExpr* OVE) { 1600 Visit(OVE->getSourceExpr()); 1601 } 1602 }; 1603 1604 } // end anonymous namespace 1605 1606 static void dump(llvm::raw_ostream &OS, StringRef FunctionName, 1607 ArrayRef<CounterExpression> Expressions, 1608 ArrayRef<CounterMappingRegion> Regions) { 1609 OS << FunctionName << ":\n"; 1610 CounterMappingContext Ctx(Expressions); 1611 for (const auto &R : Regions) { 1612 OS.indent(2); 1613 switch (R.Kind) { 1614 case CounterMappingRegion::CodeRegion: 1615 break; 1616 case CounterMappingRegion::ExpansionRegion: 1617 OS << "Expansion,"; 1618 break; 1619 case CounterMappingRegion::SkippedRegion: 1620 OS << "Skipped,"; 1621 break; 1622 case CounterMappingRegion::GapRegion: 1623 OS << "Gap,"; 1624 break; 1625 case CounterMappingRegion::BranchRegion: 1626 case CounterMappingRegion::MCDCBranchRegion: 1627 OS << "Branch,"; 1628 break; 1629 case CounterMappingRegion::MCDCDecisionRegion: 1630 OS << "Decision,"; 1631 break; 1632 } 1633 1634 OS << "File " << R.FileID << ", " << R.LineStart << ":" << R.ColumnStart 1635 << " -> " << R.LineEnd << ":" << R.ColumnEnd << " = "; 1636 Ctx.dump(R.Count, OS); 1637 1638 if (R.Kind == CounterMappingRegion::BranchRegion) { 1639 OS << ", "; 1640 Ctx.dump(R.FalseCount, OS); 1641 } 1642 1643 if (R.Kind == CounterMappingRegion::ExpansionRegion) 1644 OS << " (Expanded file = " << R.ExpandedFileID << ")"; 1645 OS << "\n"; 1646 } 1647 } 1648 1649 CoverageMappingModuleGen::CoverageMappingModuleGen( 1650 CodeGenModule &CGM, CoverageSourceInfo &SourceInfo) 1651 : CGM(CGM), SourceInfo(SourceInfo) {} 1652 1653 std::string CoverageMappingModuleGen::getCurrentDirname() { 1654 if (!CGM.getCodeGenOpts().CoverageCompilationDir.empty()) 1655 return CGM.getCodeGenOpts().CoverageCompilationDir; 1656 1657 SmallString<256> CWD; 1658 llvm::sys::fs::current_path(CWD); 1659 return CWD.str().str(); 1660 } 1661 1662 std::string CoverageMappingModuleGen::normalizeFilename(StringRef Filename) { 1663 llvm::SmallString<256> Path(Filename); 1664 llvm::sys::path::remove_dots(Path, /*remove_dot_dot=*/true); 1665 1666 /// Traverse coverage prefix map in reverse order because prefix replacements 1667 /// are applied in reverse order starting from the last one when multiple 1668 /// prefix replacement options are provided. 1669 for (const auto &[From, To] : 1670 llvm::reverse(CGM.getCodeGenOpts().CoveragePrefixMap)) { 1671 if (llvm::sys::path::replace_path_prefix(Path, From, To)) 1672 break; 1673 } 1674 return Path.str().str(); 1675 } 1676 1677 static std::string getInstrProfSection(const CodeGenModule &CGM, 1678 llvm::InstrProfSectKind SK) { 1679 return llvm::getInstrProfSectionName( 1680 SK, CGM.getContext().getTargetInfo().getTriple().getObjectFormat()); 1681 } 1682 1683 void CoverageMappingModuleGen::emitFunctionMappingRecord( 1684 const FunctionInfo &Info, uint64_t FilenamesRef) { 1685 llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 1686 1687 // Assign a name to the function record. This is used to merge duplicates. 1688 std::string FuncRecordName = "__covrec_" + llvm::utohexstr(Info.NameHash); 1689 1690 // A dummy description for a function included-but-not-used in a TU can be 1691 // replaced by full description provided by a different TU. The two kinds of 1692 // descriptions play distinct roles: therefore, assign them different names 1693 // to prevent `linkonce_odr` merging. 1694 if (Info.IsUsed) 1695 FuncRecordName += "u"; 1696 1697 // Create the function record type. 1698 const uint64_t NameHash = Info.NameHash; 1699 const uint64_t FuncHash = Info.FuncHash; 1700 const std::string &CoverageMapping = Info.CoverageMapping; 1701 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType, 1702 llvm::Type *FunctionRecordTypes[] = { 1703 #include "llvm/ProfileData/InstrProfData.inc" 1704 }; 1705 auto *FunctionRecordTy = 1706 llvm::StructType::get(Ctx, ArrayRef(FunctionRecordTypes), 1707 /*isPacked=*/true); 1708 1709 // Create the function record constant. 1710 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init, 1711 llvm::Constant *FunctionRecordVals[] = { 1712 #include "llvm/ProfileData/InstrProfData.inc" 1713 }; 1714 auto *FuncRecordConstant = 1715 llvm::ConstantStruct::get(FunctionRecordTy, ArrayRef(FunctionRecordVals)); 1716 1717 // Create the function record global. 1718 auto *FuncRecord = new llvm::GlobalVariable( 1719 CGM.getModule(), FunctionRecordTy, /*isConstant=*/true, 1720 llvm::GlobalValue::LinkOnceODRLinkage, FuncRecordConstant, 1721 FuncRecordName); 1722 FuncRecord->setVisibility(llvm::GlobalValue::HiddenVisibility); 1723 FuncRecord->setSection(getInstrProfSection(CGM, llvm::IPSK_covfun)); 1724 FuncRecord->setAlignment(llvm::Align(8)); 1725 if (CGM.supportsCOMDAT()) 1726 FuncRecord->setComdat(CGM.getModule().getOrInsertComdat(FuncRecordName)); 1727 1728 // Make sure the data doesn't get deleted. 1729 CGM.addUsedGlobal(FuncRecord); 1730 } 1731 1732 void CoverageMappingModuleGen::addFunctionMappingRecord( 1733 llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash, 1734 const std::string &CoverageMapping, bool IsUsed) { 1735 const uint64_t NameHash = llvm::IndexedInstrProf::ComputeHash(NameValue); 1736 FunctionRecords.push_back({NameHash, FuncHash, CoverageMapping, IsUsed}); 1737 1738 if (!IsUsed) 1739 FunctionNames.push_back(NamePtr); 1740 1741 if (CGM.getCodeGenOpts().DumpCoverageMapping) { 1742 // Dump the coverage mapping data for this function by decoding the 1743 // encoded data. This allows us to dump the mapping regions which were 1744 // also processed by the CoverageMappingWriter which performs 1745 // additional minimization operations such as reducing the number of 1746 // expressions. 1747 llvm::SmallVector<std::string, 16> FilenameStrs; 1748 std::vector<StringRef> Filenames; 1749 std::vector<CounterExpression> Expressions; 1750 std::vector<CounterMappingRegion> Regions; 1751 FilenameStrs.resize(FileEntries.size() + 1); 1752 FilenameStrs[0] = normalizeFilename(getCurrentDirname()); 1753 for (const auto &Entry : FileEntries) { 1754 auto I = Entry.second; 1755 FilenameStrs[I] = normalizeFilename(Entry.first.getName()); 1756 } 1757 ArrayRef<std::string> FilenameRefs = llvm::ArrayRef(FilenameStrs); 1758 RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames, 1759 Expressions, Regions); 1760 if (Reader.read()) 1761 return; 1762 dump(llvm::outs(), NameValue, Expressions, Regions); 1763 } 1764 } 1765 1766 void CoverageMappingModuleGen::emit() { 1767 if (FunctionRecords.empty()) 1768 return; 1769 llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 1770 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); 1771 1772 // Create the filenames and merge them with coverage mappings 1773 llvm::SmallVector<std::string, 16> FilenameStrs; 1774 FilenameStrs.resize(FileEntries.size() + 1); 1775 // The first filename is the current working directory. 1776 FilenameStrs[0] = normalizeFilename(getCurrentDirname()); 1777 for (const auto &Entry : FileEntries) { 1778 auto I = Entry.second; 1779 FilenameStrs[I] = normalizeFilename(Entry.first.getName()); 1780 } 1781 1782 std::string Filenames; 1783 { 1784 llvm::raw_string_ostream OS(Filenames); 1785 CoverageFilenamesSectionWriter(FilenameStrs).write(OS); 1786 } 1787 auto *FilenamesVal = 1788 llvm::ConstantDataArray::getString(Ctx, Filenames, false); 1789 const int64_t FilenamesRef = llvm::IndexedInstrProf::ComputeHash(Filenames); 1790 1791 // Emit the function records. 1792 for (const FunctionInfo &Info : FunctionRecords) 1793 emitFunctionMappingRecord(Info, FilenamesRef); 1794 1795 const unsigned NRecords = 0; 1796 const size_t FilenamesSize = Filenames.size(); 1797 const unsigned CoverageMappingSize = 0; 1798 llvm::Type *CovDataHeaderTypes[] = { 1799 #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType, 1800 #include "llvm/ProfileData/InstrProfData.inc" 1801 }; 1802 auto CovDataHeaderTy = 1803 llvm::StructType::get(Ctx, ArrayRef(CovDataHeaderTypes)); 1804 llvm::Constant *CovDataHeaderVals[] = { 1805 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init, 1806 #include "llvm/ProfileData/InstrProfData.inc" 1807 }; 1808 auto CovDataHeaderVal = 1809 llvm::ConstantStruct::get(CovDataHeaderTy, ArrayRef(CovDataHeaderVals)); 1810 1811 // Create the coverage data record 1812 llvm::Type *CovDataTypes[] = {CovDataHeaderTy, FilenamesVal->getType()}; 1813 auto CovDataTy = llvm::StructType::get(Ctx, ArrayRef(CovDataTypes)); 1814 llvm::Constant *TUDataVals[] = {CovDataHeaderVal, FilenamesVal}; 1815 auto CovDataVal = llvm::ConstantStruct::get(CovDataTy, ArrayRef(TUDataVals)); 1816 auto CovData = new llvm::GlobalVariable( 1817 CGM.getModule(), CovDataTy, true, llvm::GlobalValue::PrivateLinkage, 1818 CovDataVal, llvm::getCoverageMappingVarName()); 1819 1820 CovData->setSection(getInstrProfSection(CGM, llvm::IPSK_covmap)); 1821 CovData->setAlignment(llvm::Align(8)); 1822 1823 // Make sure the data doesn't get deleted. 1824 CGM.addUsedGlobal(CovData); 1825 // Create the deferred function records array 1826 if (!FunctionNames.empty()) { 1827 auto NamesArrTy = llvm::ArrayType::get(llvm::PointerType::getUnqual(Ctx), 1828 FunctionNames.size()); 1829 auto NamesArrVal = llvm::ConstantArray::get(NamesArrTy, FunctionNames); 1830 // This variable will *NOT* be emitted to the object file. It is used 1831 // to pass the list of names referenced to codegen. 1832 new llvm::GlobalVariable(CGM.getModule(), NamesArrTy, true, 1833 llvm::GlobalValue::InternalLinkage, NamesArrVal, 1834 llvm::getCoverageUnusedNamesVarName()); 1835 } 1836 } 1837 1838 unsigned CoverageMappingModuleGen::getFileID(FileEntryRef File) { 1839 auto It = FileEntries.find(File); 1840 if (It != FileEntries.end()) 1841 return It->second; 1842 unsigned FileID = FileEntries.size() + 1; 1843 FileEntries.insert(std::make_pair(File, FileID)); 1844 return FileID; 1845 } 1846 1847 void CoverageMappingGen::emitCounterMapping(const Decl *D, 1848 llvm::raw_ostream &OS) { 1849 assert(CounterMap); 1850 CounterCoverageMappingBuilder Walker(CVM, *CounterMap, SM, LangOpts); 1851 Walker.VisitDecl(D); 1852 Walker.write(OS); 1853 } 1854 1855 void CoverageMappingGen::emitEmptyMapping(const Decl *D, 1856 llvm::raw_ostream &OS) { 1857 EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts); 1858 Walker.VisitDecl(D); 1859 Walker.write(OS); 1860 } 1861