diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 81307d7b025d9..72b66db271f1b 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -900,6 +900,7 @@ class InstantiationGroup { class CoverageData { friend class CoverageMapping; +protected: std::string Filename; std::vector Segments; std::vector Expansions; @@ -914,6 +915,8 @@ class CoverageData { CoverageData(bool Single, StringRef Filename) : Filename(Filename), SingleByteCoverage(Single) {} + CoverageData(CoverageData &&RHS) = default; + /// Get the name of the file this data covers. StringRef getFilename() const { return Filename; } diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 6d6678e9e4afe..e6a789c16cdf7 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -1368,6 +1368,37 @@ class SegmentBuilder { } }; +struct MergeableCoverageData : public CoverageData { + std::vector CodeRegions; + + MergeableCoverageData(bool Single, StringRef Filename) + : CoverageData(Single, Filename) {} + + void addFunctionRegions( + const FunctionRecord &Function, + std::function shouldProcess, + std::function shouldExpand) { + for (const auto &CR : Function.CountedRegions) + if (shouldProcess(CR)) { + CodeRegions.push_back(CR); + if (shouldExpand(CR)) + Expansions.emplace_back(CR, Function); + } + // Capture branch regions specific to the function (excluding expansions). + for (const auto &CR : Function.CountedBranchRegions) + if (shouldProcess(CR)) + BranchRegions.push_back(CR); + // Capture MCDC records specific to the function. + for (const auto &MR : Function.MCDCRecords) + if (shouldProcess(MR.getDecisionRegion())) + MCDCRecords.push_back(MR); + } + + CoverageData buildSegments() { + Segments = SegmentBuilder::buildSegments(CodeRegions); + return CoverageData(std::move(*this)); + } +}; } // end anonymous namespace std::vector CoverageMapping::getUniqueSourceFiles() const { @@ -1419,8 +1450,7 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) { CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { assert(SingleByteCoverage); - CoverageData FileCoverage(*SingleByteCoverage, Filename); - std::vector Regions; + MergeableCoverageData FileCoverage(*SingleByteCoverage, Filename); // Look up the function records in the given file. Due to hash collisions on // the filename, we may get back some records that are not in the file. @@ -1430,26 +1460,14 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { const FunctionRecord &Function = Functions[RecordIndex]; auto MainFileID = findMainViewFileID(Filename, Function); auto FileIDs = gatherFileIDs(Filename, Function); - for (const auto &CR : Function.CountedRegions) - if (FileIDs.test(CR.FileID)) { - Regions.push_back(CR); - if (MainFileID && isExpansion(CR, *MainFileID)) - FileCoverage.Expansions.emplace_back(CR, Function); - } - // Capture branch regions specific to the function (excluding expansions). - for (const auto &CR : Function.CountedBranchRegions) - if (FileIDs.test(CR.FileID)) - FileCoverage.BranchRegions.push_back(CR); - // Capture MCDC records specific to the function. - for (const auto &MR : Function.MCDCRecords) - if (FileIDs.test(MR.getDecisionRegion().FileID)) - FileCoverage.MCDCRecords.push_back(MR); + FileCoverage.addFunctionRegions( + Function, [&](auto &CR) { return FileIDs.test(CR.FileID); }, + [&](auto &CR) { return (MainFileID && isExpansion(CR, *MainFileID)); }); } LLVM_DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n"); - FileCoverage.Segments = SegmentBuilder::buildSegments(Regions); - return FileCoverage; + return FileCoverage.buildSegments(); } std::vector @@ -1484,30 +1502,16 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { return CoverageData(); assert(SingleByteCoverage); - CoverageData FunctionCoverage(*SingleByteCoverage, - Function.Filenames[*MainFileID]); - std::vector Regions; - for (const auto &CR : Function.CountedRegions) - if (CR.FileID == *MainFileID) { - Regions.push_back(CR); - if (isExpansion(CR, *MainFileID)) - FunctionCoverage.Expansions.emplace_back(CR, Function); - } - // Capture branch regions specific to the function (excluding expansions). - for (const auto &CR : Function.CountedBranchRegions) - if (CR.FileID == *MainFileID) - FunctionCoverage.BranchRegions.push_back(CR); - - // Capture MCDC records specific to the function. - for (const auto &MR : Function.MCDCRecords) - if (MR.getDecisionRegion().FileID == *MainFileID) - FunctionCoverage.MCDCRecords.push_back(MR); + MergeableCoverageData FunctionCoverage(*SingleByteCoverage, + Function.Filenames[*MainFileID]); + FunctionCoverage.addFunctionRegions( + Function, [&](auto &CR) { return (CR.FileID == *MainFileID); }, + [&](auto &CR) { return isExpansion(CR, *MainFileID); }); LLVM_DEBUG(dbgs() << "Emitting segments for function: " << Function.Name << "\n"); - FunctionCoverage.Segments = SegmentBuilder::buildSegments(Regions); - return FunctionCoverage; + return FunctionCoverage.buildSegments(); } CoverageData CoverageMapping::getCoverageForExpansion(