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.getFileEntryForID(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 bool Defaulted = false; 1036 if (auto *Method = dyn_cast<CXXMethodDecl>(D)) 1037 Defaulted = Method->isDefaulted(); 1038 1039 propagateCounts(getRegionCounter(Body), Body, 1040 /*VisitChildren=*/!Defaulted); 1041 assert(RegionStack.empty() && "Regions entered but never exited"); 1042 } 1043 1044 void VisitReturnStmt(const ReturnStmt *S) { 1045 extendRegion(S); 1046 if (S->getRetValue()) 1047 Visit(S->getRetValue()); 1048 terminateRegion(S); 1049 } 1050 1051 void VisitCoroutineBodyStmt(const CoroutineBodyStmt *S) { 1052 extendRegion(S); 1053 Visit(S->getBody()); 1054 } 1055 1056 void VisitCoreturnStmt(const CoreturnStmt *S) { 1057 extendRegion(S); 1058 if (S->getOperand()) 1059 Visit(S->getOperand()); 1060 terminateRegion(S); 1061 } 1062 1063 void VisitCXXThrowExpr(const CXXThrowExpr *E) { 1064 extendRegion(E); 1065 if (E->getSubExpr()) 1066 Visit(E->getSubExpr()); 1067 terminateRegion(E); 1068 } 1069 1070 void VisitGotoStmt(const GotoStmt *S) { terminateRegion(S); } 1071 1072 void VisitLabelStmt(const LabelStmt *S) { 1073 Counter LabelCount = getRegionCounter(S); 1074 SourceLocation Start = getStart(S); 1075 // We can't extendRegion here or we risk overlapping with our new region. 1076 handleFileExit(Start); 1077 pushRegion(LabelCount, Start); 1078 Visit(S->getSubStmt()); 1079 } 1080 1081 void VisitBreakStmt(const BreakStmt *S) { 1082 assert(!BreakContinueStack.empty() && "break not in a loop or switch!"); 1083 BreakContinueStack.back().BreakCount = addCounters( 1084 BreakContinueStack.back().BreakCount, getRegion().getCounter()); 1085 // FIXME: a break in a switch should terminate regions for all preceding 1086 // case statements, not just the most recent one. 1087 terminateRegion(S); 1088 } 1089 1090 void VisitContinueStmt(const ContinueStmt *S) { 1091 assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); 1092 BreakContinueStack.back().ContinueCount = addCounters( 1093 BreakContinueStack.back().ContinueCount, getRegion().getCounter()); 1094 terminateRegion(S); 1095 } 1096 1097 void VisitCallExpr(const CallExpr *E) { 1098 VisitStmt(E); 1099 1100 // Terminate the region when we hit a noreturn function. 1101 // (This is helpful dealing with switch statements.) 1102 QualType CalleeType = E->getCallee()->getType(); 1103 if (getFunctionExtInfo(*CalleeType).getNoReturn()) 1104 terminateRegion(E); 1105 } 1106 1107 void VisitWhileStmt(const WhileStmt *S) { 1108 extendRegion(S); 1109 1110 Counter ParentCount = getRegion().getCounter(); 1111 Counter BodyCount = getRegionCounter(S); 1112 1113 // Handle the body first so that we can get the backedge count. 1114 BreakContinueStack.push_back(BreakContinue()); 1115 extendRegion(S->getBody()); 1116 Counter BackedgeCount = propagateCounts(BodyCount, S->getBody()); 1117 BreakContinue BC = BreakContinueStack.pop_back_val(); 1118 1119 bool BodyHasTerminateStmt = HasTerminateStmt; 1120 HasTerminateStmt = false; 1121 1122 // Go back to handle the condition. 1123 Counter CondCount = 1124 addCounters(ParentCount, BackedgeCount, BC.ContinueCount); 1125 propagateCounts(CondCount, S->getCond()); 1126 adjustForOutOfOrderTraversal(getEnd(S)); 1127 1128 // The body count applies to the area immediately after the increment. 1129 auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody())); 1130 if (Gap) 1131 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); 1132 1133 Counter OutCount = 1134 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount)); 1135 if (OutCount != ParentCount) { 1136 pushRegion(OutCount); 1137 GapRegionCounter = OutCount; 1138 if (BodyHasTerminateStmt) 1139 HasTerminateStmt = true; 1140 } 1141 1142 // Create Branch Region around condition. 1143 createBranchRegion(S->getCond(), BodyCount, 1144 subtractCounters(CondCount, BodyCount)); 1145 } 1146 1147 void VisitDoStmt(const DoStmt *S) { 1148 extendRegion(S); 1149 1150 Counter ParentCount = getRegion().getCounter(); 1151 Counter BodyCount = getRegionCounter(S); 1152 1153 BreakContinueStack.push_back(BreakContinue()); 1154 extendRegion(S->getBody()); 1155 Counter BackedgeCount = 1156 propagateCounts(addCounters(ParentCount, BodyCount), S->getBody()); 1157 BreakContinue BC = BreakContinueStack.pop_back_val(); 1158 1159 bool BodyHasTerminateStmt = HasTerminateStmt; 1160 HasTerminateStmt = false; 1161 1162 Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount); 1163 propagateCounts(CondCount, S->getCond()); 1164 1165 Counter OutCount = 1166 addCounters(BC.BreakCount, subtractCounters(CondCount, BodyCount)); 1167 if (OutCount != ParentCount) { 1168 pushRegion(OutCount); 1169 GapRegionCounter = OutCount; 1170 } 1171 1172 // Create Branch Region around condition. 1173 createBranchRegion(S->getCond(), BodyCount, 1174 subtractCounters(CondCount, BodyCount)); 1175 1176 if (BodyHasTerminateStmt) 1177 HasTerminateStmt = true; 1178 } 1179 1180 void VisitForStmt(const ForStmt *S) { 1181 extendRegion(S); 1182 if (S->getInit()) 1183 Visit(S->getInit()); 1184 1185 Counter ParentCount = getRegion().getCounter(); 1186 Counter BodyCount = getRegionCounter(S); 1187 1188 // The loop increment may contain a break or continue. 1189 if (S->getInc()) 1190 BreakContinueStack.emplace_back(); 1191 1192 // Handle the body first so that we can get the backedge count. 1193 BreakContinueStack.emplace_back(); 1194 extendRegion(S->getBody()); 1195 Counter BackedgeCount = propagateCounts(BodyCount, S->getBody()); 1196 BreakContinue BodyBC = BreakContinueStack.pop_back_val(); 1197 1198 bool BodyHasTerminateStmt = HasTerminateStmt; 1199 HasTerminateStmt = false; 1200 1201 // The increment is essentially part of the body but it needs to include 1202 // the count for all the continue statements. 1203 BreakContinue IncrementBC; 1204 if (const Stmt *Inc = S->getInc()) { 1205 propagateCounts(addCounters(BackedgeCount, BodyBC.ContinueCount), Inc); 1206 IncrementBC = BreakContinueStack.pop_back_val(); 1207 } 1208 1209 // Go back to handle the condition. 1210 Counter CondCount = addCounters( 1211 addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount), 1212 IncrementBC.ContinueCount); 1213 if (const Expr *Cond = S->getCond()) { 1214 propagateCounts(CondCount, Cond); 1215 adjustForOutOfOrderTraversal(getEnd(S)); 1216 } 1217 1218 // The body count applies to the area immediately after the increment. 1219 auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody())); 1220 if (Gap) 1221 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); 1222 1223 Counter OutCount = addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, 1224 subtractCounters(CondCount, BodyCount)); 1225 if (OutCount != ParentCount) { 1226 pushRegion(OutCount); 1227 GapRegionCounter = OutCount; 1228 if (BodyHasTerminateStmt) 1229 HasTerminateStmt = true; 1230 } 1231 1232 // Create Branch Region around condition. 1233 createBranchRegion(S->getCond(), BodyCount, 1234 subtractCounters(CondCount, BodyCount)); 1235 } 1236 1237 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { 1238 extendRegion(S); 1239 if (S->getInit()) 1240 Visit(S->getInit()); 1241 Visit(S->getLoopVarStmt()); 1242 Visit(S->getRangeStmt()); 1243 1244 Counter ParentCount = getRegion().getCounter(); 1245 Counter BodyCount = getRegionCounter(S); 1246 1247 BreakContinueStack.push_back(BreakContinue()); 1248 extendRegion(S->getBody()); 1249 Counter BackedgeCount = propagateCounts(BodyCount, S->getBody()); 1250 BreakContinue BC = BreakContinueStack.pop_back_val(); 1251 1252 bool BodyHasTerminateStmt = HasTerminateStmt; 1253 HasTerminateStmt = false; 1254 1255 // The body count applies to the area immediately after the range. 1256 auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody())); 1257 if (Gap) 1258 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); 1259 1260 Counter LoopCount = 1261 addCounters(ParentCount, BackedgeCount, BC.ContinueCount); 1262 Counter OutCount = 1263 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount)); 1264 if (OutCount != ParentCount) { 1265 pushRegion(OutCount); 1266 GapRegionCounter = OutCount; 1267 if (BodyHasTerminateStmt) 1268 HasTerminateStmt = true; 1269 } 1270 1271 // Create Branch Region around condition. 1272 createBranchRegion(S->getCond(), BodyCount, 1273 subtractCounters(LoopCount, BodyCount)); 1274 } 1275 1276 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { 1277 extendRegion(S); 1278 Visit(S->getElement()); 1279 1280 Counter ParentCount = getRegion().getCounter(); 1281 Counter BodyCount = getRegionCounter(S); 1282 1283 BreakContinueStack.push_back(BreakContinue()); 1284 extendRegion(S->getBody()); 1285 Counter BackedgeCount = propagateCounts(BodyCount, S->getBody()); 1286 BreakContinue BC = BreakContinueStack.pop_back_val(); 1287 1288 // The body count applies to the area immediately after the collection. 1289 auto Gap = findGapAreaBetween(S->getRParenLoc(), getStart(S->getBody())); 1290 if (Gap) 1291 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); 1292 1293 Counter LoopCount = 1294 addCounters(ParentCount, BackedgeCount, BC.ContinueCount); 1295 Counter OutCount = 1296 addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount)); 1297 if (OutCount != ParentCount) { 1298 pushRegion(OutCount); 1299 GapRegionCounter = OutCount; 1300 } 1301 } 1302 1303 void VisitSwitchStmt(const SwitchStmt *S) { 1304 extendRegion(S); 1305 if (S->getInit()) 1306 Visit(S->getInit()); 1307 Visit(S->getCond()); 1308 1309 BreakContinueStack.push_back(BreakContinue()); 1310 1311 const Stmt *Body = S->getBody(); 1312 extendRegion(Body); 1313 if (const auto *CS = dyn_cast<CompoundStmt>(Body)) { 1314 if (!CS->body_empty()) { 1315 // Make a region for the body of the switch. If the body starts with 1316 // a case, that case will reuse this region; otherwise, this covers 1317 // the unreachable code at the beginning of the switch body. 1318 size_t Index = pushRegion(Counter::getZero(), getStart(CS)); 1319 getRegion().setGap(true); 1320 Visit(Body); 1321 1322 // Set the end for the body of the switch, if it isn't already set. 1323 for (size_t i = RegionStack.size(); i != Index; --i) { 1324 if (!RegionStack[i - 1].hasEndLoc()) 1325 RegionStack[i - 1].setEndLoc(getEnd(CS->body_back())); 1326 } 1327 1328 popRegions(Index); 1329 } 1330 } else 1331 propagateCounts(Counter::getZero(), Body); 1332 BreakContinue BC = BreakContinueStack.pop_back_val(); 1333 1334 if (!BreakContinueStack.empty()) 1335 BreakContinueStack.back().ContinueCount = addCounters( 1336 BreakContinueStack.back().ContinueCount, BC.ContinueCount); 1337 1338 Counter ParentCount = getRegion().getCounter(); 1339 Counter ExitCount = getRegionCounter(S); 1340 SourceLocation ExitLoc = getEnd(S); 1341 pushRegion(ExitCount); 1342 GapRegionCounter = ExitCount; 1343 1344 // Ensure that handleFileExit recognizes when the end location is located 1345 // in a different file. 1346 MostRecentLocation = getStart(S); 1347 handleFileExit(ExitLoc); 1348 1349 // Create a Branch Region around each Case. Subtract the case's 1350 // counter from the Parent counter to track the "False" branch count. 1351 Counter CaseCountSum; 1352 bool HasDefaultCase = false; 1353 const SwitchCase *Case = S->getSwitchCaseList(); 1354 for (; Case; Case = Case->getNextSwitchCase()) { 1355 HasDefaultCase = HasDefaultCase || isa<DefaultStmt>(Case); 1356 CaseCountSum = 1357 addCounters(CaseCountSum, getRegionCounter(Case), /*Simplify=*/false); 1358 createSwitchCaseRegion( 1359 Case, getRegionCounter(Case), 1360 subtractCounters(ParentCount, getRegionCounter(Case))); 1361 } 1362 // Simplify is skipped while building the counters above: it can get really 1363 // slow on top of switches with thousands of cases. Instead, trigger 1364 // simplification by adding zero to the last counter. 1365 CaseCountSum = addCounters(CaseCountSum, Counter::getZero()); 1366 1367 // If no explicit default case exists, create a branch region to represent 1368 // the hidden branch, which will be added later by the CodeGen. This region 1369 // will be associated with the switch statement's condition. 1370 if (!HasDefaultCase) { 1371 Counter DefaultTrue = subtractCounters(ParentCount, CaseCountSum); 1372 Counter DefaultFalse = subtractCounters(ParentCount, DefaultTrue); 1373 createBranchRegion(S->getCond(), DefaultTrue, DefaultFalse); 1374 } 1375 } 1376 1377 void VisitSwitchCase(const SwitchCase *S) { 1378 extendRegion(S); 1379 1380 SourceMappingRegion &Parent = getRegion(); 1381 1382 Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S)); 1383 // Reuse the existing region if it starts at our label. This is typical of 1384 // the first case in a switch. 1385 if (Parent.hasStartLoc() && Parent.getBeginLoc() == getStart(S)) 1386 Parent.setCounter(Count); 1387 else 1388 pushRegion(Count, getStart(S)); 1389 1390 GapRegionCounter = Count; 1391 1392 if (const auto *CS = dyn_cast<CaseStmt>(S)) { 1393 Visit(CS->getLHS()); 1394 if (const Expr *RHS = CS->getRHS()) 1395 Visit(RHS); 1396 } 1397 Visit(S->getSubStmt()); 1398 } 1399 1400 void VisitIfStmt(const IfStmt *S) { 1401 extendRegion(S); 1402 if (S->getInit()) 1403 Visit(S->getInit()); 1404 1405 // Extend into the condition before we propagate through it below - this is 1406 // needed to handle macros that generate the "if" but not the condition. 1407 if (!S->isConsteval()) 1408 extendRegion(S->getCond()); 1409 1410 Counter ParentCount = getRegion().getCounter(); 1411 Counter ThenCount = getRegionCounter(S); 1412 1413 if (!S->isConsteval()) { 1414 // Emitting a counter for the condition makes it easier to interpret the 1415 // counter for the body when looking at the coverage. 1416 propagateCounts(ParentCount, S->getCond()); 1417 1418 // The 'then' count applies to the area immediately after the condition. 1419 std::optional<SourceRange> Gap = 1420 findGapAreaBetween(S->getRParenLoc(), getStart(S->getThen())); 1421 if (Gap) 1422 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ThenCount); 1423 } 1424 1425 extendRegion(S->getThen()); 1426 Counter OutCount = propagateCounts(ThenCount, S->getThen()); 1427 1428 Counter ElseCount = subtractCounters(ParentCount, ThenCount); 1429 if (const Stmt *Else = S->getElse()) { 1430 bool ThenHasTerminateStmt = HasTerminateStmt; 1431 HasTerminateStmt = false; 1432 // The 'else' count applies to the area immediately after the 'then'. 1433 std::optional<SourceRange> Gap = 1434 findGapAreaBetween(getEnd(S->getThen()), getStart(Else)); 1435 if (Gap) 1436 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ElseCount); 1437 extendRegion(Else); 1438 OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else)); 1439 1440 if (ThenHasTerminateStmt) 1441 HasTerminateStmt = true; 1442 } else 1443 OutCount = addCounters(OutCount, ElseCount); 1444 1445 if (OutCount != ParentCount) { 1446 pushRegion(OutCount); 1447 GapRegionCounter = OutCount; 1448 } 1449 1450 if (!S->isConsteval()) { 1451 // Create Branch Region around condition. 1452 createBranchRegion(S->getCond(), ThenCount, 1453 subtractCounters(ParentCount, ThenCount)); 1454 } 1455 } 1456 1457 void VisitCXXTryStmt(const CXXTryStmt *S) { 1458 extendRegion(S); 1459 // Handle macros that generate the "try" but not the rest. 1460 extendRegion(S->getTryBlock()); 1461 1462 Counter ParentCount = getRegion().getCounter(); 1463 propagateCounts(ParentCount, S->getTryBlock()); 1464 1465 for (unsigned I = 0, E = S->getNumHandlers(); I < E; ++I) 1466 Visit(S->getHandler(I)); 1467 1468 Counter ExitCount = getRegionCounter(S); 1469 pushRegion(ExitCount); 1470 } 1471 1472 void VisitCXXCatchStmt(const CXXCatchStmt *S) { 1473 propagateCounts(getRegionCounter(S), S->getHandlerBlock()); 1474 } 1475 1476 void VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { 1477 extendRegion(E); 1478 1479 Counter ParentCount = getRegion().getCounter(); 1480 Counter TrueCount = getRegionCounter(E); 1481 1482 propagateCounts(ParentCount, E->getCond()); 1483 Counter OutCount; 1484 1485 if (!isa<BinaryConditionalOperator>(E)) { 1486 // The 'then' count applies to the area immediately after the condition. 1487 auto Gap = 1488 findGapAreaBetween(E->getQuestionLoc(), getStart(E->getTrueExpr())); 1489 if (Gap) 1490 fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), TrueCount); 1491 1492 extendRegion(E->getTrueExpr()); 1493 OutCount = propagateCounts(TrueCount, E->getTrueExpr()); 1494 } 1495 1496 extendRegion(E->getFalseExpr()); 1497 OutCount = addCounters( 1498 OutCount, propagateCounts(subtractCounters(ParentCount, TrueCount), 1499 E->getFalseExpr())); 1500 1501 if (OutCount != ParentCount) { 1502 pushRegion(OutCount); 1503 GapRegionCounter = OutCount; 1504 } 1505 1506 // Create Branch Region around condition. 1507 createBranchRegion(E->getCond(), TrueCount, 1508 subtractCounters(ParentCount, TrueCount)); 1509 } 1510 1511 void VisitBinLAnd(const BinaryOperator *E) { 1512 extendRegion(E->getLHS()); 1513 propagateCounts(getRegion().getCounter(), E->getLHS()); 1514 handleFileExit(getEnd(E->getLHS())); 1515 1516 // Counter tracks the right hand side of a logical and operator. 1517 extendRegion(E->getRHS()); 1518 propagateCounts(getRegionCounter(E), E->getRHS()); 1519 1520 // Extract the RHS's Execution Counter. 1521 Counter RHSExecCnt = getRegionCounter(E); 1522 1523 // Extract the RHS's "True" Instance Counter. 1524 Counter RHSTrueCnt = getRegionCounter(E->getRHS()); 1525 1526 // Extract the Parent Region Counter. 1527 Counter ParentCnt = getRegion().getCounter(); 1528 1529 // Create Branch Region around LHS condition. 1530 createBranchRegion(E->getLHS(), RHSExecCnt, 1531 subtractCounters(ParentCnt, RHSExecCnt)); 1532 1533 // Create Branch Region around RHS condition. 1534 createBranchRegion(E->getRHS(), RHSTrueCnt, 1535 subtractCounters(RHSExecCnt, RHSTrueCnt)); 1536 } 1537 1538 // Determine whether the right side of OR operation need to be visited. 1539 bool shouldVisitRHS(const Expr *LHS) { 1540 bool LHSIsTrue = false; 1541 bool LHSIsConst = false; 1542 if (!LHS->isValueDependent()) 1543 LHSIsConst = LHS->EvaluateAsBooleanCondition( 1544 LHSIsTrue, CVM.getCodeGenModule().getContext()); 1545 return !LHSIsConst || (LHSIsConst && !LHSIsTrue); 1546 } 1547 1548 void VisitBinLOr(const BinaryOperator *E) { 1549 extendRegion(E->getLHS()); 1550 Counter OutCount = propagateCounts(getRegion().getCounter(), E->getLHS()); 1551 handleFileExit(getEnd(E->getLHS())); 1552 1553 // Counter tracks the right hand side of a logical or operator. 1554 extendRegion(E->getRHS()); 1555 propagateCounts(getRegionCounter(E), E->getRHS()); 1556 1557 // Extract the RHS's Execution Counter. 1558 Counter RHSExecCnt = getRegionCounter(E); 1559 1560 // Extract the RHS's "False" Instance Counter. 1561 Counter RHSFalseCnt = getRegionCounter(E->getRHS()); 1562 1563 if (!shouldVisitRHS(E->getLHS())) { 1564 GapRegionCounter = OutCount; 1565 } 1566 1567 // Extract the Parent Region Counter. 1568 Counter ParentCnt = getRegion().getCounter(); 1569 1570 // Create Branch Region around LHS condition. 1571 createBranchRegion(E->getLHS(), subtractCounters(ParentCnt, RHSExecCnt), 1572 RHSExecCnt); 1573 1574 // Create Branch Region around RHS condition. 1575 createBranchRegion(E->getRHS(), subtractCounters(RHSExecCnt, RHSFalseCnt), 1576 RHSFalseCnt); 1577 } 1578 1579 void VisitLambdaExpr(const LambdaExpr *LE) { 1580 // Lambdas are treated as their own functions for now, so we shouldn't 1581 // propagate counts into them. 1582 } 1583 1584 void VisitPseudoObjectExpr(const PseudoObjectExpr *POE) { 1585 // Just visit syntatic expression as this is what users actually write. 1586 VisitStmt(POE->getSyntacticForm()); 1587 } 1588 1589 void VisitOpaqueValueExpr(const OpaqueValueExpr* OVE) { 1590 Visit(OVE->getSourceExpr()); 1591 } 1592 }; 1593 1594 } // end anonymous namespace 1595 1596 static void dump(llvm::raw_ostream &OS, StringRef FunctionName, 1597 ArrayRef<CounterExpression> Expressions, 1598 ArrayRef<CounterMappingRegion> Regions) { 1599 OS << FunctionName << ":\n"; 1600 CounterMappingContext Ctx(Expressions); 1601 for (const auto &R : Regions) { 1602 OS.indent(2); 1603 switch (R.Kind) { 1604 case CounterMappingRegion::CodeRegion: 1605 break; 1606 case CounterMappingRegion::ExpansionRegion: 1607 OS << "Expansion,"; 1608 break; 1609 case CounterMappingRegion::SkippedRegion: 1610 OS << "Skipped,"; 1611 break; 1612 case CounterMappingRegion::GapRegion: 1613 OS << "Gap,"; 1614 break; 1615 case CounterMappingRegion::BranchRegion: 1616 OS << "Branch,"; 1617 break; 1618 } 1619 1620 OS << "File " << R.FileID << ", " << R.LineStart << ":" << R.ColumnStart 1621 << " -> " << R.LineEnd << ":" << R.ColumnEnd << " = "; 1622 Ctx.dump(R.Count, OS); 1623 1624 if (R.Kind == CounterMappingRegion::BranchRegion) { 1625 OS << ", "; 1626 Ctx.dump(R.FalseCount, OS); 1627 } 1628 1629 if (R.Kind == CounterMappingRegion::ExpansionRegion) 1630 OS << " (Expanded file = " << R.ExpandedFileID << ")"; 1631 OS << "\n"; 1632 } 1633 } 1634 1635 CoverageMappingModuleGen::CoverageMappingModuleGen( 1636 CodeGenModule &CGM, CoverageSourceInfo &SourceInfo) 1637 : CGM(CGM), SourceInfo(SourceInfo) {} 1638 1639 std::string CoverageMappingModuleGen::getCurrentDirname() { 1640 if (!CGM.getCodeGenOpts().CoverageCompilationDir.empty()) 1641 return CGM.getCodeGenOpts().CoverageCompilationDir; 1642 1643 SmallString<256> CWD; 1644 llvm::sys::fs::current_path(CWD); 1645 return CWD.str().str(); 1646 } 1647 1648 std::string CoverageMappingModuleGen::normalizeFilename(StringRef Filename) { 1649 llvm::SmallString<256> Path(Filename); 1650 llvm::sys::path::remove_dots(Path, /*remove_dot_dot=*/true); 1651 1652 /// Traverse coverage prefix map in reverse order because prefix replacements 1653 /// are applied in reverse order starting from the last one when multiple 1654 /// prefix replacement options are provided. 1655 for (const auto &[From, To] : 1656 llvm::reverse(CGM.getCodeGenOpts().CoveragePrefixMap)) { 1657 if (llvm::sys::path::replace_path_prefix(Path, From, To)) 1658 break; 1659 } 1660 return Path.str().str(); 1661 } 1662 1663 static std::string getInstrProfSection(const CodeGenModule &CGM, 1664 llvm::InstrProfSectKind SK) { 1665 return llvm::getInstrProfSectionName( 1666 SK, CGM.getContext().getTargetInfo().getTriple().getObjectFormat()); 1667 } 1668 1669 void CoverageMappingModuleGen::emitFunctionMappingRecord( 1670 const FunctionInfo &Info, uint64_t FilenamesRef) { 1671 llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 1672 1673 // Assign a name to the function record. This is used to merge duplicates. 1674 std::string FuncRecordName = "__covrec_" + llvm::utohexstr(Info.NameHash); 1675 1676 // A dummy description for a function included-but-not-used in a TU can be 1677 // replaced by full description provided by a different TU. The two kinds of 1678 // descriptions play distinct roles: therefore, assign them different names 1679 // to prevent `linkonce_odr` merging. 1680 if (Info.IsUsed) 1681 FuncRecordName += "u"; 1682 1683 // Create the function record type. 1684 const uint64_t NameHash = Info.NameHash; 1685 const uint64_t FuncHash = Info.FuncHash; 1686 const std::string &CoverageMapping = Info.CoverageMapping; 1687 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) LLVMType, 1688 llvm::Type *FunctionRecordTypes[] = { 1689 #include "llvm/ProfileData/InstrProfData.inc" 1690 }; 1691 auto *FunctionRecordTy = 1692 llvm::StructType::get(Ctx, ArrayRef(FunctionRecordTypes), 1693 /*isPacked=*/true); 1694 1695 // Create the function record constant. 1696 #define COVMAP_FUNC_RECORD(Type, LLVMType, Name, Init) Init, 1697 llvm::Constant *FunctionRecordVals[] = { 1698 #include "llvm/ProfileData/InstrProfData.inc" 1699 }; 1700 auto *FuncRecordConstant = 1701 llvm::ConstantStruct::get(FunctionRecordTy, ArrayRef(FunctionRecordVals)); 1702 1703 // Create the function record global. 1704 auto *FuncRecord = new llvm::GlobalVariable( 1705 CGM.getModule(), FunctionRecordTy, /*isConstant=*/true, 1706 llvm::GlobalValue::LinkOnceODRLinkage, FuncRecordConstant, 1707 FuncRecordName); 1708 FuncRecord->setVisibility(llvm::GlobalValue::HiddenVisibility); 1709 FuncRecord->setSection(getInstrProfSection(CGM, llvm::IPSK_covfun)); 1710 FuncRecord->setAlignment(llvm::Align(8)); 1711 if (CGM.supportsCOMDAT()) 1712 FuncRecord->setComdat(CGM.getModule().getOrInsertComdat(FuncRecordName)); 1713 1714 // Make sure the data doesn't get deleted. 1715 CGM.addUsedGlobal(FuncRecord); 1716 } 1717 1718 void CoverageMappingModuleGen::addFunctionMappingRecord( 1719 llvm::GlobalVariable *NamePtr, StringRef NameValue, uint64_t FuncHash, 1720 const std::string &CoverageMapping, bool IsUsed) { 1721 llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 1722 const uint64_t NameHash = llvm::IndexedInstrProf::ComputeHash(NameValue); 1723 FunctionRecords.push_back({NameHash, FuncHash, CoverageMapping, IsUsed}); 1724 1725 if (!IsUsed) 1726 FunctionNames.push_back( 1727 llvm::ConstantExpr::getBitCast(NamePtr, llvm::Type::getInt8PtrTy(Ctx))); 1728 1729 if (CGM.getCodeGenOpts().DumpCoverageMapping) { 1730 // Dump the coverage mapping data for this function by decoding the 1731 // encoded data. This allows us to dump the mapping regions which were 1732 // also processed by the CoverageMappingWriter which performs 1733 // additional minimization operations such as reducing the number of 1734 // expressions. 1735 llvm::SmallVector<std::string, 16> FilenameStrs; 1736 std::vector<StringRef> Filenames; 1737 std::vector<CounterExpression> Expressions; 1738 std::vector<CounterMappingRegion> Regions; 1739 FilenameStrs.resize(FileEntries.size() + 1); 1740 FilenameStrs[0] = normalizeFilename(getCurrentDirname()); 1741 for (const auto &Entry : FileEntries) { 1742 auto I = Entry.second; 1743 FilenameStrs[I] = normalizeFilename(Entry.first->getName()); 1744 } 1745 ArrayRef<std::string> FilenameRefs = llvm::ArrayRef(FilenameStrs); 1746 RawCoverageMappingReader Reader(CoverageMapping, FilenameRefs, Filenames, 1747 Expressions, Regions); 1748 if (Reader.read()) 1749 return; 1750 dump(llvm::outs(), NameValue, Expressions, Regions); 1751 } 1752 } 1753 1754 void CoverageMappingModuleGen::emit() { 1755 if (FunctionRecords.empty()) 1756 return; 1757 llvm::LLVMContext &Ctx = CGM.getLLVMContext(); 1758 auto *Int32Ty = llvm::Type::getInt32Ty(Ctx); 1759 1760 // Create the filenames and merge them with coverage mappings 1761 llvm::SmallVector<std::string, 16> FilenameStrs; 1762 FilenameStrs.resize(FileEntries.size() + 1); 1763 // The first filename is the current working directory. 1764 FilenameStrs[0] = normalizeFilename(getCurrentDirname()); 1765 for (const auto &Entry : FileEntries) { 1766 auto I = Entry.second; 1767 FilenameStrs[I] = normalizeFilename(Entry.first->getName()); 1768 } 1769 1770 std::string Filenames; 1771 { 1772 llvm::raw_string_ostream OS(Filenames); 1773 CoverageFilenamesSectionWriter(FilenameStrs).write(OS); 1774 } 1775 auto *FilenamesVal = 1776 llvm::ConstantDataArray::getString(Ctx, Filenames, false); 1777 const int64_t FilenamesRef = llvm::IndexedInstrProf::ComputeHash(Filenames); 1778 1779 // Emit the function records. 1780 for (const FunctionInfo &Info : FunctionRecords) 1781 emitFunctionMappingRecord(Info, FilenamesRef); 1782 1783 const unsigned NRecords = 0; 1784 const size_t FilenamesSize = Filenames.size(); 1785 const unsigned CoverageMappingSize = 0; 1786 llvm::Type *CovDataHeaderTypes[] = { 1787 #define COVMAP_HEADER(Type, LLVMType, Name, Init) LLVMType, 1788 #include "llvm/ProfileData/InstrProfData.inc" 1789 }; 1790 auto CovDataHeaderTy = 1791 llvm::StructType::get(Ctx, ArrayRef(CovDataHeaderTypes)); 1792 llvm::Constant *CovDataHeaderVals[] = { 1793 #define COVMAP_HEADER(Type, LLVMType, Name, Init) Init, 1794 #include "llvm/ProfileData/InstrProfData.inc" 1795 }; 1796 auto CovDataHeaderVal = 1797 llvm::ConstantStruct::get(CovDataHeaderTy, ArrayRef(CovDataHeaderVals)); 1798 1799 // Create the coverage data record 1800 llvm::Type *CovDataTypes[] = {CovDataHeaderTy, FilenamesVal->getType()}; 1801 auto CovDataTy = llvm::StructType::get(Ctx, ArrayRef(CovDataTypes)); 1802 llvm::Constant *TUDataVals[] = {CovDataHeaderVal, FilenamesVal}; 1803 auto CovDataVal = llvm::ConstantStruct::get(CovDataTy, ArrayRef(TUDataVals)); 1804 auto CovData = new llvm::GlobalVariable( 1805 CGM.getModule(), CovDataTy, true, llvm::GlobalValue::PrivateLinkage, 1806 CovDataVal, llvm::getCoverageMappingVarName()); 1807 1808 CovData->setSection(getInstrProfSection(CGM, llvm::IPSK_covmap)); 1809 CovData->setAlignment(llvm::Align(8)); 1810 1811 // Make sure the data doesn't get deleted. 1812 CGM.addUsedGlobal(CovData); 1813 // Create the deferred function records array 1814 if (!FunctionNames.empty()) { 1815 auto NamesArrTy = llvm::ArrayType::get(llvm::Type::getInt8PtrTy(Ctx), 1816 FunctionNames.size()); 1817 auto NamesArrVal = llvm::ConstantArray::get(NamesArrTy, FunctionNames); 1818 // This variable will *NOT* be emitted to the object file. It is used 1819 // to pass the list of names referenced to codegen. 1820 new llvm::GlobalVariable(CGM.getModule(), NamesArrTy, true, 1821 llvm::GlobalValue::InternalLinkage, NamesArrVal, 1822 llvm::getCoverageUnusedNamesVarName()); 1823 } 1824 } 1825 1826 unsigned CoverageMappingModuleGen::getFileID(const FileEntry *File) { 1827 auto It = FileEntries.find(File); 1828 if (It != FileEntries.end()) 1829 return It->second; 1830 unsigned FileID = FileEntries.size() + 1; 1831 FileEntries.insert(std::make_pair(File, FileID)); 1832 return FileID; 1833 } 1834 1835 void CoverageMappingGen::emitCounterMapping(const Decl *D, 1836 llvm::raw_ostream &OS) { 1837 assert(CounterMap); 1838 CounterCoverageMappingBuilder Walker(CVM, *CounterMap, SM, LangOpts); 1839 Walker.VisitDecl(D); 1840 Walker.write(OS); 1841 } 1842 1843 void CoverageMappingGen::emitEmptyMapping(const Decl *D, 1844 llvm::raw_ostream &OS) { 1845 EmptyCoverageMappingBuilder Walker(CVM, SM, LangOpts); 1846 Walker.VisitDecl(D); 1847 Walker.write(OS); 1848 } 1849