From 178b57cbbcb2b21b7d13f90ffd75903417913438 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 2 Oct 2024 23:11:36 +0900 Subject: [PATCH 01/35] [Coverage] Move SingleByteCoverage out of CountedRegion `SingleByteCoverage` is not per-region attribute at least. At the moment, this change moves it into `FunctionRecord`. --- .../ProfileData/Coverage/CoverageMapping.h | 27 +++++++------- .../ProfileData/Coverage/CoverageMapping.cpp | 36 ++++++++++++------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index fa07b3a9e8b14..77c447efe1a7c 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -359,19 +359,15 @@ struct CountedRegion : public CounterMappingRegion { uint64_t ExecutionCount; uint64_t FalseExecutionCount; bool Folded; - bool HasSingleByteCoverage; - CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount, - bool HasSingleByteCoverage) + CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount) : CounterMappingRegion(R), ExecutionCount(ExecutionCount), - FalseExecutionCount(0), Folded(false), - HasSingleByteCoverage(HasSingleByteCoverage) {} + FalseExecutionCount(0), Folded(false) {} CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount, - uint64_t FalseExecutionCount, bool HasSingleByteCoverage) + uint64_t FalseExecutionCount) : CounterMappingRegion(R), ExecutionCount(ExecutionCount), - FalseExecutionCount(FalseExecutionCount), Folded(false), - HasSingleByteCoverage(HasSingleByteCoverage) {} + FalseExecutionCount(FalseExecutionCount), Folded(false) {} }; /// MCDC Record grouping all information together. @@ -702,9 +698,12 @@ struct FunctionRecord { std::vector MCDCRecords; /// The number of times this function was executed. uint64_t ExecutionCount = 0; + bool SingleByteCoverage; - FunctionRecord(StringRef Name, ArrayRef Filenames) - : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {} + FunctionRecord(StringRef Name, ArrayRef Filenames, + bool SingleByteCoverage) + : Name(Name), Filenames(Filenames.begin(), Filenames.end()), + SingleByteCoverage(SingleByteCoverage) {} FunctionRecord(FunctionRecord &&FR) = default; FunctionRecord &operator=(FunctionRecord &&) = default; @@ -714,11 +713,10 @@ struct FunctionRecord { } void pushRegion(CounterMappingRegion Region, uint64_t Count, - uint64_t FalseCount, bool HasSingleByteCoverage) { + uint64_t FalseCount) { if (Region.Kind == CounterMappingRegion::BranchRegion || Region.Kind == CounterMappingRegion::MCDCBranchRegion) { - CountedBranchRegions.emplace_back(Region, Count, FalseCount, - HasSingleByteCoverage); + CountedBranchRegions.emplace_back(Region, Count, FalseCount); // If both counters are hard-coded to zero, then this region represents a // constant-folded branch. if (Region.Count.isZero() && Region.FalseCount.isZero()) @@ -727,8 +725,7 @@ struct FunctionRecord { } if (CountedRegions.empty()) ExecutionCount = Count; - CountedRegions.emplace_back(Region, Count, FalseCount, - HasSingleByteCoverage); + CountedRegions.emplace_back(Region, Count, FalseCount); } }; diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 18643c6b44485..a02136d5b0386 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -808,6 +808,7 @@ Error CoverageMapping::loadFunctionRecord( else OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]); + bool SingleByteCoverage = ProfileReader.hasSingleByteCoverage(); CounterMappingContext Ctx(Record.Expressions); std::vector Counts; @@ -855,7 +856,7 @@ Error CoverageMapping::loadFunctionRecord( return Error::success(); MCDCDecisionRecorder MCDCDecisions; - FunctionRecord Function(OrigFuncName, Record.Filenames); + FunctionRecord Function(OrigFuncName, Record.Filenames, SingleByteCoverage); for (const auto &Region : Record.MappingRegions) { // MCDCDecisionRegion should be handled first since it overlaps with // others inside. @@ -873,8 +874,7 @@ Error CoverageMapping::loadFunctionRecord( consumeError(std::move(E)); return Error::success(); } - Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount, - ProfileReader.hasSingleByteCoverage()); + Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount); // Record ExpansionRegion. if (Region.Kind == CounterMappingRegion::ExpansionRegion) { @@ -1270,7 +1270,8 @@ class SegmentBuilder { /// Combine counts of regions which cover the same area. static ArrayRef - combineRegions(MutableArrayRef Regions) { + combineRegions(MutableArrayRef Regions, + bool SingleByteCoverage) { if (Regions.empty()) return Regions; auto Active = Regions.begin(); @@ -1297,9 +1298,7 @@ class SegmentBuilder { // We add counts of the regions of the same kind as the active region // to handle the both situations. if (I->Kind == Active->Kind) { - assert(I->HasSingleByteCoverage == Active->HasSingleByteCoverage && - "Regions are generated in different coverage modes"); - if (I->HasSingleByteCoverage) + if (SingleByteCoverage) Active->ExecutionCount = Active->ExecutionCount || I->ExecutionCount; else Active->ExecutionCount += I->ExecutionCount; @@ -1311,12 +1310,14 @@ class SegmentBuilder { public: /// Build a sorted list of CoverageSegments from a list of Regions. static std::vector - buildSegments(MutableArrayRef Regions) { + buildSegments(MutableArrayRef Regions, + bool SingleByteCoverage) { std::vector Segments; SegmentBuilder Builder(Segments); sortNestedRegions(Regions); - ArrayRef CombinedRegions = combineRegions(Regions); + ArrayRef CombinedRegions = + combineRegions(Regions, SingleByteCoverage); LLVM_DEBUG({ dbgs() << "Combined regions:\n"; @@ -1403,10 +1404,14 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { // the filename, we may get back some records that are not in the file. ArrayRef RecordIndices = getImpreciseRecordIndicesForFilename(Filename); + std::optional SingleByteCoverage; for (unsigned RecordIndex : RecordIndices) { const FunctionRecord &Function = Functions[RecordIndex]; auto MainFileID = findMainViewFileID(Filename, Function); auto FileIDs = gatherFileIDs(Filename, Function); + assert(!SingleByteCoverage || + *SingleByteCoverage == Function.SingleByteCoverage); + SingleByteCoverage = Function.SingleByteCoverage; for (const auto &CR : Function.CountedRegions) if (FileIDs.test(CR.FileID)) { Regions.push_back(CR); @@ -1424,7 +1429,8 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { } LLVM_DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n"); - FileCoverage.Segments = SegmentBuilder::buildSegments(Regions); + FileCoverage.Segments = + SegmentBuilder::buildSegments(Regions, *SingleByteCoverage); return FileCoverage; } @@ -1480,7 +1486,8 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { LLVM_DEBUG(dbgs() << "Emitting segments for function: " << Function.Name << "\n"); - FunctionCoverage.Segments = SegmentBuilder::buildSegments(Regions); + FunctionCoverage.Segments = + SegmentBuilder::buildSegments(Regions, Function.SingleByteCoverage); return FunctionCoverage; } @@ -1490,8 +1497,12 @@ CoverageData CoverageMapping::getCoverageForExpansion( CoverageData ExpansionCoverage( Expansion.Function.Filenames[Expansion.FileID]); std::vector Regions; + std::optional SingleByteCoverage; for (const auto &CR : Expansion.Function.CountedRegions) if (CR.FileID == Expansion.FileID) { + assert(!SingleByteCoverage || + *SingleByteCoverage == Expansion.Function.SingleByteCoverage); + SingleByteCoverage = Expansion.Function.SingleByteCoverage; Regions.push_back(CR); if (isExpansion(CR, Expansion.FileID)) ExpansionCoverage.Expansions.emplace_back(CR, Expansion.Function); @@ -1503,7 +1514,8 @@ CoverageData CoverageMapping::getCoverageForExpansion( LLVM_DEBUG(dbgs() << "Emitting segments for expansion of file " << Expansion.FileID << "\n"); - ExpansionCoverage.Segments = SegmentBuilder::buildSegments(Regions); + ExpansionCoverage.Segments = + SegmentBuilder::buildSegments(Regions, *SingleByteCoverage); return ExpansionCoverage; } From aacb50ddf87d96b4a0644c7ef5d0a86dc94f069b Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 2 Oct 2024 23:25:52 +0900 Subject: [PATCH 02/35] [Coverage] Make SingleByteCoverage work consistent to merging - Round `Counts` as 1/0 - Confirm both `ExecutionCount` and `AltExecutionCount` are in range. --- compiler-rt/test/profile/instrprof-block-coverage.c | 2 +- compiler-rt/test/profile/instrprof-entry-coverage.c | 2 +- llvm/include/llvm/ProfileData/InstrProf.h | 5 ++++- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 3 +++ llvm/lib/ProfileData/InstrProf.cpp | 2 +- llvm/lib/ProfileData/InstrProfReader.cpp | 1 + 6 files changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler-rt/test/profile/instrprof-block-coverage.c b/compiler-rt/test/profile/instrprof-block-coverage.c index 829d5af8dc3f9..8d924e1cac64d 100644 --- a/compiler-rt/test/profile/instrprof-block-coverage.c +++ b/compiler-rt/test/profile/instrprof-block-coverage.c @@ -49,4 +49,4 @@ int main(int argc, char *argv[]) { // CHECK-ERROR-NOT: warning: {{.*}}: Found inconsistent block coverage -// COUNTS: Maximum function count: 4 +// COUNTS: Maximum function count: 1 diff --git a/compiler-rt/test/profile/instrprof-entry-coverage.c b/compiler-rt/test/profile/instrprof-entry-coverage.c index 1c6816ba01964..b93a4e0c43ccd 100644 --- a/compiler-rt/test/profile/instrprof-entry-coverage.c +++ b/compiler-rt/test/profile/instrprof-entry-coverage.c @@ -36,4 +36,4 @@ int main(int argc, char *argv[]) { // CHECK-DAG: foo // CHECK-DAG: bar -// COUNTS: Maximum function count: 2 +// COUNTS: Maximum function count: 1 diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index b0b2258735e2a..df9e76966bf42 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -830,6 +830,7 @@ struct InstrProfValueSiteRecord { /// Profiling information for a single function. struct InstrProfRecord { std::vector Counts; + bool SingleByteCoverage = false; std::vector BitmapBytes; InstrProfRecord() = default; @@ -839,13 +840,15 @@ struct InstrProfRecord { : Counts(std::move(Counts)), BitmapBytes(std::move(BitmapBytes)) {} InstrProfRecord(InstrProfRecord &&) = default; InstrProfRecord(const InstrProfRecord &RHS) - : Counts(RHS.Counts), BitmapBytes(RHS.BitmapBytes), + : Counts(RHS.Counts), SingleByteCoverage(RHS.SingleByteCoverage), + BitmapBytes(RHS.BitmapBytes), ValueData(RHS.ValueData ? std::make_unique(*RHS.ValueData) : nullptr) {} InstrProfRecord &operator=(InstrProfRecord &&) = default; InstrProfRecord &operator=(const InstrProfRecord &RHS) { Counts = RHS.Counts; + SingleByteCoverage = RHS.SingleByteCoverage; BitmapBytes = RHS.BitmapBytes; if (!RHS.ValueData) { ValueData = nullptr; diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index a02136d5b0386..bc765c5938171 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -874,6 +874,9 @@ Error CoverageMapping::loadFunctionRecord( consumeError(std::move(E)); return Error::success(); } + assert(!SingleByteCoverage || + (0 <= *ExecutionCount && *ExecutionCount <= 1 && + 0 <= *AltExecutionCount && *AltExecutionCount <= 1)); Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount); // Record ExpansionRegion. diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index b9937c9429b77..0f6677b4d3571 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -952,7 +952,7 @@ void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight, Value = getInstrMaxCountValue(); Overflowed = true; } - Counts[I] = Value; + Counts[I] = (SingleByteCoverage && Value != 0 ? 1 : Value); if (Overflowed) Warn(instrprof_error::counter_overflow); } diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index b90617c74f6d1..a07d7f573275b 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -743,6 +743,7 @@ Error RawInstrProfReader::readRawCounts( Record.Counts.clear(); Record.Counts.reserve(NumCounters); + Record.SingleByteCoverage = hasSingleByteCoverage(); for (uint32_t I = 0; I < NumCounters; I++) { const char *Ptr = CountersStart + CounterBaseOffset + I * getCounterTypeSize(); From b9bbc7cac3076594cd326ffa7f2d4fc4a92fabb9 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 5 Oct 2024 10:43:26 +0900 Subject: [PATCH 03/35] Rework. (Also reverts "[Coverage] Move SingleByteCoverage out of CountedRegion") --- .../test/profile/instrprof-block-coverage.c | 2 +- .../test/profile/instrprof-entry-coverage.c | 2 +- .../ProfileData/Coverage/CoverageMapping.h | 27 +++++++------ llvm/include/llvm/ProfileData/InstrProf.h | 5 +-- .../ProfileData/Coverage/CoverageMapping.cpp | 40 +++++++------------ llvm/lib/ProfileData/InstrProf.cpp | 2 +- llvm/lib/ProfileData/InstrProfReader.cpp | 1 - 7 files changed, 33 insertions(+), 46 deletions(-) diff --git a/compiler-rt/test/profile/instrprof-block-coverage.c b/compiler-rt/test/profile/instrprof-block-coverage.c index 8d924e1cac64d..829d5af8dc3f9 100644 --- a/compiler-rt/test/profile/instrprof-block-coverage.c +++ b/compiler-rt/test/profile/instrprof-block-coverage.c @@ -49,4 +49,4 @@ int main(int argc, char *argv[]) { // CHECK-ERROR-NOT: warning: {{.*}}: Found inconsistent block coverage -// COUNTS: Maximum function count: 1 +// COUNTS: Maximum function count: 4 diff --git a/compiler-rt/test/profile/instrprof-entry-coverage.c b/compiler-rt/test/profile/instrprof-entry-coverage.c index b93a4e0c43ccd..1c6816ba01964 100644 --- a/compiler-rt/test/profile/instrprof-entry-coverage.c +++ b/compiler-rt/test/profile/instrprof-entry-coverage.c @@ -36,4 +36,4 @@ int main(int argc, char *argv[]) { // CHECK-DAG: foo // CHECK-DAG: bar -// COUNTS: Maximum function count: 1 +// COUNTS: Maximum function count: 2 diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 77c447efe1a7c..fa07b3a9e8b14 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -359,15 +359,19 @@ struct CountedRegion : public CounterMappingRegion { uint64_t ExecutionCount; uint64_t FalseExecutionCount; bool Folded; + bool HasSingleByteCoverage; - CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount) + CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount, + bool HasSingleByteCoverage) : CounterMappingRegion(R), ExecutionCount(ExecutionCount), - FalseExecutionCount(0), Folded(false) {} + FalseExecutionCount(0), Folded(false), + HasSingleByteCoverage(HasSingleByteCoverage) {} CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount, - uint64_t FalseExecutionCount) + uint64_t FalseExecutionCount, bool HasSingleByteCoverage) : CounterMappingRegion(R), ExecutionCount(ExecutionCount), - FalseExecutionCount(FalseExecutionCount), Folded(false) {} + FalseExecutionCount(FalseExecutionCount), Folded(false), + HasSingleByteCoverage(HasSingleByteCoverage) {} }; /// MCDC Record grouping all information together. @@ -698,12 +702,9 @@ struct FunctionRecord { std::vector MCDCRecords; /// The number of times this function was executed. uint64_t ExecutionCount = 0; - bool SingleByteCoverage; - FunctionRecord(StringRef Name, ArrayRef Filenames, - bool SingleByteCoverage) - : Name(Name), Filenames(Filenames.begin(), Filenames.end()), - SingleByteCoverage(SingleByteCoverage) {} + FunctionRecord(StringRef Name, ArrayRef Filenames) + : Name(Name), Filenames(Filenames.begin(), Filenames.end()) {} FunctionRecord(FunctionRecord &&FR) = default; FunctionRecord &operator=(FunctionRecord &&) = default; @@ -713,10 +714,11 @@ struct FunctionRecord { } void pushRegion(CounterMappingRegion Region, uint64_t Count, - uint64_t FalseCount) { + uint64_t FalseCount, bool HasSingleByteCoverage) { if (Region.Kind == CounterMappingRegion::BranchRegion || Region.Kind == CounterMappingRegion::MCDCBranchRegion) { - CountedBranchRegions.emplace_back(Region, Count, FalseCount); + CountedBranchRegions.emplace_back(Region, Count, FalseCount, + HasSingleByteCoverage); // If both counters are hard-coded to zero, then this region represents a // constant-folded branch. if (Region.Count.isZero() && Region.FalseCount.isZero()) @@ -725,7 +727,8 @@ struct FunctionRecord { } if (CountedRegions.empty()) ExecutionCount = Count; - CountedRegions.emplace_back(Region, Count, FalseCount); + CountedRegions.emplace_back(Region, Count, FalseCount, + HasSingleByteCoverage); } }; diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index df9e76966bf42..b0b2258735e2a 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -830,7 +830,6 @@ struct InstrProfValueSiteRecord { /// Profiling information for a single function. struct InstrProfRecord { std::vector Counts; - bool SingleByteCoverage = false; std::vector BitmapBytes; InstrProfRecord() = default; @@ -840,15 +839,13 @@ struct InstrProfRecord { : Counts(std::move(Counts)), BitmapBytes(std::move(BitmapBytes)) {} InstrProfRecord(InstrProfRecord &&) = default; InstrProfRecord(const InstrProfRecord &RHS) - : Counts(RHS.Counts), SingleByteCoverage(RHS.SingleByteCoverage), - BitmapBytes(RHS.BitmapBytes), + : Counts(RHS.Counts), BitmapBytes(RHS.BitmapBytes), ValueData(RHS.ValueData ? std::make_unique(*RHS.ValueData) : nullptr) {} InstrProfRecord &operator=(InstrProfRecord &&) = default; InstrProfRecord &operator=(const InstrProfRecord &RHS) { Counts = RHS.Counts; - SingleByteCoverage = RHS.SingleByteCoverage; BitmapBytes = RHS.BitmapBytes; if (!RHS.ValueData) { ValueData = nullptr; diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index bc765c5938171..9a03dede84b6d 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -856,7 +856,7 @@ Error CoverageMapping::loadFunctionRecord( return Error::success(); MCDCDecisionRecorder MCDCDecisions; - FunctionRecord Function(OrigFuncName, Record.Filenames, SingleByteCoverage); + FunctionRecord Function(OrigFuncName, Record.Filenames); for (const auto &Region : Record.MappingRegions) { // MCDCDecisionRegion should be handled first since it overlaps with // others inside. @@ -874,10 +874,10 @@ Error CoverageMapping::loadFunctionRecord( consumeError(std::move(E)); return Error::success(); } - assert(!SingleByteCoverage || - (0 <= *ExecutionCount && *ExecutionCount <= 1 && - 0 <= *AltExecutionCount && *AltExecutionCount <= 1)); - Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount); + Function.pushRegion( + Region, (SingleByteCoverage && *ExecutionCount ? 1 : *ExecutionCount), + (SingleByteCoverage && *AltExecutionCount ? 1 : *AltExecutionCount), + SingleByteCoverage); // Record ExpansionRegion. if (Region.Kind == CounterMappingRegion::ExpansionRegion) { @@ -1273,8 +1273,7 @@ class SegmentBuilder { /// Combine counts of regions which cover the same area. static ArrayRef - combineRegions(MutableArrayRef Regions, - bool SingleByteCoverage) { + combineRegions(MutableArrayRef Regions) { if (Regions.empty()) return Regions; auto Active = Regions.begin(); @@ -1301,7 +1300,9 @@ class SegmentBuilder { // We add counts of the regions of the same kind as the active region // to handle the both situations. if (I->Kind == Active->Kind) { - if (SingleByteCoverage) + assert(I->HasSingleByteCoverage == Active->HasSingleByteCoverage && + "Regions are generated in different coverage modes"); + if (I->HasSingleByteCoverage) Active->ExecutionCount = Active->ExecutionCount || I->ExecutionCount; else Active->ExecutionCount += I->ExecutionCount; @@ -1313,14 +1314,12 @@ class SegmentBuilder { public: /// Build a sorted list of CoverageSegments from a list of Regions. static std::vector - buildSegments(MutableArrayRef Regions, - bool SingleByteCoverage) { + buildSegments(MutableArrayRef Regions) { std::vector Segments; SegmentBuilder Builder(Segments); sortNestedRegions(Regions); - ArrayRef CombinedRegions = - combineRegions(Regions, SingleByteCoverage); + ArrayRef CombinedRegions = combineRegions(Regions); LLVM_DEBUG({ dbgs() << "Combined regions:\n"; @@ -1407,14 +1406,10 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { // the filename, we may get back some records that are not in the file. ArrayRef RecordIndices = getImpreciseRecordIndicesForFilename(Filename); - std::optional SingleByteCoverage; for (unsigned RecordIndex : RecordIndices) { const FunctionRecord &Function = Functions[RecordIndex]; auto MainFileID = findMainViewFileID(Filename, Function); auto FileIDs = gatherFileIDs(Filename, Function); - assert(!SingleByteCoverage || - *SingleByteCoverage == Function.SingleByteCoverage); - SingleByteCoverage = Function.SingleByteCoverage; for (const auto &CR : Function.CountedRegions) if (FileIDs.test(CR.FileID)) { Regions.push_back(CR); @@ -1432,8 +1427,7 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { } LLVM_DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n"); - FileCoverage.Segments = - SegmentBuilder::buildSegments(Regions, *SingleByteCoverage); + FileCoverage.Segments = SegmentBuilder::buildSegments(Regions); return FileCoverage; } @@ -1489,8 +1483,7 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { LLVM_DEBUG(dbgs() << "Emitting segments for function: " << Function.Name << "\n"); - FunctionCoverage.Segments = - SegmentBuilder::buildSegments(Regions, Function.SingleByteCoverage); + FunctionCoverage.Segments = SegmentBuilder::buildSegments(Regions); return FunctionCoverage; } @@ -1500,12 +1493,8 @@ CoverageData CoverageMapping::getCoverageForExpansion( CoverageData ExpansionCoverage( Expansion.Function.Filenames[Expansion.FileID]); std::vector Regions; - std::optional SingleByteCoverage; for (const auto &CR : Expansion.Function.CountedRegions) if (CR.FileID == Expansion.FileID) { - assert(!SingleByteCoverage || - *SingleByteCoverage == Expansion.Function.SingleByteCoverage); - SingleByteCoverage = Expansion.Function.SingleByteCoverage; Regions.push_back(CR); if (isExpansion(CR, Expansion.FileID)) ExpansionCoverage.Expansions.emplace_back(CR, Expansion.Function); @@ -1517,8 +1506,7 @@ CoverageData CoverageMapping::getCoverageForExpansion( LLVM_DEBUG(dbgs() << "Emitting segments for expansion of file " << Expansion.FileID << "\n"); - ExpansionCoverage.Segments = - SegmentBuilder::buildSegments(Regions, *SingleByteCoverage); + ExpansionCoverage.Segments = SegmentBuilder::buildSegments(Regions); return ExpansionCoverage; } diff --git a/llvm/lib/ProfileData/InstrProf.cpp b/llvm/lib/ProfileData/InstrProf.cpp index 0f6677b4d3571..b9937c9429b77 100644 --- a/llvm/lib/ProfileData/InstrProf.cpp +++ b/llvm/lib/ProfileData/InstrProf.cpp @@ -952,7 +952,7 @@ void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight, Value = getInstrMaxCountValue(); Overflowed = true; } - Counts[I] = (SingleByteCoverage && Value != 0 ? 1 : Value); + Counts[I] = Value; if (Overflowed) Warn(instrprof_error::counter_overflow); } diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index a07d7f573275b..b90617c74f6d1 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -743,7 +743,6 @@ Error RawInstrProfReader::readRawCounts( Record.Counts.clear(); Record.Counts.reserve(NumCounters); - Record.SingleByteCoverage = hasSingleByteCoverage(); for (uint32_t I = 0; I < NumCounters; I++) { const char *Ptr = CountersStart + CounterBaseOffset + I * getCounterTypeSize(); From 52f072e5058267660aa8c8fbb00c5d09634f22b3 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 18 Oct 2024 08:32:39 +0900 Subject: [PATCH 04/35] clang/test/CoverageMapping/single-byte-counters.cpp: Rewrite counter matches --- .../CoverageMapping/single-byte-counters.cpp | 163 +++++++----------- 1 file changed, 65 insertions(+), 98 deletions(-) diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp index 8e9b613dcc68f..d20b695bc2636 100644 --- a/clang/test/CoverageMapping/single-byte-counters.cpp +++ b/clang/test/CoverageMapping/single-byte-counters.cpp @@ -1,169 +1,136 @@ // RUN: %clang_cc1 -mllvm -emptyline-comment-coverage=false -mllvm -enable-single-byte-coverage=true -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name single-byte-counters.cpp %s | FileCheck %s // CHECK: testIf -int testIf(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> [[@LINE+10]]:2 = #0 - // CHECK-NEXT: File 0, [[@LINE+5]]:7 -> [[@LINE+5]]:13 = #0 - // CHECK-NEXT: Gap,File 0, [[@LINE+4]]:14 -> [[@LINE+5]]:5 = #1 - // CHECK-NEXT: File 0, [[@LINE+4]]:5 -> [[@LINE+4]]:16 = #1 - // CHECK-NEXT: File 0, [[@LINE+5]]:3 -> [[@LINE+5]]:16 = #2 +int testIf(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> [[@LINE+7]]:2 = [[C00:#0]] int result = 0; - if (x == 0) - result = -1; + if (x == 0) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:13 = [[C00]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:5 = [[C0T:#1]] + result = -1; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:16 = [[C0T]] - return result; + return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C0E:#2]] } // CHECK-NEXT: testIfElse -int testIfElse(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+13]]:2 = #0 - // CHECK-NEXT: File 0, [[@LINE+7]]:7 -> [[@LINE+7]]:12 = #0 - // CHECK-NEXT: Gap,File 0, [[@LINE+6]]:13 -> [[@LINE+7]]:5 = #1 - // CHECK-NEXT: File 0, [[@LINE+6]]:5 -> [[@LINE+6]]:15 = #1 - // CHECK-NEXT: Gap,File 0, [[@LINE+5]]:16 -> [[@LINE+7]]:5 = #2 - // CHECK-NEXT: File 0, [[@LINE+6]]:5 -> [[@LINE+6]]:19 = #2 - // CHECK-NEXT: File 0, [[@LINE+6]]:3 -> [[@LINE+6]]:16 = #3 +int testIfElse(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+8]]:2 = [[C10:#0]] int result = 0; - if (x < 0) - result = 0; - else - result = x * x; - return result; + if (x < 0) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = [[C10]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:5 = [[C1T:#1]] + result = 0; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:15 = [[C1T]] + else // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:5 = [[C1F:#2]] + result = x * x; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:19 = [[C1F]] + return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C1E:#3]] } // CHECK-NEXT: testIfElseReturn -int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+14]]:2 = #0 - // CHECK-NEXT: File 0, [[@LINE+8]]:7 -> [[@LINE+8]]:12 = #0 - // CHECK-NEXT: Gap,File 0, [[@LINE+7]]:13 -> [[@LINE+8]]:5 = #1 - // CHECK-NEXT: File 0, [[@LINE+7]]:5 -> [[@LINE+7]]:19 = #1 - // CHECK-NEXT: Gap,File 0, [[@LINE+6]]:20 -> [[@LINE+8]]:5 = #2 - // CHECK-NEXT: File 0, [[@LINE+7]]:5 -> [[@LINE+7]]:13 = #2 - // CHECK-NEXT: Gap,File 0, [[@LINE+6]]:14 -> [[@LINE+7]]:3 = #3 - // CHECK-NEXT: File 0, [[@LINE+6]]:3 -> [[@LINE+6]]:16 = #3 +int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+9]]:2 = [[C20:#0]] int result = 0; - if (x > 0) - result = x * x; - else - return 0; - return result; + if (x > 0) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = [[C20]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:5 = [[C2T:#1]] + result = x * x; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:19 = [[C2T]] + else // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:20 -> [[@LINE+1]]:5 = [[C2F:#2]] + return 0; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:13 = [[C2F]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:3 = [[C2E:#3]] + return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C2E:#3]] } // CHECK-NEXT: testSwitch -int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+22]]:2 = #0 - // CHECK-NEXT: Gap,File 0, [[@LINE+9]]:14 -> [[@LINE+17]]:15 = 0 - // CHECK-NEXT: File 0, [[@LINE+9]]:3 -> [[@LINE+11]]:10 = #2 - // CHECK-NEXT: Gap,File 0, [[@LINE+10]]:11 -> [[@LINE+11]]:3 = 0 - // CHECK-NEXT: File 0, [[@LINE+10]]:3 -> [[@LINE+12]]:10 = #3 - // CHECK-NEXT: Gap,File 0, [[@LINE+11]]:11 -> [[@LINE+12]]:3 = 0 - // CHECK-NEXT: File 0, [[@LINE+11]]:3 -> [[@LINE+12]]:15 = #4 - // CHECK-NEXT: Gap,File 0, [[@LINE+12]]:4 -> [[@LINE+14]]:3 = #1 - // CHECK-NEXT: File 0, [[@LINE+13]]:3 -> [[@LINE+13]]:16 = #1 +int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+17]]:2 = [[C30:#0]] int result; switch (x) { - case 1: + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+10]]:15 = 0 + case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = [[C31:#2]] result = 1; break; - case 2: + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = 0 + case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:10 = [[C32:#3]] result = 2; break; - default: + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = 0 + default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:15 = [[C3D:#4]] result = 0; } - - return result; + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C3E:#1]] + return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C3E]] } // CHECK-NEXT: testWhile -int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+13]]:2 = #0 - // CHECK-NEXT: File 0, [[@LINE+6]]:10 -> [[@LINE+6]]:16 = #1 - // CHECK-NEXT: Gap,File 0, [[@LINE+5]]:17 -> [[@LINE+5]]:18 = #2 - // CHECK-NEXT: File 0, [[@LINE+4]]:18 -> [[@LINE+7]]:4 = #2 - // CHECK-NEXT: File 0, [[@LINE+8]]:3 -> [[@LINE+8]]:13 = #3 +int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+11]]:2 = [[C40:#0]] int i = 0; int sum = 0; - while (i < 10) { + while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = [[C4C:#1]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:17 -> [[@LINE-1]]:18 = [[C4T:#2]] + // CHECK-NEXT: File 0, [[@LINE-2]]:18 -> [[@LINE+3]]:4 = [[C4T]] sum += i; i++; } - return sum; + return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C4E:#3]] } // CHECK-NEXT: testContinue -int testContinue() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+21]]:2 = #0 - // CHECK-NEXT: File 0, [[@LINE+12]]:10 -> [[@LINE+12]]:16 = #1 - // CHECK-NEXT: Gap,File 0, [[@LINE+11]]:17 -> [[@LINE+11]]:18 = #2 - // CHECK-NEXT: File 0, [[@LINE+10]]:18 -> [[@LINE+15]]:4 = #2 - // CHECK-NEXT: File 0, [[@LINE+10]]:9 -> [[@LINE+10]]:15 = #2 - // CHECK-NEXT: Gap,File 0, [[@LINE+9]]:16 -> [[@LINE+10]]:7 = #4 - // CHECK-NEXT: File 0, [[@LINE+9]]:7 -> [[@LINE+9]]:15 = #4 - // CHECK-NEXT: Gap,File 0, [[@LINE+8]]:16 -> [[@LINE+9]]:5 = #5 - // CHECK-NEXT: File 0, [[@LINE+8]]:5 -> [[@LINE+10]]:4 = #5 - // CHECK-NEXT: Gap,File 0, [[@LINE+9]]:4 -> [[@LINE+11]]:3 = #3 - // CHECK-NEXT: File 0, [[@LINE+10]]:3 -> [[@LINE+10]]:13 = #3 +int testContinue() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+15]]:2 = [[C50:#0]] int i = 0; int sum = 0; - while (i < 10) { - if (i == 4) - continue; - sum += i; + while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = [[C5C:#1]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:17 -> [[@LINE-1]]:18 = [[C5B:#2]] + // CHECK-NEXT: File 0, [[@LINE-2]]:18 -> [[@LINE+7]]:4 = [[C5B]] + if (i == 4) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = [[C5B]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:7 = [[C5T:#4]] + continue; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = [[C5T]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:5 = [[C5F:#5]] + sum += i; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = [[C5F]] i++; } - - return sum; + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C5E:#3]] + return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C5E]] } // CHECK-NEXT: testFor -int testFor() { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+13]]:2 = #0 - // CHECK-NEXT: File 0, [[@LINE+7]]:19 -> [[@LINE+7]]:25 = #1 - // CHECK-NEXT: File 0, [[@LINE+6]]:27 -> [[@LINE+6]]:30 = #2 - // CHECK-NEXT: Gap,File 0, [[@LINE+5]]:31 -> [[@LINE+5]]:32 = #3 - // CHECK-NEXT: File 0, [[@LINE+4]]:32 -> [[@LINE+6]]:4 = #3 - // CHECK-NEXT: File 0, [[@LINE+7]]:3 -> [[@LINE+7]]:13 = #4 +int testFor() { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+12]]:2 = [[C60:#0]] int i; int sum = 0; + // CHECK-NEXT: File 0, [[@LINE+2]]:19 -> [[@LINE+2]]:25 = [[C61:#1]] + // CHECK-NEXT: File 0, [[@LINE+1]]:27 -> [[@LINE+1]]:30 = [[C6C:#2]] for (int i = 0; i < 10; i++) { + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:31 -> [[@LINE-1]]:32 = [[C6B:#3]] + // CHECK-NEXT: File 0, [[@LINE-2]]:32 -> [[@LINE+2]]:4 = [[C6B]] sum += i; } - return sum; + return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C6E:#4]] } // CHECK-NEXT: testForRange -int testForRange() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+12]]:2 = #0 - // CHECK-NEXT: Gap,File 0, [[@LINE+6]]:28 -> [[@LINE+6]]:29 = #1 - // CHECK-NEXT: File 0, [[@LINE+5]]:29 -> [[@LINE+7]]:4 = #1 - // CHECK-NEXT: File 0, [[@LINE+8]]:3 -> [[@LINE+8]]:13 = #2 +int testForRange() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+11]]:2 = [[C70:#0]] int sum = 0; int array[] = {1, 2, 3, 4, 5}; for (int element : array) { + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:28 -> [[@LINE-1]]:29 = [[C7B:#1]] + // CHECK-NEXT: File 0, [[@LINE-2]]:29 -> [[@LINE+2]]:4 = [[C7B]] sum += element; } - return sum; + return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C7E:#2]] } // CHECK-NEXT: testDo -int testDo() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+12]]:2 = #0 - // CHECK-NEXT: File 0, [[@LINE+5]]:6 -> [[@LINE+8]]:4 = #1 - // CHECK-NEXT: File 0, [[@LINE+7]]:12 -> [[@LINE+7]]:17 = #2 - // CHECK-NEXT: File 0, [[@LINE+8]]:3 -> [[@LINE+8]]:13 = #3 +int testDo() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+9]]:2 = [[C80:#0]] int i = 0; int sum = 0; - do { + do { // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE+3]]:4 = [[C8B:#1]] sum += i; i++; - } while (i < 5); + } while (i < 5); // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE]]:17 = [[C8C:#2]] - return sum; + return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C8E:#3]] } // CHECK-NEXT: testConditional -int testConditional(int x) { // CHECK-NEXT: File 0, [[@LINE]]:28 -> [[@LINE+8]]:2 = #0 - // CHECK-NEXT: File 0, [[@LINE+5]]:15 -> [[@LINE+5]]:22 = #0 - // CHECK-NEXT: Gap,File 0, [[@LINE+4]]:24 -> [[@LINE+4]]:25 = #2 - // CHECK-NEXT: File 0, [[@LINE+3]]:25 -> [[@LINE+3]]:26 = #2 - // CHECK-NEXT: File 0, [[@LINE+2]]:29 -> [[@LINE+2]]:31 = #3 - // CHECK-NEXT: File 0, [[@LINE+2]]:2 -> [[@LINE+2]]:15 = #1 - int result = (x > 0) ? 1 : -1; - return result; +int testConditional(int x) { // CHECK-NEXT: File 0, [[@LINE]]:28 -> [[@LINE+6]]:2 = [[C90:#0]] + int result = (x > 0) ? 1 : -1; // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE]]:22 = [[C90]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:24 -> [[@LINE-1]]:25 = [[C9T:#2]] + // CHECK-NEXT: File 0, [[@LINE-2]]:25 -> [[@LINE-2]]:26 = [[C9T]] + // CHECK-NEXT: File 0, [[@LINE-3]]:29 -> [[@LINE-3]]:31 = [[C9F:#3]] + return result; // CHECK-NEXT: File 0, [[@LINE]]:2 -> [[@LINE]]:15 = [[C9E:#1]] } From 97a4a8f40afb53250639c29e193edd814cb82f58 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 20 Nov 2024 23:33:51 +0900 Subject: [PATCH 05/35] test/llvm-cov: Transform %.c* tests to {%.test, Inputs/%.c*} And reformat. NFC. --- .../{ => Inputs}/branch-logical-mixed.cpp | 13 +--- .../llvm-cov/{ => Inputs}/branch-macros.cpp | 14 +--- .../Inputs/branch-showBranchPercentage.c | 58 +++++++++++++++ .../llvm-cov/Inputs/branch-templates.cpp | 38 ++++++++++ .../Inputs/showLineExecutionCounts.cpp | 29 ++++++++ .../test/tools/llvm-cov/branch-c-general.test | 2 +- .../tools/llvm-cov/branch-logical-mixed.test | 11 +++ llvm/test/tools/llvm-cov/branch-macros.test | 11 +++ .../tools/llvm-cov/branch-noShowBranch.test | 8 +- ...age.c => branch-showBranchPercentage.test} | 57 +-------------- ...ch-templates.cpp => branch-templates.test} | 46 ++---------- .../llvm-cov/showLineExecutionCounts.cpp | 73 ------------------- .../llvm-cov/showLineExecutionCounts.test | 43 +++++++++++ 13 files changed, 209 insertions(+), 194 deletions(-) rename llvm/test/tools/llvm-cov/{ => Inputs}/branch-logical-mixed.cpp (80%) rename llvm/test/tools/llvm-cov/{ => Inputs}/branch-macros.cpp (70%) create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-showBranchPercentage.c create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp create mode 100644 llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp create mode 100644 llvm/test/tools/llvm-cov/branch-logical-mixed.test create mode 100644 llvm/test/tools/llvm-cov/branch-macros.test rename llvm/test/tools/llvm-cov/{branch-showBranchPercentage.c => branch-showBranchPercentage.test} (51%) rename llvm/test/tools/llvm-cov/{branch-templates.cpp => branch-templates.test} (54%) delete mode 100644 llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp create mode 100644 llvm/test/tools/llvm-cov/showLineExecutionCounts.test diff --git a/llvm/test/tools/llvm-cov/branch-logical-mixed.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp similarity index 80% rename from llvm/test/tools/llvm-cov/branch-logical-mixed.cpp rename to llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp index f5f7871124467..0a7d8d8967115 100644 --- a/llvm/test/tools/llvm-cov/branch-logical-mixed.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp @@ -1,6 +1,6 @@ -// RUN: llvm-profdata merge %S/Inputs/branch-logical-mixed.proftext -o %t.profdata -// RUN: llvm-cov show --show-branches=count %S/Inputs/branch-logical-mixed.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s -// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-logical-mixed.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S %s | FileCheck %s -check-prefix=REPORT + + + #include #include @@ -81,10 +81,3 @@ int main(int argc, char *argv[]) __llvm_profile_write_file(); return 0; } - -// REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover -// REPORT-NEXT: --- -// REPORT-NEXT: _Z4funcii 77 9 88.31% 68 3 95.59% 80 32 60.00% -// REPORT-NEXT: main 1 0 100.00% 5 0 100.00% 0 0 0.00% -// REPORT-NEXT: --- -// REPORT-NEXT: TOTAL 78 9 88.46% 73 3 95.89% 80 32 60.00% diff --git a/llvm/test/tools/llvm-cov/branch-macros.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp similarity index 70% rename from llvm/test/tools/llvm-cov/branch-macros.cpp rename to llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp index 73042ac397d40..712b2790f774a 100644 --- a/llvm/test/tools/llvm-cov/branch-macros.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp @@ -1,6 +1,6 @@ -// RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata -// RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s -// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S %s | FileCheck %s -check-prefix=REPORT + + + #define COND1 (a == b) #define COND2 (a != b) @@ -50,11 +50,3 @@ int main(int argc, char *argv[]) __llvm_profile_write_file(); return 0; } - -// REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover -// REPORT-NEXT: --- -// REPORT-NEXT: _Z4funcii 28 4 85.71% 18 0 100.00% 30 14 53.33% -// REPORT-NEXT: _Z5func2ii 13 1 92.31% 8 0 100.00% 10 2 80.00% -// REPORT-NEXT: main 1 0 100.00% 6 0 100.00% 0 0 0.00% -// REPORT-NEXT: --- -// REPORT-NEXT: TOTAL 42 5 88.10% 32 0 100.00% 40 16 60.00% diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-showBranchPercentage.c b/llvm/test/tools/llvm-cov/Inputs/branch-showBranchPercentage.c new file mode 100644 index 0000000000000..c41739ff0b22f --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/branch-showBranchPercentage.c @@ -0,0 +1,58 @@ + + + + + +#include +#include + +extern void __llvm_profile_write_file(void); + +int main(int argc, char *argv[]) +{ + int i = 0; + if (argc < 3) // CHECK: Branch ([[@LINE]]:7): [True: 16.67%, False: 83.33%] + { + __llvm_profile_write_file(); + return 0; + } + + int a = atoi(argv[1]); + int b = atoi(argv[2]); + + // CHECK: Branch ([[@LINE+4]]:8): [True: 20.00%, False: 80.00%] + // CHECK: Branch ([[@LINE+3]]:18): [True: 0.00%, False: 100.00%] + // CHECK: Branch ([[@LINE+2]]:29): [True: 0.00%, False: 100.00%] + // CHECK: Branch ([[@LINE+1]]:40): [True: 40.00%, False: 60.00%] + if ((a == 0 && b == 2) || b == 34 || a == b) + printf("case1\n"); + + b = (a != 0 || a == 2) ? b : b+2; // CHECK: Branch ([[@LINE]]:8): [True: 80.00%, False: 20.00%] + // CHECK: Branch ([[@LINE-1]]:18): [True: 0.00%, False: 100.00%] + b = (a != 0 && a == 1); // CHECK: Branch ([[@LINE]]:8): [True: 80.00%, False: 20.00%] + // CHECK: Branch ([[@LINE-1]]:18): [True: 25.00%, False: 75.00%] + for (i = 0; i < b; i++) { a = 2 + b + b; } + // CHECK: Branch ([[@LINE-1]]:15): [True: 16.67%, False: 83.33%] + + b = a; + + switch (a) + { + case 0: // CHECK: Branch ([[@LINE]]:5): [True: 20.00%, False: 80.00%] + printf("case0\n"); + case 2: // CHECK: Branch ([[@LINE]]:5): [True: 20.00%, False: 80.00%] + printf("case2\n"); + case 3: // CHECK: Branch ([[@LINE]]:5): [True: 0.00%, False: 100.00%] + printf("case3\n"); + default: break; // CHECK: Branch ([[@LINE]]:5): [True: 60.00%, False: 40.00%] + } + + i = 0; + do { + printf("loop\n"); + } while (i++ < 10); // CHECK: Branch ([[@LINE]]:12): [True: 90.91%, False: 9.09%] + + __llvm_profile_write_file(); + + return b; +} diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp new file mode 100644 index 0000000000000..0795a5346380d --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp @@ -0,0 +1,38 @@ + + + + + +#include +template +void unused(T x) { + return; +} + +template +int func(T x) { + if(x) // CHECK: | Branch ([[@LINE]]:6): [True: 0, False: 1] + return 0; // CHECK: | Branch ([[@LINE-1]]:6): [True: 1, False: 0] + else // CHECK: | Branch ([[@LINE-2]]:6): [True: 0, False: 1] + return 1; + int j = 1; +} + + // CHECK-LABEL: _Z4funcIiEiT_: + // CHECK: | | Branch ([[@LINE-8]]:6): [True: 0, False: 1] + // CHECK-LABEL: _Z4funcIbEiT_: + // CHECK: | | Branch ([[@LINE-10]]:6): [True: 1, False: 0] + // CHECK-LABEL: _Z4funcIfEiT_: + // CHECK: | | Branch ([[@LINE-12]]:6): [True: 0, False: 1] + +extern "C" { extern void __llvm_profile_write_file(void); } +int main() { + if (func(0)) // CHECK: | Branch ([[@LINE]]:7): [True: 1, False: 0] + printf("case1\n"); + if (func(true)) // CHECK: | Branch ([[@LINE]]:7): [True: 0, False: 1] + printf("case2\n"); + if (func(0.0)) // CHECK: | Branch ([[@LINE]]:7): [True: 1, False: 0] + printf("case3\n"); + __llvm_profile_write_file(); + return 0; +} diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp new file mode 100644 index 0000000000000..c7e8c8fb0c75e --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp @@ -0,0 +1,29 @@ +// HTML-WHOLE-FILE:
[[@LINE+2]]
// before
+// HTML-FILTER-NOT: 
[[@LINE+1]]
// before
+// before any coverage              // WHOLE-FILE: [[@LINE]]|      |// before
+                                    // FILTER-NOT: [[@LINE-1]]|    |// before
+// HTML: 
[[@LINE+1]]
161
int main() {
+int main() {                              // TEXT: [[@LINE]]|   161|int main(
+  int x = 0;                              // TEXT: [[@LINE]]|   161|  int x
+                                          // TEXT: [[@LINE]]|   161|
+  if (x) {                                // TEXT: [[@LINE]]|   161|  if (x)
+    x = 0;                                // TEXT: [[@LINE]]|     0|    x = 0
+  } else {                                // TEXT: [[@LINE]]|   161|  } else
+    x = 1;                                // TEXT: [[@LINE]]|   161|    x = 1
+  }                                       // TEXT: [[@LINE]]|   161|  }
+                                          // TEXT: [[@LINE]]|   161|
+  for (int i = 0; i < 100; ++i) {         // TEXT: [[@LINE]]| 16.2k|  for (
+    x = 1;                                // TEXT: [[@LINE]]| 16.1k|    x = 1
+  }                                       // TEXT: [[@LINE]]| 16.1k|  }
+                                          // TEXT: [[@LINE]]|   161|
+  x = x < 10 ? x + 1 : x - 1;             // TEXT: [[@LINE]]|   161|  x =
+  x = x > 10 ?                            // TEXT: [[@LINE]]|   161|  x =
+        x - 1:                            // TEXT: [[@LINE]]|     0|        x
+        x + 1;                            // TEXT: [[@LINE]]|   161|        x
+                                          // TEXT: [[@LINE]]|   161|
+  return 0;                               // TEXT: [[@LINE]]|   161|  return
+}                                         // TEXT: [[@LINE]]|   161|}
+// after coverage                   // WHOLE-FILE: [[@LINE]]|      |// after
+                                    // FILTER-NOT: [[@LINE-1]]|    |// after
+// HTML-WHOLE-FILE: 
[[@LINE-2]]
// after
+// HTML-FILTER-NOT: 
[[@LINE-3]]
// after
diff --git a/llvm/test/tools/llvm-cov/branch-c-general.test b/llvm/test/tools/llvm-cov/branch-c-general.test
index 2fa99dfe61532..865a2662460e8 100644
--- a/llvm/test/tools/llvm-cov/branch-c-general.test
+++ b/llvm/test/tools/llvm-cov/branch-c-general.test
@@ -114,7 +114,7 @@
 
 
 
-//      REPORT: Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
+// REPORT:      Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
 // REPORT-NEXT: ---
 // REPORT-NEXT: simple_loops                      8       0 100.00%         9       0 100.00%         6       0 100.00%
 // REPORT-NEXT: conditionals                     24       0 100.00%        15       0 100.00%        16       2  87.50%
diff --git a/llvm/test/tools/llvm-cov/branch-logical-mixed.test b/llvm/test/tools/llvm-cov/branch-logical-mixed.test
new file mode 100644
index 0000000000000..a07d2357f2c34
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/branch-logical-mixed.test
@@ -0,0 +1,11 @@
+// RUN: llvm-profdata merge %S/Inputs/branch-logical-mixed.proftext -o %t.profdata
+// RUN: llvm-cov show --show-branches=count %S/Inputs/branch-logical-mixed.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-logical-mixed.cpp
+// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-logical-mixed.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-logical-mixed.cpp
+| FileCheck %s -check-prefix=REPORT
+
+// REPORT:      Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
+// REPORT-NEXT: ---
+// REPORT-NEXT: _Z4funcii                        77      15  80.52%        60       2  96.67%        80      30  62.50%
+// REPORT-NEXT: main                              1       0 100.00%         5       0 100.00%         0       0   0.00%
+// REPORT-NEXT: ---
+// REPORT-NEXT: TOTAL                            78      15  80.77%        65       2  96.92%        80      30  62.50%
diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test
new file mode 100644
index 0000000000000..fbe7694b4f4e0
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/branch-macros.test
@@ -0,0 +1,11 @@
+// RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata
+// RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp
+// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=REPORT
+
+// REPORT:      Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
+// REPORT-NEXT: ---
+// REPORT-NEXT: _Z4funcii                        28       4  85.71%        18       0 100.00%        30      14  53.33%
+// REPORT-NEXT: _Z5func2ii                       13       1  92.31%         8       0 100.00%        10       2  80.00%
+// REPORT-NEXT: main                              1       0 100.00%         6       0 100.00%         0       0   0.00%
+// REPORT-NEXT: ---
+// REPORT-NEXT: TOTAL                            42       5  88.10%        32       0 100.00%        40      16  60.00%
diff --git a/llvm/test/tools/llvm-cov/branch-noShowBranch.test b/llvm/test/tools/llvm-cov/branch-noShowBranch.test
index 25a98d59481aa..cabeeb01bfe3e 100644
--- a/llvm/test/tools/llvm-cov/branch-noShowBranch.test
+++ b/llvm/test/tools/llvm-cov/branch-noShowBranch.test
@@ -5,9 +5,9 @@
 
 // CHECK-NOT: | Branch
 
-// REPORT: Name                        Regions    Miss   Cover     Lines    Miss   Cover
+// REPORT:     Name                        Regions    Miss   Cover     Lines    Miss   Cover
 // REPORT-NOT: Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
-// REPORT: ---
+// REPORT:     ---
 // REPORT-NOT: simple_loops                      8       0 100.00%         9       0 100.00%         6       0 100.00%
 // REPORT-NOT: conditionals                     24       0 100.00%        15       0 100.00%        16       2  87.50%
 // REPORT-NOT: early_exits                      20       4  80.00%        25       2  92.00%        16       6  62.50%
@@ -20,6 +20,6 @@
 // REPORT-NOT: do_fallthrough                    9       0 100.00%        12       0 100.00%         6       0 100.00%
 // REPORT-NOT: main                              1       0 100.00%        16       0 100.00%         0       0   0.00%
 // REPORT-NOT: c-general.c:static_func           4       0 100.00%         4       0 100.00%         2       0 100.00%
-// REPORT: TOTAL                           197      24  87.82%       234       8  96.58%
-// REPORT-NOT: TOTAL                           197      24  87.82%       234       13  94.44%       174      38  78.16%
+// REPORT:     TOTAL                           197      24  87.82%       234       8  96.58%
+// REPORT-NOT: TOTAL                           197      24  87.82%       234      13  94.44%       174      38  78.16%
 
diff --git a/llvm/test/tools/llvm-cov/branch-showBranchPercentage.c b/llvm/test/tools/llvm-cov/branch-showBranchPercentage.test
similarity index 51%
rename from llvm/test/tools/llvm-cov/branch-showBranchPercentage.c
rename to llvm/test/tools/llvm-cov/branch-showBranchPercentage.test
index a649462116a08..f6f9e3df742b4 100644
--- a/llvm/test/tools/llvm-cov/branch-showBranchPercentage.c
+++ b/llvm/test/tools/llvm-cov/branch-showBranchPercentage.test
@@ -1,63 +1,10 @@
 // Test visualization of branch taken percentages
 
 // RUN: llvm-profdata merge %S/Inputs/branch-showBranchPercentage.proftext -o %t.profdata
-// RUN: llvm-cov show --show-branches=percent %S/Inputs/branch-showBranchPercentage.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s
+// RUN: llvm-cov show --show-branches=percent %S/Inputs/branch-showBranchPercentage.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-showBranchPercentage.c
 
-#include 
-#include 
-
-extern void __llvm_profile_write_file(void);
-
-int main(int argc, char *argv[])
-{
-  int i = 0;
-  if (argc < 3)                       // CHECK: Branch ([[@LINE]]:7): [True: 16.67%, False: 83.33%]
-  {
-    __llvm_profile_write_file();
-    return 0;
-  }
-
-  int a = atoi(argv[1]);
-  int b = atoi(argv[2]);
-
-                                      // CHECK: Branch ([[@LINE+4]]:8): [True: 20.00%, False: 80.00%]
-                                      // CHECK: Branch ([[@LINE+3]]:18): [True: 0.00%, False: 100.00%]
-                                      // CHECK: Branch ([[@LINE+2]]:29): [True: 0.00%, False: 100.00%]
-                                      // CHECK: Branch ([[@LINE+1]]:40): [True: 40.00%, False: 60.00%]
-  if ((a == 0 && b == 2) || b == 34 || a == b)
-    printf("case1\n");
-
-  b = (a != 0 || a == 2) ? b : b+2;   // CHECK: Branch ([[@LINE]]:8): [True: 80.00%, False: 20.00%]
-                                      // CHECK: Branch ([[@LINE-1]]:18): [True: 0.00%, False: 100.00%]
-  b = (a != 0 && a == 1);             // CHECK: Branch ([[@LINE]]:8): [True: 80.00%, False: 20.00%]
-                                      // CHECK: Branch ([[@LINE-1]]:18): [True: 25.00%, False: 75.00%]
-  for (i = 0; i < b; i++) { a = 2 + b + b; }
-                                      // CHECK: Branch ([[@LINE-1]]:15): [True: 16.67%, False: 83.33%]
-
-  b = a;
-
-  switch (a)
-  {
-    case 0:                           // CHECK: Branch ([[@LINE]]:5): [True: 20.00%, False: 80.00%]
-      printf("case0\n");
-    case 2:                           // CHECK: Branch ([[@LINE]]:5): [True: 20.00%, False: 80.00%]
-      printf("case2\n");
-    case 3:                           // CHECK: Branch ([[@LINE]]:5): [True: 0.00%, False: 100.00%]
-      printf("case3\n");
-    default: break;                   // CHECK: Branch ([[@LINE]]:5): [True: 60.00%, False: 40.00%]
-  }
-
-  i = 0;
-  do {
-    printf("loop\n");
-  } while (i++ < 10);                 // CHECK: Branch ([[@LINE]]:12): [True: 90.91%, False: 9.09%]
-
-  __llvm_profile_write_file();
-
-  return b;
-}
 // RUN: llvm-profdata merge %S/Inputs/branch-showBranchPercentage.proftext -o %t.profdata
-// RUN: llvm-cov show --show-branches=percent %S/Inputs/branch-showBranchPercentage.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s -format html -o %t.html.dir
+// RUN: llvm-cov show --show-branches=percent %S/Inputs/branch-showBranchPercentage.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -format html -o %t.html.dir
 
 // Test html output.
 // RUN: FileCheck -check-prefix=HTML -input-file=%t.html.dir/coverage/tmp/branch-showBranchPercentage.c.html %s
diff --git a/llvm/test/tools/llvm-cov/branch-templates.cpp b/llvm/test/tools/llvm-cov/branch-templates.test
similarity index 54%
rename from llvm/test/tools/llvm-cov/branch-templates.cpp
rename to llvm/test/tools/llvm-cov/branch-templates.test
index 4797428f8835a..74aef16050228 100644
--- a/llvm/test/tools/llvm-cov/branch-templates.cpp
+++ b/llvm/test/tools/llvm-cov/branch-templates.test
@@ -1,43 +1,9 @@
 // RUN: llvm-profdata merge %S/Inputs/branch-templates.proftext -o %t.profdata
-// RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-templates.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s
-// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-templates.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S %s | FileCheck %s -check-prefix=REPORT
-// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-templates.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s -check-prefix=REPORTFILE
+// RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-templates.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-templates.cpp
+// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-templates.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-templates.cpp | FileCheck %s -check-prefix=REPORT
+// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-templates.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %s -check-prefix=REPORTFILE
 
-#include 
-template
-void unused(T x) {
-  return;
-}
-
-template
-int func(T x) {
-  if(x)       // CHECK: |  Branch ([[@LINE]]:6): [True: 0, False: 1]
-    return 0; // CHECK: |  Branch ([[@LINE-1]]:6): [True: 1, False: 0]
-  else        // CHECK: |  Branch ([[@LINE-2]]:6): [True: 0, False: 1]
-    return 1;
-  int j = 1;
-}
-
-              // CHECK-LABEL: _Z4funcIiEiT_:
-              // CHECK: |  |  Branch ([[@LINE-8]]:6): [True: 0, False: 1]
-              // CHECK-LABEL: _Z4funcIbEiT_:
-              // CHECK: |  |  Branch ([[@LINE-10]]:6): [True: 1, False: 0]
-              // CHECK-LABEL: _Z4funcIfEiT_:
-              // CHECK: |  |  Branch ([[@LINE-12]]:6): [True: 0, False: 1]
-
-extern "C" { extern void __llvm_profile_write_file(void); }
-int main() {
-  if (func(0))      // CHECK: |  Branch ([[@LINE]]:7): [True: 1, False: 0]
-    printf("case1\n");
-  if (func(true))  // CHECK: |  Branch ([[@LINE]]:7): [True: 0, False: 1]
-    printf("case2\n");
-  if (func(0.0))  // CHECK: |  Branch ([[@LINE]]:7): [True: 1, False: 0]
-    printf("case3\n");
-  __llvm_profile_write_file();
-  return 0;
-}
-
-// REPORT: Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
+// REPORT:      Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
 // REPORT-NEXT: ---
 // REPORT-NEXT: main                              7       1  85.71%        10       1  90.00%         6       3  50.00%
 // REPORT-NEXT: _Z4funcIiEiT_                     5       2  60.00%         7       3  57.14%         2       1  50.00%
@@ -54,8 +20,8 @@ int main() {
 // respectively).  This is returned by: FunctionCoverageSummary::get(const
 // InstantiationGroup &Group, ...)
 
-// REPORTFILE: Filename                      Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover    Branches   Missed Branches     Cover
+// REPORTFILE:      Filename                 Regions    Missed Regions     Cover   Functions  Missed Functions  Executed       Lines      Missed Lines     Cover    Branches   Missed Branches     Cover
 // REPORTFILE-NEXT: ---
 // REPORTFILE-NEXT: branch-templates.cpp          12                 3    75.00%           2                 0   100.00%          17                 4    76.47%           8                 4    50.00%
 // REPORTFILE-NEXT: ---
-// REPORTFILE-NEXT: TOTAL                              12                 3    75.00%           2                 0   100.00%          17                 4    76.47%           8                 4    50.00%
+// REPORTFILE-NEXT: TOTAL                         12                 3    75.00%           2                 0   100.00%          17                 4    76.47%           8                 4    50.00%
diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp b/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
deleted file mode 100644
index f72a9978b8a73..0000000000000
--- a/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// Basic handling of line counts.
-// RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata
-
-// before any coverage              // WHOLE-FILE: [[@LINE]]|      |// before
-                                    // FILTER-NOT: [[@LINE-1]]|    |// before
-int main() {                              // TEXT: [[@LINE]]|   161|int main(
-  int x = 0;                              // TEXT: [[@LINE]]|   161|  int x
-                                          // TEXT: [[@LINE]]|   161|
-  if (x) {                                // TEXT: [[@LINE]]|   161|  if (x)
-    x = 0;                                // TEXT: [[@LINE]]|     0|    x = 0
-  } else {                                // TEXT: [[@LINE]]|   161|  } else
-    x = 1;                                // TEXT: [[@LINE]]|   161|    x = 1
-  }                                       // TEXT: [[@LINE]]|   161|  }
-                                          // TEXT: [[@LINE]]|   161|
-  for (int i = 0; i < 100; ++i) {         // TEXT: [[@LINE]]| 16.2k|  for (
-    x = 1;                                // TEXT: [[@LINE]]| 16.1k|    x = 1
-  }                                       // TEXT: [[@LINE]]| 16.1k|  }
-                                          // TEXT: [[@LINE]]|   161|
-  x = x < 10 ? x + 1 : x - 1;             // TEXT: [[@LINE]]|   161|  x =
-  x = x > 10 ?                            // TEXT: [[@LINE]]|   161|  x =
-        x - 1:                            // TEXT: [[@LINE]]|     0|        x
-        x + 1;                            // TEXT: [[@LINE]]|   161|        x
-                                          // TEXT: [[@LINE]]|   161|
-  return 0;                               // TEXT: [[@LINE]]|   161|  return
-}                                         // TEXT: [[@LINE]]|   161|}
-// after coverage                   // WHOLE-FILE: [[@LINE]]|      |// after
-                                    // FILTER-NOT: [[@LINE-1]]|    |// after
-
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck -check-prefixes=TEXT,WHOLE-FILE %s
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S -name=main %s | FileCheck -check-prefixes=TEXT,FILTER %s
-
-// Test -output-dir.
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S %s
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -output-dir %t.filtered.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S -name=main %s
-// RUN: FileCheck -check-prefixes=TEXT,WHOLE-FILE -input-file %t.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %s
-// RUN: FileCheck -check-prefixes=TEXT,FILTER -input-file %t.filtered.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %s
-//
-// RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata 2>/dev/null -summary-only > %t.export-summary.json
-// RUN: not grep '"name":"main"' %t.export-summary.json
-//
-// Test html output.
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.html.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S %s
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.html.filtered.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S -name=main %s
-// RUN: FileCheck -check-prefixes=HTML,HTML-WHOLE-FILE -input-file %t.html.dir/coverage/tmp/showLineExecutionCounts.cpp.html %s
-// RUN: FileCheck -check-prefixes=HTML,HTML-FILTER -input-file %t.html.filtered.dir/coverage/tmp/showLineExecutionCounts.cpp.html %s
-//
-// HTML-WHOLE-FILE: 
4
// before
-// HTML-FILTER-NOT: 
4
// before
-// HTML: 
6
161
int main() {
-// HTML-WHOLE-FILE: 
26
// after
-// HTML-FILTER-NOT: 
26
// after
-//
-// Test index creation.
-// RUN: FileCheck -check-prefix=TEXT-INDEX -input-file %t.dir/index.txt %s
-// TEXT-INDEX: Filename
-// TEXT-INDEX-NEXT: ---
-// TEXT-INDEX-NEXT: {{.*}}showLineExecutionCounts.cpp
-//
-// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.html.dir/index.html %s
-// HTML-INDEX-LABEL: 
-// HTML-INDEX: 
-// HTML-INDEX: 
-// HTML-INDEX: 
-// HTML-INDEX: 
-// HTML-INDEX: 
-// HTML-INDEX: 
-// HTML-INDEX: Totals
diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.test b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test
new file mode 100644
index 0000000000000..997b16a0b8e94
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test
@@ -0,0 +1,43 @@
+// Basic handling of line counts.
+// RUN: rm -rf %t*.dir
+// RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata
+
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE %S/Inputs/showLineExecutionCounts.cpp
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main | FileCheck -check-prefixes=TEXT,FILTER %S/Inputs/showLineExecutionCounts.cpp
+
+// Test -output-dir.
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -output-dir %t.filtered.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main
+// RUN: FileCheck -check-prefixes=TEXT,WHOLE-FILE -input-file %t.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp
+// RUN: FileCheck -check-prefixes=TEXT,FILTER -input-file %t.filtered.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp
+//
+// RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata 2>/dev/null -summary-only > %t.export-summary.json
+// RUN: not grep '"name":"main"' %t.export-summary.json
+//
+// Test html output.
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.html.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.html.filtered.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main
+// RUN: FileCheck -check-prefixes=HTML,HTML-WHOLE-FILE -input-file %t.html.dir/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp
+// RUN: FileCheck -check-prefixes=HTML,HTML-FILTER -input-file %t.html.filtered.dir/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp
+//
+// Test index creation.
+// RUN: FileCheck -check-prefix=TEXT-INDEX -input-file %t.dir/index.txt %s
+// TEXT-INDEX: Filename
+// TEXT-INDEX-NEXT: ---
+// TEXT-INDEX-NEXT: {{.*}}showLineExecutionCounts.cpp
+//
+// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.html.dir/index.html %s
+// HTML-INDEX-LABEL: 
FilenameFunction CoverageLine CoverageRegion Coverage -// HTML-INDEX: 100.00% (1/1) -// HTML-INDEX: -// HTML-INDEX: 90.00% (18/20) -// HTML-INDEX: -// HTML-INDEX: 72.73% (8/11) -// HTML-INDEX:
+// HTML-INDEX: +// HTML-INDEX: +// HTML-INDEX: +// HTML-INDEX: +// HTML-INDEX: +// HTML-INDEX: +// HTML-INDEX: Totals From c50c492964a9239fc9e07ffe4a56bdbd4bf17aa8 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 20 Nov 2024 23:34:04 +0900 Subject: [PATCH 06/35] Introduce test/llvm-cov/Inputs/yaml.makefile for convenience. --- llvm/test/tools/llvm-cov/Inputs/yaml.makefile | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 llvm/test/tools/llvm-cov/Inputs/yaml.makefile diff --git a/llvm/test/tools/llvm-cov/Inputs/yaml.makefile b/llvm/test/tools/llvm-cov/Inputs/yaml.makefile new file mode 100644 index 0000000000000..2a256f0cffc0b --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/yaml.makefile @@ -0,0 +1,96 @@ +# This is for developers' convenience and not expected to be in build steps. +# +# Usage: +# cd /path/to/llvm-project/llvm/test/tools/llvm-cov/Inputs +# PATH=/path/to/build/bin:$PATH make -f yaml.makefile + +CFLAGS_COVMAP = -fcoverage-compilation-dir=. \ + -mllvm -runtime-counter-relocation=true \ + -mllvm -conditional-counter-update=true \ + -mllvm -enable-name-compression=false \ + -fprofile-instr-generate -fcoverage-mapping \ + $(if $(filter mcdc-%, $*), $(CFLAGS_MCDC)) + +CFLAGS_MCDC = -fcoverage-mcdc + +%.o: %.cpp + clang++ $< -c -o $@ $(CFLAGS_COVMAP) + +%.o: %.c + clang $< -c -o $@ $(CFLAGS_COVMAP) + +%-single.o: %.cpp + clang++ $< -c -o $@ \ + -mllvm -enable-single-byte-coverage=true \ + $(CFLAGS_COVMAP) + +%-single.o: %.c + clang $< -c -o $@ \ + -mllvm -enable-single-byte-coverage=true \ + $(CFLAGS_COVMAP) + +%.covmap.o: %.o + llvm-objcopy \ + --only-section=__llvm_covfun \ + --only-section=__llvm_covmap \ + --only-section=__llvm_prf_names \ + --strip-unneeded \ + $< $@ + +%.yaml: %.covmap.o + obj2yaml $< > $@ + +%.exe: %.o + clang++ -fprofile-instr-generate $^ -o $@ + +ARGS_branch-logical-mixed := \ + 0 0; \ + 0 1; \ + 1 0; \ + 1 1 + +ARGS_branch-macros := \ + 0 1; \ + 1 0; \ + 1 1 + +ARGS_branch-showBranchPercentage := \ + 0 1; \ + 1 1; \ + 2 2; \ + 4 0; \ + 5 0; \ + 1 + +ARGS_showLineExecutionCounts := $(patsubst %,%;,$(shell seq 161)) + +ARGS_mcdc-const-folding := \ + 0 1; \ + 1 0; \ + 1 1; \ + 1 1 + +%.profdata: %.exe + -find -name '$*.*.profraw' | xargs rm -fv + @if [ "$(ARGS_$(patsubst %-single,%,$*))" = "" ]; then \ + echo "Executing: $<"; \ + LLVM_PROFILE_FILE=$*.%p%c.profraw ./$<; \ + else \ + LLVM_PROFILE_FILE=$*.%p%c.profraw; \ + export LLVM_PROFILE_FILE; \ + for xcmd in $(shell echo "$(ARGS_$(patsubst %-single,%,$*))" | tr ';[:blank:]' ' %'); do \ + cmd=$$(echo "$$xcmd" | tr '%' ' '); \ + echo "Executing series: $< $$cmd"; \ + eval "./$< $$cmd"; \ + done; \ + fi + find -name '$*.*.profraw' | xargs llvm-profdata merge --sparse -o $@ + +%.proftext: %.profdata + llvm-profdata merge --text -o $@ $< + +.PHONY: all +all: \ + $(patsubst %.yaml,%.proftext, $(wildcard *.yaml)) \ + $(wildcard *.yaml) + -find -name '*.profraw' | xargs rm -f From d7c5b4404c48a6b02ddffc331849335580e16b9b Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 20 Nov 2024 23:34:16 +0900 Subject: [PATCH 07/35] Add tests for SingleByteCoverage --- .../Inputs/branch-c-general-single.proftext | 297 ++++++++++++++++++ .../Inputs/branch-c-general-single.yaml | 177 +++++++++++ .../tools/llvm-cov/Inputs/branch-c-general.c | 202 ++++++------ .../branch-logical-mixed-single.proftext | 84 +++++ .../Inputs/branch-logical-mixed-single.yaml | 57 ++++ .../llvm-cov/Inputs/branch-logical-mixed.cpp | 86 ++--- .../Inputs/branch-macros-single.proftext | 53 ++++ .../llvm-cov/Inputs/branch-macros-single.yaml | 69 ++++ .../tools/llvm-cov/Inputs/branch-macros.cpp | 46 +-- .../Inputs/branch-showBranchPercentage.c | 6 +- .../Inputs/branch-templates-single.proftext | 49 +++ .../Inputs/branch-templates-single.yaml | 81 +++++ .../llvm-cov/Inputs/branch-templates.cpp | 22 +- .../showLineExecutionCounts-single.proftext | 23 ++ .../showLineExecutionCounts-single.yaml | 45 +++ .../Inputs/showLineExecutionCounts.cpp | 40 +-- .../test/tools/llvm-cov/branch-c-general.test | 4 + .../tools/llvm-cov/branch-logical-mixed.test | 8 +- llvm/test/tools/llvm-cov/branch-macros.test | 6 +- .../test/tools/llvm-cov/branch-templates.test | 4 + .../llvm-cov/showLineExecutionCounts.test | 7 + 21 files changed, 1163 insertions(+), 203 deletions(-) create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.proftext create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-macros-single.proftext create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-templates-single.proftext create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml create mode 100644 llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext create mode 100644 llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext new file mode 100644 index 0000000000000..ea8c6f9bc634e --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext @@ -0,0 +1,297 @@ +# Instrument block coverage +:single_byte_coverage +big_switch +# Func Hash: +13144136522122330070 +# Num Counters: +27 +# Counter Values: +1 +1 +1 +1 +1 +1 +1 +0 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 + +boolean_operators +# Func Hash: +1245693242827665 +# Num Counters: +17 +# Counter Values: +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 + +boolop_loops +# Func Hash: +12402604614320574815 +# Num Counters: +23 +# Counter Values: +1 +0 +1 +1 +1 +1 +0 +1 +1 +1 +1 +0 +1 +1 +1 +1 +1 +0 +1 +1 +1 +1 +1 + +branch-c-general.c:static_func +# Func Hash: +18129 +# Num Counters: +5 +# Counter Values: +1 +1 +1 +1 +1 + +conditional_operator +# Func Hash: +54992 +# Num Counters: +5 +# Counter Values: +1 +1 +0 +1 +1 + +conditionals +# Func Hash: +4904767535850050386 +# Num Counters: +25 +# Counter Values: +1 +1 +1 +1 +1 +1 +0 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 + +do_fallthrough +# Func Hash: +8714614136504380050 +# Num Counters: +10 +# Counter Values: +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 + +early_exits +# Func Hash: +2880354649761471549 +# Num Counters: +20 +# Counter Values: +1 +0 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +0 +1 +1 +1 +0 +0 + +jumps +# Func Hash: +15051420506203462683 +# Num Counters: +38 +# Counter Values: +1 +1 +0 +1 +0 +0 +0 +1 +0 +1 +1 +0 +1 +1 +0 +1 +1 +1 +1 +1 +1 +1 +0 +1 +1 +0 +1 +1 +1 +1 +1 +1 +1 +0 +0 +1 +1 +1 + +main +# Func Hash: +24 +# Num Counters: +1 +# Counter Values: +1 + +simple_loops +# Func Hash: +1245818015463121 +# Num Counters: +11 +# Counter Values: +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 + +switches +# Func Hash: +43242458792028222 +# Num Counters: +29 +# Counter Values: +1 +1 +1 +1 +1 +1 +0 +1 +1 +0 +1 +1 +1 +1 +1 +1 +1 +1 +1 +1 +0 +1 +1 +1 +1 +1 +1 +0 +0 + diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml new file mode 100644 index 0000000000000..9d23dcb67ad2a --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml @@ -0,0 +1,177 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 + SectionHeaderStringTable: .strtab +Sections: + - Name: __llvm_covfun + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: D7878914FBE99B074D000000D136449C106D04004C551E9517F40F4F0101000D010715080205020F0016090018001B0D001C009D808080080D001D0104110203040215000A000F19001001858080800819010500081D01030202210006000825001000181001010001 + - Name: '__llvm_covfun (1)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 83AD05A5F1438E68EA00000052D33558163C11444C551E9517F40F4F010100260111150E02050113001A09001C001F0D002000A1808080080D00210B040D0109000E15000F009080808008150010020615010B000C21000D008E8080800821000E0010310106008C8080800831000C04063100100015290016009780808008290017020629010B000C35000D008E8080800835000E00102D0106008C808080082D000C02062D010B000C3D000D008E808080083D000E0010100201005B1D010502041D0009000A1D0009000F4D000E000F45001000918080800845001100134901050104490009000A490009000F5D000E000F55001000918080800855001100131002010001 + - Name: '__llvm_covfun (2)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 0449C70428C57369F80000003D5C2D0E4B13F9274C551E9517F40F4F01010028012114180210020100010101070008050009008A8080800805000A000C100101000109010313020D000A00111100120093808080081100130604110209000F190010018780808008190107000C1D000D0185808080081D010502041D0009000E21000F018780808008210107000F15010402838080800810010100011501030B021500070008290009008A8080800829000A000C10010100012D010309023100060504310109000F3D00100187808080083D0107000D41000E028780808008410207000A35010C0013390015028380808008100101000139010302023900070008490009008A8080800849000A000C1001010001 + - Name: '__llvm_covfun (3)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 55947829059F255EB80100001B9C495D3463E1D04C551E9517F40F4F01010046013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A15000B008C8080800815000C000E11010402818080800810010100011D010126021D01070008210009008A8080800821000A000C1001010001250103000D25000E0283808080081001010001000103210229000A000B2D000C008D808080082D000D03043501030204350109000A39000B008C8080800839000C000E1002010001310103000D31000E0181808080084101011B024501011A024901011902490207000C4D000D0185808080084D0105000F5100100283808080081001010001510103140255000A000F5900100091808080085900110A04610103090400011006918080800869010501110001120185808080086D0105011200011301858080800871010501115D030402838080800810010100015D0103080275000F0015790017001A7D001B009C808080087D001C0604000115028580808008100101003F0001050304000009000A8501000B008C808080088501000C000E8D01010302048D010109000A9101000B008C808080089101000C000E1002010001 + - Name: '__llvm_covfun (4)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 7129CA3C268292BF4D0100003E688383C9A099004C551E9517F40F4F01010035016C112502100201011C000217028A80808008090103010A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F21010B000C25000D008E8080800825000E001010010100152D0105100F2D010B000C31000D008E8080800831000E0010350107000C35000D0185808080083901050D0F39010B000C3D000D008E808080083D000E0010410107000F4100100185808080084501050A0F45010B000C49000D008E8080800849000E00104D0107080F000012039180808008550107021155010D000E59000F00908080800859001000125D010900115101080285808080081001010001610105020F61010B0017650018018980808008650109000F1902040383808080081001010121190203020219000700116D00120093808080086D001300151001010001 + - Name: '__llvm_covfun (5)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 3F4D1C6E6087417B32010000D6FF56B8865A69B64C551E9517F40F4F01010031019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C19010B000C1D000D008E808080081D000E00101001010015250105150C25010B000C29000D008E8080800829000E00102D0107000C2D000D018580808008310105120C31010B000C35000D008E8080800835000E0010390107000C39000D03858080800810010101013D02050D0C3D010B000C41000D008E8080800841000E0010450107000C45000D0185808080084901050A0C49010B000C4D000D008E808080084D000E0010510107000C51000D0385808080081001010101550205050C55010B000C59000D008E8080800859000E00105D0107000C5D000D018580808008610105020C61010B000C65000D008E8080800865000E0010690107000C1003010001 + - Name: '__llvm_covfun (6)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 59A48AA8899AA3587200000091E33C8FF36C04004C551E9517F40F4F0101001501B4011A0C02050213001A09001C001F0D002000A1808080080D002108040D0109000E1500120013100101005D0D0109000E1D00120013100101005D0D0109000E0D000900172D0012001725001B001C10010100630D0109000E0D000900173D0012001735001B001C1002010063 + - Name: '__llvm_covfun (7)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: F5953D044B505D139E0000005FD132562FE71EAC4C551E9517F40F4F0101001D01C201150D02100201000111010A000B11000A001511000F0015090016018580808008090105000810010100010D0103070225000A001125000A001C250015001C1D001D0185808080081D01050008100101000121010304023D001100123D0011001C3D0016001C31001E002135002200231001010061390103020255000A001155000A001C550015001C49001E00214D002200231001010061 + - Name: '__llvm_covfun (8)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 20E5C369BDF15C7940000000D0D60000000000004C551E9517F40F4F0101000B01D1011D0702100201000101010B001109001300948080800809001400150D001800191001010001050103020205000B000C01001000111001010001 + - Name: '__llvm_covfun (9)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 7DE8E7C47096EB425200000092EAF0986287F0784C551E9517F40F4F0101000D01DA01170B02050113001909001B001E0D001F00A0808080080D002009041502080606100101024D15030B00102100110092808080082100120017250018018780808008250107010619010E0013 + - Name: '__llvm_covfun (10)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: FAD58DE7366495DB0A00000018000000000000004C551E9517F40F4F0101000101F501280F02 + - Name: '__llvm_covfun (11)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 4CB4F49D6737EBF922000000D1460000000000004C551E9517F40F4F0101000501E7011B0302050113001909001B001E0D001F00A0808080080D00200104 + - Name: __llvm_covmap + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 0000000017000000000000000600000002140000126272616E63682D632D67656E6572616C2E6300 + - Name: __llvm_prf_names + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] + AddressAlign: 0x1 + Content: A6010073696D706C655F6C6F6F707301636F6E646974696F6E616C73016561726C795F6578697473016A756D7073017377697463686573016269675F73776974636801626F6F6C65616E5F6F70657261746F727301626F6F6C6F705F6C6F6F707301636F6E646974696F6E616C5F6F70657261746F7201646F5F66616C6C7468726F756768016D61696E016272616E63682D632D67656E6572616C2E633A7374617469635F66756E63 + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: __llvm_covfun + - Name: '__llvm_covfun (1)' + - Name: '__llvm_covfun (2)' + - Name: '__llvm_covfun (3)' + - Name: '__llvm_covfun (4)' + - Name: '__llvm_covfun (5)' + - Name: '__llvm_covfun (6)' + - Name: '__llvm_covfun (7)' + - Name: '__llvm_covfun (8)' + - Name: '__llvm_covfun (9)' + - Name: '__llvm_covfun (10)' + - Name: '__llvm_covfun (11)' + - Name: __llvm_covmap + - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_79BE9FB148987D7u + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0x69 + Other: [ STV_HIDDEN ] + - Name: __covrec_688E43F1A505AD83u + Type: STT_OBJECT + Section: '__llvm_covfun (1)' + Binding: STB_WEAK + Size: 0x106 + Other: [ STV_HIDDEN ] + - Name: __covrec_6973C52804C74904u + Type: STT_OBJECT + Section: '__llvm_covfun (2)' + Binding: STB_WEAK + Size: 0x114 + Other: [ STV_HIDDEN ] + - Name: __covrec_5E259F0529789455u + Type: STT_OBJECT + Section: '__llvm_covfun (3)' + Binding: STB_WEAK + Size: 0x1D4 + Other: [ STV_HIDDEN ] + - Name: __covrec_BF9282263CCA2971u + Type: STT_OBJECT + Section: '__llvm_covfun (4)' + Binding: STB_WEAK + Size: 0x169 + Other: [ STV_HIDDEN ] + - Name: __covrec_7B4187606E1C4D3Fu + Type: STT_OBJECT + Section: '__llvm_covfun (5)' + Binding: STB_WEAK + Size: 0x14E + Other: [ STV_HIDDEN ] + - Name: __covrec_58A39A89A88AA459u + Type: STT_OBJECT + Section: '__llvm_covfun (6)' + Binding: STB_WEAK + Size: 0x8E + Other: [ STV_HIDDEN ] + - Name: __covrec_135D504B043D95F5u + Type: STT_OBJECT + Section: '__llvm_covfun (7)' + Binding: STB_WEAK + Size: 0xBA + Other: [ STV_HIDDEN ] + - Name: __covrec_795CF1BD69C3E520u + Type: STT_OBJECT + Section: '__llvm_covfun (8)' + Binding: STB_WEAK + Size: 0x5C + Other: [ STV_HIDDEN ] + - Name: __covrec_42EB9670C4E7E87Du + Type: STT_OBJECT + Section: '__llvm_covfun (9)' + Binding: STB_WEAK + Size: 0x6E + Other: [ STV_HIDDEN ] + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: '__llvm_covfun (10)' + Binding: STB_WEAK + Size: 0x26 + Other: [ STV_HIDDEN ] + - Name: __covrec_F9EB37679DF4B44Cu + Type: STT_OBJECT + Section: '__llvm_covfun (11)' + Binding: STB_WEAK + Size: 0x3E + Other: [ STV_HIDDEN ] +... diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c index 2e7e773e5c394..5ea9ecb42b0ed 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c @@ -4,75 +4,75 @@ -void simple_loops() { +void simple_loops() { // CHECK: @LINE|{{.*}}simple_loops() int i; - for (i = 0; i < 100; ++i) { + for (i = 0; i < 100; ++i) { // BRCOV: Branch ([[@LINE]]:15): [True: [[C100:100|1]], False: 1] } - while (i > 0) + while (i > 0) // BRCOV: Branch ([[@LINE]]:10): [True: [[C100]], False: 1] i--; - do {} while (i++ < 75); + do {} while (i++ < 75); // BRCOV: Branch ([[@LINE]]:16): [True: [[C75:75|1]], False: 1] } -void conditionals() { - for (int i = 0; i < 100; ++i) { - if (i % 2) { - if (i) {} - } else if (i % 3) { - if (i) {} +void conditionals() { // CHECK: @LINE|{{.*}}conditionals() + for (int i = 0; i < 100; ++i) {//BRCOV: Branch ([[@LINE]]:19): [True: [[C100]], False: 1] + if (i % 2) { // BRCOV: Branch ([[@LINE]]:9): [True: [[C50:50|1]], False: [[C50]]] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C50]], False: 0] + } else if (i % 3) { // BRCOV: Branch ([[@LINE]]:16): [True: [[C33:33|1]], False: [[C17:17|1]]] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C33]], False: 0] } else { - if (i) {} + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C16:16|1]], False: 1] } - - if (1 && i) {} - if (0 || i) {} - } + // BRCOV: Branch ([[@LINE+1]]:9): [True: [[C100]], Folded] + if (1 && i) {} // BRCOV: Branch ([[@LINE]]:14): [True: [[C99:99|1]], False: 1] + if (0 || i) {} // BRCOV: Branch ([[@LINE]]:9): [Folded, False: [[C100]]] + } // BRCOV: Branch ([[@LINE-1]]:14): [True: [[C99]], False: 1] } -void early_exits() { +void early_exits() { // CHECK: @LINE|{{.*}}early_exits() int i = 0; - if (i) {} + if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 1] - while (i < 100) { + while (i < 100) { // BRCOV: Branch ([[@LINE]]:10): [True: [[C51:51|1]], False: 0] i++; - if (i > 50) + if (i > 50) // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[C50]]] break; - if (i % 2) + if (i % 2) // BRCOV: Branch ([[@LINE]]:9): [True: [[C25:25|1]], False: [[C25]]] continue; } - if (i) {} + if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 1, False: 0] do { - if (i > 75) + if (i > 75) // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[C25]]] return; else i++; - } while (i < 100); + } while (i < 100); // BRCOV: Branch ([[@LINE]]:12): [True: [[C25]], False: 0] - if (i) {} + if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 0] } -void jumps() { +void jumps() { // CHECK: @LINE|{{.*}}jumps() int i; - for (i = 0; i < 2; ++i) { + for (i = 0; i < 2; ++i) { // BRCOV: Branch ([[@LINE]]:15): [True: 1, False: 0] goto outofloop; // Never reached -> no weights - if (i) {} + if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 0] } outofloop: - if (i) {} + if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 1] goto loop1; - while (i) { + while (i) { // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1] loop1: - if (i) {} + if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 1] } goto loop2; @@ -80,143 +80,143 @@ void jumps() { second: third: i++; - if (i < 3) + if (i < 3) // BRCOV: Branch ([[@LINE]]:7): [True: [[C2:2|1]], False: 1] goto loop2; - while (i < 3) { + while (i < 3) { // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1] loop2: switch (i) { - case 0: + case 0: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] goto first; - case 1: + case 1: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] goto second; - case 2: + case 2: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] goto third; } } - for (i = 0; i < 10; ++i) { + for (i = 0; i < 10; ++i) { // BRCOV: Branch ([[@LINE]]:15): [True: [[C10:10|1]], False: 1] goto withinloop; - // never reached -> no weights - if (i) {} + // never reached -> no weights + if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 0] withinloop: - if (i) {} + if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: [[C9:9|1]], False: 1] } } -void switches() { +void switches() { // CHECK: @LINE|{{.*}}switches() static int weights[] = {1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5}; // No cases -> no weights switch (weights[0]) { - default: + default: // BRCOV: Branch ([[@LINE]]:3): [True: 1, Folded] break; } - + // BRCOV: Branch ([[@LINE+1]]:63): [True: [[C15:15|1]], False: 0] for (int i = 0, len = sizeof(weights) / sizeof(weights[0]); i < len; ++i) { switch (i[weights]) { - case 1: - if (i) {} + case 1: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1] // fallthrough - case 2: - if (i) {} + case 2: // BRCOV: Branch ([[@LINE]]:5): [True: [[C2]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C2]], False: 1] break; - case 3: - if (i) {} + case 3: // BRCOV: Branch ([[@LINE]]:5): [True: [[C3:3|1]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C3]], False: 0] continue; - case 4: - if (i) {} + case 4: // BRCOV: Branch ([[@LINE]]:5): [True: [[C4:4|1]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C4]], False: 0] switch (i) { - case 6 ... 9: - if (i) {} + case 6 ... 9: // BRCOV: Branch ([[@LINE]]:7): [True: [[C4]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:13): [True: [[C4]], False: 0] continue; } - default: - if (i == len - 1) + default: // BRCOV: Branch ([[@LINE]]:5): [True: [[C5:5|1]], Folded] + if (i == len - 1) // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: [[C4]]] return; } } // Never reached -> no weights - if (weights[0]) {} + if (weights[0]) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 0] } -void big_switch() { - for (int i = 0; i < 32; ++i) { +void big_switch() { // CHECK: @LINE|{{.*}}big_switch() + for (int i = 0; i < 32; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[C32:32|1]], False: 1] switch (1 << i) { - case (1 << 0): - if (i) {} + case (1 << 0): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1] // fallthrough - case (1 << 1): - if (i) {} + case (1 << 1): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 1] break; - case (1 << 2) ... (1 << 12): - if (i) {} + case (1 << 2) ... (1 << 12):// BRCOV: Branch ([[@LINE]]:5): [True: [[C11:11|1]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C11]], False: 0] break; // The branch for the large case range above appears after the case body. - case (1 << 13): - if (i) {} + case (1 << 13): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0] break; - case (1 << 14) ... (1 << 28): - if (i) {} + case (1 << 14) ... (1 << 28)://BRCOV: Branch ([[@LINE]]:5): [True: [[C15]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C15]], False: 0] break; // The branch for the large case range above appears after the case body. case (1 << 29) ... ((1 << 29) + 1): - if (i) {} + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0] break; - default: - if (i) {} + default: // BRCOV: Branch ([[@LINE]]:5): [True: [[C2]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C2]], False: 0] break; } } } -void boolean_operators() { +void boolean_operators() { // CHECK: @LINE|{{.*}}boolean_operators() int v; for (int i = 0; i < 100; ++i) { - v = i % 3 || i; - - v = i % 3 && i; - - v = i % 3 || i % 2 || i; - - v = i % 2 && i % 3 && i; - } - -} - -void boolop_loops() { + v = i % 3 || i; // BRCOV: Branch ([[@LINE]]:9): [True: [[C66:66|1]], False: [[C34:34|1]]] + // BRCOV: Branch ([[@LINE-1]]:18): [True: [[C33]], False: 1] + v = i % 3 && i; // BRCOV: Branch ([[@LINE]]:9): [True: [[C66]], False: [[C34]]] + // BRCOV: Branch ([[@LINE-1]]:18): [True: [[C66]], False: 0] + v = i % 3 || i % 2 || i; // BRCOV: Branch ([[@LINE]]:9): [True: [[C66]], False: [[C34]]] + // BRCOV: Branch ([[@LINE-1]]:18): [True: [[C17]], False: [[C17]]] + v = i % 2 && i % 3 && i; // BRCOV: Branch ([[@LINE-2]]:27): [True: [[C16]], False: 1] + } // BRCOV: Branch ([[@LINE-1]]:9): [True: [[C50]], False: [[C50]]] + // BRCOV: Branch ([[@LINE-2]]:18): [True: [[C33]], False: [[C17]]] +} // BRCOV: Branch ([[@LINE-3]]:27): [True: [[C33]], False: 0] + +void boolop_loops() { // CHECK: @LINE|{{.*}}boolop_loops() int i = 100; - while (i && i > 50) - i--; - - while ((i % 2) || (i > 0)) - i--; - - for (i = 100; i && i > 50; --i); + while (i && i > 50) // BRCOV: Branch ([[@LINE]]:10): [True: [[C51]], False: 0] + i--; // BRCOV: Branch ([[@LINE-1]]:15): [True: [[C50]], False: 1] - for (; (i % 2) || (i > 0); --i); + while ((i % 2) || (i > 0)) // BRCOV: Branch ([[@LINE]]:10): [True: [[C25]], False: [[C26:26|1]]] + i--; // BRCOV: Branch ([[@LINE-1]]:21): [True: [[C25]], False: 1] + for (i = 100; i && i > 50; --i); // BRCOV: Branch ([[@LINE]]:17): [True: [[C51]], False: 0] + // BRCOV: Branch ([[@LINE-1]]:22): [True: [[C50]], False: 1] + for (; (i % 2) || (i > 0); --i); // BRCOV: Branch ([[@LINE]]:10): [True: [[C25]], False: [[C26]]] + // BRCOV: Branch ([[@LINE-1]]:21): [True: [[C25]], False: 1] } -void conditional_operator() { +void conditional_operator() { // CHECK: @LINE|{{.*}}conditional_operator() int i = 100; - int j = i < 50 ? i : 1; + int j = i < 50 ? i : 1; // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1] - int k = i ?: 0; + int k = i ?: 0; // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0] } -void do_fallthrough() { - for (int i = 0; i < 10; ++i) { +void do_fallthrough() { // CHECK: @LINE|{{.*}}do_fallthrough() + for (int i = 0; i < 10; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[C10]], False: 1] int j = 0; do { // The number of exits out of this do-loop via the break statement @@ -224,12 +224,12 @@ void do_fallthrough() { // fallthrough count). Make sure that does not violate any assertions. if (i < 8) break; j++; - } while (j < 2); + } while (j < 2); // BRCOV: Branch ([[@LINE]]:14): [True: [[C2]], False: [[C2]]] } } -static void static_func() { - for (int i = 0; i < 10; ++i) { +static void static_func() { // CHECK: @LINE|{{.*}}static_func() + for (int i = 0; i < 10; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[C10]], False: 1] } } @@ -254,7 +254,7 @@ int main(int argc, const char *argv[]) { conditional_operator(); do_fallthrough(); static_func(); - extern void __llvm_profile_write_file(); - __llvm_profile_write_file(); + (void)0; + (void)0; return 0; } diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.proftext b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.proftext new file mode 100644 index 0000000000000..f9662438de0e6 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.proftext @@ -0,0 +1,84 @@ +# Instrument block coverage +:single_byte_coverage +_Z4funcii +# Func Hash: +8468630735863722633 +# Num Counters: +67 +# Counter Values: +4 +0 +0 +0 +0 +2 +0 +2 +2 +3 +2 +0 +0 +0 +0 +0 +0 +1 +0 +1 +1 +3 +3 +3 +3 +3 +3 +1 +2 +0 +3 +0 +0 +0 +1 +0 +1 +0 +3 +3 +3 +3 +4 +1 +0 +2 +1 +0 +0 +3 +0 +2 +0 +2 +0 +0 +4 +4 +4 +0 +4 +1 +3 +4 +3 +1 +4 + +main +# Func Hash: +24 +# Num Counters: +1 +# Counter Values: +4 + diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml new file mode 100644 index 0000000000000..56f3d4955f4d9 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml @@ -0,0 +1,57 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 + SectionHeaderStringTable: .strtab +Sections: + - Name: __llvm_covfun + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: F0A0ED2C305C0BB32D02000089B21C19C99E86758F2950E06FBD46E8010100600108194302100701000101010C000E01000C010E01000C020E01000C030E01000C040E25010C000E1D010C000E15010C000E0D010C000E05010C000E100101000101010C000E01000C010E01000C020E01000C030E01000C040E4D010C000E45010C000E3D010C000E35010C000E2D010C000E100101000101010C011001000C031001000C051001000C071001000C091001000D000F69010D000F65010C011065000D000F71010D000F61010C011061000D000F79010D000F5D010C01105D000D000F8101010D000F59010C011059000D000F8901010D000F55010C011055000D000F9101010D000F100101000101010C011001000C031001000C051001000C071001000C091001000D000FAD01010D000FA901010C0110A901000D000FB501010D000FA501010C0110A501000D000FBD01010D000FA101010C0110A101000D000FC501010D000F9D01010C01109D01000D000FCD01010D000F9901010C01109901000D000FD501010D000F10010100010101070008DD010009018580808008DD0101050016E1010017028580808008E101020500161001010001E50101030E02E50100070008E9010009018580808008E90101050016ED010017028580808008ED01020500161001010001F10101030902F10100070008F5010009018580808008F50101050016F9010017028580808008F901020500161001010001FD0101030402FD01000700088102000901858080800881020105001685020017028580808008850202050016 + - Name: '__llvm_covfun (1)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: FAD58DE7366495DB0900000018000000000000008F2950E06FBD46E801010001014F010402 + - Name: __llvm_covmap + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 000000001D0000000000000006000000021A0000186272616E63682D6C6F676963616C2D6D697865642E637070000000 + - Name: __llvm_prf_names + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] + AddressAlign: 0x1 + Content: 0E005F5A3466756E636969016D61696E + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: __llvm_covfun + - Name: '__llvm_covfun (1)' + - Name: __llvm_covmap + - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_B30B5C302CEDA0F0u + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0x249 + Other: [ STV_HIDDEN ] + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: '__llvm_covfun (1)' + Binding: STB_WEAK + Size: 0x25 + Other: [ STV_HIDDEN ] +... diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp index 0a7d8d8967115..0eaf4c963ef9f 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp @@ -4,7 +4,7 @@ #include #include - +// CHECK: |{{ +}}[[C4:4|1]]|void func( void func(int a, int b) { bool b0 = a <= b; bool b1 = a == b; @@ -13,71 +13,71 @@ void func(int a, int b) { bool b4 = a > b; bool b5 = a != b; - bool c = b0 && // CHECK: Branch ([[@LINE]]:12): [True: 3, False: 1] - b1 && // CHECK: Branch ([[@LINE]]:12): [True: 2, False: 1] - b2 && // CHECK: Branch ([[@LINE]]:12): [True: 2, False: 0] - b3 && // CHECK: Branch ([[@LINE]]:12): [True: 0, False: 2] - b4 && // CHECK: Branch ([[@LINE]]:12): [True: 0, False: 0] - b5; // CHECK: Branch ([[@LINE]]:12): [True: 0, False: 0] + bool c = b0 && // BRCOV: Branch ([[@LINE]]:12): [True: [[C3:3|1]], False: 1] + b1 && // BRCOV: Branch ([[@LINE]]:12): [True: [[C2:2|1]], False: 1] + b2 && // BRCOV: Branch ([[@LINE]]:12): [True: [[C2]], False: 0] + b3 && // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: [[C2]]] + b4 && // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] + b5; // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] - bool d = b0 || // CHECK: Branch ([[@LINE]]:12): [True: 3, False: 1] - b1 || // CHECK: Branch ([[@LINE]]:12): [True: 0, False: 1] - b2 || // CHECK: Branch ([[@LINE]]:12): [True: 1, False: 0] - b3 || // CHECK: Branch ([[@LINE]]:12): [True: 0, False: 0] - b4 || // CHECK: Branch ([[@LINE]]:12): [True: 0, False: 0] - b5; // CHECK: Branch ([[@LINE]]:12): [True: 0, False: 0] + bool d = b0 || // BRCOV: Branch ([[@LINE]]:12): [True: [[C3]], False: 1] + b1 || // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 1] + b2 || // BRCOV: Branch ([[@LINE]]:12): [True: 1, False: 0] + b3 || // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] + b4 || // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] + b5; // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] - bool e = (b0 && // CHECK: Branch ([[@LINE]]:13): [True: 3, False: 1] - b5) || // CHECK: Branch ([[@LINE]]:13): [True: 1, False: 2] - (b1 && // CHECK: Branch ([[@LINE]]:13): [True: 2, False: 1] - b4) || // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 2] - (b2 && // CHECK: Branch ([[@LINE]]:13): [True: 3, False: 0] - b3) || // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 3] - (b3 && // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 3] - b2) || // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 0] - (b4 && // CHECK: Branch ([[@LINE]]:13): [True: 1, False: 2] - b1) || // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 1] - (b5 && // CHECK: Branch ([[@LINE]]:13): [True: 1, False: 2] - b0); // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 1] + bool e = (b0 && // BRCOV: Branch ([[@LINE]]:13): [True: [[C3]], False: 1] + b5) || // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + (b1 && // BRCOV: Branch ([[@LINE]]:13): [True: [[C2]], False: 1] + b4) || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[C2]]] + (b2 && // BRCOV: Branch ([[@LINE]]:13): [True: [[C3]], False: 0] + b3) || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[C3]]] + (b3 && // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[C3]]] + b2) || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: 0] + (b4 && // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + b1) || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: 1] + (b5 && // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + b0); // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: 1] - bool f = (b0 || // CHECK: Branch ([[@LINE]]:13): [True: 3, False: 1] - b5) && // CHECK: Branch ([[@LINE]]:13): [True: 1, False: 0] - (b1 || // CHECK: Branch ([[@LINE]]:13): [True: 2, False: 2] - b4) && // CHECK: Branch ([[@LINE]]:13): [True: 1, False: 1] - (b2 || // CHECK: Branch ([[@LINE]]:13): [True: 3, False: 0] - b3) && // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 0] - (b3 || // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 3] - b2) && // CHECK: Branch ([[@LINE]]:13): [True: 3, False: 0] - (b4 || // CHECK: Branch ([[@LINE]]:13): [True: 1, False: 2] - b1) && // CHECK: Branch ([[@LINE]]:13): [True: 2, False: 0] - (b5 || // CHECK: Branch ([[@LINE]]:13): [True: 1, False: 2] - b0); // CHECK: Branch ([[@LINE]]:13): [True: 2, False: 0] + bool f = (b0 || // BRCOV: Branch ([[@LINE]]:13): [True: [[C3]], False: 1] + b5) && // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: 0] + (b1 || // BRCOV: Branch ([[@LINE]]:13): [True: [[C2]], False: [[C2]]] + b4) && // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: 1] + (b2 || // BRCOV: Branch ([[@LINE]]:13): [True: [[C3]], False: 0] + b3) && // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: 0] + (b3 || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[C3]]] + b2) && // BRCOV: Branch ([[@LINE]]:13): [True: [[C3]], False: 0] + (b4 || // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + b1) && // BRCOV: Branch ([[@LINE]]:13): [True: [[C2]], False: 0] + (b5 || // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + b0); // BRCOV: Branch ([[@LINE]]:13): [True: [[C2]], False: 0] - if (c) // CHECK: Branch ([[@LINE]]:7): [True: 0, False: 4] + if (c) // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: [[C4]]] printf("case0\n"); else printf("case1\n"); - if (d) // CHECK: Branch ([[@LINE]]:7): [True: 4, False: 0] + if (d) // BRCOV: Branch ([[@LINE]]:7): [True: [[C4]], False: 0] printf("case2\n"); else printf("case3\n"); - if (e) // CHECK: Branch ([[@LINE]]:7): [True: 1, False: 3] + if (e) // BRCOV: Branch ([[@LINE]]:7): [True: 1, False: [[C3]]] printf("case4\n"); else printf("case5\n"); - if (f) // CHECK: Branch ([[@LINE]]:7): [True: 3, False: 1] + if (f) // BRCOV: Branch ([[@LINE]]:7): [True: [[C3]], False: 1] printf("case6\n"); else printf("case7\n"); } -extern "C" { extern void __llvm_profile_write_file(void); } + int main(int argc, char *argv[]) { func(atoi(argv[1]), atoi(argv[2])); - __llvm_profile_write_file(); + (void)0; return 0; } diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.proftext b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.proftext new file mode 100644 index 0000000000000..afb4b1038d3f8 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.proftext @@ -0,0 +1,53 @@ +# Instrument block coverage +:single_byte_coverage +_Z4funcii +# Func Hash: +456046650042366162 +# Num Counters: +19 +# Counter Values: +3 +1 +0 +1 +0 +1 +0 +1 +0 +1 +0 +0 +0 +0 +0 +0 +0 +0 +0 + +_Z5func2ii +# Func Hash: +14151920320560143107 +# Num Counters: +10 +# Counter Values: +3 +3 +2 +1 +0 +3 +0 +3 +1 +0 + +main +# Func Hash: +24 +# Num Counters: +1 +# Counter Values: +3 + diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml new file mode 100644 index 0000000000000..5c5f62b11863b --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml @@ -0,0 +1,69 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 + SectionHeaderStringTable: .strtab +Sections: + - Name: __llvm_covfun + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: F0A0ED2C305C0BB33F010000D238C8100334540693E696313ECE8F5D15010101010101010101010101010101010101010101001501101911020C010C0011140015001A100101005C1C010C0011100101006224010C001210010100682C010C0012100101006E34010C0012100101007401010A000B01000A001001000A001501000A001A45000F00103D00140015350019001A2D001E001F10010104550201050F001701000F00170105060F00170301070F001F3C00100015440019001E014C0910001501540A100016015C0B1000160201050F001701000F0017010D060F00170301070F001F64001000156C0019001E017409100015017C0A1000160201050F001701000F00170115060F00170301070F001F8401001000158C010019001E019401091000150201050F001701000F0017011D060F00170301070F001F9C0100100015A4010019001E0201050F001701000F00170125060F0017 + - Name: '__llvm_covfun (1)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: B01D983FC67363959E000000039B9E2C8DB865C493E696313ECE8F5D0D01010101010101010101010101000401241A07020C010E0014140018001D1001010365011C0B1000160405080F002624001000152C0018001D3400200025013C0A1000160305070F001F44001000154C0019001E0119060F0017011D050F00170154091000150205050F001705000F00170121060F00170401070F001F01000F001F5C00100015640019001E0201050F001701000F0017010D060F0017 + - Name: '__llvm_covfun (2)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: FAD58DE7366495DB09000000180000000000000093E696313ECE8F5D01010001012F010502 + - Name: __llvm_covmap + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 0000000016000000000000000600000002130000116272616E63682D6D6163726F732E6370700000 + - Name: __llvm_prf_names + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] + AddressAlign: 0x1 + Content: 19005F5A3466756E636969015F5A3566756E63326969016D61696E + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: __llvm_covfun + - Name: '__llvm_covfun (1)' + - Name: '__llvm_covfun (2)' + - Name: __llvm_covmap + - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_B30B5C302CEDA0F0u + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0x15B + Other: [ STV_HIDDEN ] + - Name: __covrec_956373C63F981DB0u + Type: STT_OBJECT + Section: '__llvm_covfun (1)' + Binding: STB_WEAK + Size: 0xBA + Other: [ STV_HIDDEN ] + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: '__llvm_covfun (2)' + Binding: STB_WEAK + Size: 0x25 + Other: [ STV_HIDDEN ] +... diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp index 712b2790f774a..e2abe748d86dc 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp @@ -12,41 +12,41 @@ #include - +// CHECK: |{{ +}}[[C3:3|1]]|bool func( bool func(int a, int b) { - bool c = COND1 && COND2; // CHECK: | | | Branch ([[@LINE-12]]:15): [True: 1, False: 2] - // CHECK: | | | Branch ([[@LINE-12]]:15): [True: 0, False: 1] - bool d = COND3; // CHECK: | | | | | Branch ([[@LINE-14]]:15): [True: 1, False: 2] - // CHECK: | | | | | Branch ([[@LINE-14]]:15): [True: 0, False: 1] - bool e = MACRO1; // CHECK: | | | | | | | Branch ([[@LINE-16]]:15): [True: 1, False: 2] - // CHECK: | | | | | | | Branch ([[@LINE-16]]:15): [True: 0, False: 1] - bool f = MACRO2; // CHECK: | | | | | | | | | Branch ([[@LINE-18]]:15): [True: 1, False: 2] - // CHECK: | | | | | | | | | Branch ([[@LINE-18]]:15): [True: 0, False: 1] - bool g = MACRO3; // CHECK: | | | | | | | | | | | Branch ([[@LINE-20]]:15): [True: 1, False: 2] - // CHECK: | | | | | | | | | | | Branch ([[@LINE-20]]:15): [True: 0, False: 1] + bool c = COND1 && COND2; // BRCOV: | | | Branch ([[@LINE-12]]:15): [True: 1, False: [[C2:2|1]]] + // BRCOV: | | | Branch ([[@LINE-12]]:15): [True: 0, False: 1] + bool d = COND3; // BRCOV: | | | | | Branch ([[@LINE-14]]:15): [True: 1, False: [[C2]]] + // BRCOV: | | | | | Branch ([[@LINE-14]]:15): [True: 0, False: 1] + bool e = MACRO1; // BRCOV: | | | | | | | Branch ([[@LINE-16]]:15): [True: 1, False: [[C2]]] + // BRCOV: | | | | | | | Branch ([[@LINE-16]]:15): [True: 0, False: 1] + bool f = MACRO2; // BRCOV: | | | | | | | | | Branch ([[@LINE-18]]:15): [True: 1, False: [[C2]]] + // BRCOV: | | | | | | | | | Branch ([[@LINE-18]]:15): [True: 0, False: 1] + bool g = MACRO3; // BRCOV: | | | | | | | | | | | Branch ([[@LINE-20]]:15): [True: 1, False: [[C2]]] + // BRCOV: | | | | | | | | | | | Branch ([[@LINE-20]]:15): [True: 0, False: 1] return c && d && e && f && g; - // CHECK: | Branch ([[@LINE-1]]:10): [True: 0, False: 3] - // CHECK: | Branch ([[@LINE-2]]:15): [True: 0, False: 0] - // CHECK: | Branch ([[@LINE-3]]:20): [True: 0, False: 0] - // CHECK: | Branch ([[@LINE-4]]:25): [True: 0, False: 0] - // CHECK: | Branch ([[@LINE-5]]:30): [True: 0, False: 0] + // BRCOV: | Branch ([[@LINE-1]]:10): [True: 0, False: [[C3]]] + // BRCOV: | Branch ([[@LINE-2]]:15): [True: 0, False: 0] + // BRCOV: | Branch ([[@LINE-3]]:20): [True: 0, False: 0] + // BRCOV: | Branch ([[@LINE-4]]:25): [True: 0, False: 0] + // BRCOV: | Branch ([[@LINE-5]]:30): [True: 0, False: 0] } bool func2(int a, int b) { - bool h = MACRO3 || COND4; // CHECK: | | | | | | | | | | | Branch ([[@LINE-32]]:15): [True: 1, False: 2] - // CHECK: | | | | | | | | | | | Branch ([[@LINE-32]]:15): [True: 0, False: 1] - // CHECK: | | | | | | | Branch ([[@LINE-34]]:15): [True: 1, False: 2] - // CHECK: | | | | | | | Branch ([[@LINE-34]]:15): [True: 0, False: 1] - // CHECK: | | | Branch ([[@LINE-33]]:15): [True: 1, False: 2] + bool h = MACRO3 || COND4; // BRCOV: | | | | | | | | | | | Branch ([[@LINE-32]]:15): [True: 1, False: [[C2]]] + // BRCOV: | | | | | | | | | | | Branch ([[@LINE-32]]:15): [True: 0, False: 1] + // BRCOV: | | | | | | | Branch ([[@LINE-34]]:15): [True: 1, False: [[C2]]] + // BRCOV: | | | | | | | Branch ([[@LINE-34]]:15): [True: 0, False: 1] + // BRCOV: | | | Branch ([[@LINE-33]]:15): [True: 1, False: [[C2]]] return h; } -extern "C" { extern void __llvm_profile_write_file(void); } + int main(int argc, char *argv[]) { func(atoi(argv[1]), atoi(argv[2])); func2(atoi(argv[1]), atoi(argv[2])); - __llvm_profile_write_file(); + (void)0; return 0; } diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-showBranchPercentage.c b/llvm/test/tools/llvm-cov/Inputs/branch-showBranchPercentage.c index c41739ff0b22f..6db980a8bd64a 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-showBranchPercentage.c +++ b/llvm/test/tools/llvm-cov/Inputs/branch-showBranchPercentage.c @@ -13,7 +13,7 @@ int main(int argc, char *argv[]) int i = 0; if (argc < 3) // CHECK: Branch ([[@LINE]]:7): [True: 16.67%, False: 83.33%] { - __llvm_profile_write_file(); + (void)0; return 0; } @@ -52,7 +52,7 @@ int main(int argc, char *argv[]) printf("loop\n"); } while (i++ < 10); // CHECK: Branch ([[@LINE]]:12): [True: 90.91%, False: 9.09%] - __llvm_profile_write_file(); + (void)b; - return b; + return 0; } diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.proftext b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.proftext new file mode 100644 index 0000000000000..829431334478f --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.proftext @@ -0,0 +1,49 @@ +# Instrument block coverage +:single_byte_coverage +_Z4funcIbEiT_ +# Func Hash: +11045778961 +# Num Counters: +4 +# Counter Values: +1 +1 +0 +0 + +_Z4funcIfEiT_ +# Func Hash: +11045778961 +# Num Counters: +4 +# Counter Values: +1 +0 +1 +0 + +_Z4funcIiEiT_ +# Func Hash: +11045778961 +# Num Counters: +4 +# Counter Values: +1 +0 +1 +0 + +main +# Func Hash: +185286008276329560 +# Num Counters: +7 +# Counter Values: +1 +1 +1 +0 +1 +1 +1 + diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml new file mode 100644 index 0000000000000..d4ede6db448e6 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml @@ -0,0 +1,81 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 + SectionHeaderStringTable: .strtab +Sections: + - Name: __llvm_covfun + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: FAD58DE7366495DB5100000058242991A444920226ED9A40DAABBC6B0101000D011D0C090201010700130500140185808080080501050016090103060209000700170D00180185808080080D01050016110103040211000700171500180185808080081501050016190103010B + - Name: '__llvm_covfun (1)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 5427717259E0E43E38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 + - Name: '__llvm_covfun (2)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 4B7E22082F0551AA38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 + - Name: '__llvm_covfun (3)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: AC1440BC3DA3E41A38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 + - Name: __llvm_covmap + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 0000000019000000000000000600000002160000146272616E63682D74656D706C617465732E637070000000 + - Name: __llvm_prf_names + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] + AddressAlign: 0x1 + Content: 2E006D61696E015F5A3466756E6349694569545F015F5A3466756E6349624569545F015F5A3466756E6349664569545F + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: __llvm_covfun + - Name: '__llvm_covfun (1)' + - Name: '__llvm_covfun (2)' + - Name: '__llvm_covfun (3)' + - Name: __llvm_covmap + - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0x6D + Other: [ STV_HIDDEN ] + - Name: __covrec_3EE4E05972712754u + Type: STT_OBJECT + Section: '__llvm_covfun (1)' + Binding: STB_WEAK + Size: 0x54 + Other: [ STV_HIDDEN ] + - Name: __covrec_AA51052F08227E4Bu + Type: STT_OBJECT + Section: '__llvm_covfun (2)' + Binding: STB_WEAK + Size: 0x54 + Other: [ STV_HIDDEN ] + - Name: __covrec_1AE4A33DBC4014ACu + Type: STT_OBJECT + Section: '__llvm_covfun (3)' + Binding: STB_WEAK + Size: 0x54 + Other: [ STV_HIDDEN ] +... diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp index 0795a5346380d..4d932eaf5944a 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp @@ -11,28 +11,28 @@ void unused(T x) { template int func(T x) { - if(x) // CHECK: | Branch ([[@LINE]]:6): [True: 0, False: 1] - return 0; // CHECK: | Branch ([[@LINE-1]]:6): [True: 1, False: 0] - else // CHECK: | Branch ([[@LINE-2]]:6): [True: 0, False: 1] + if(x) // BRCOV: | Branch ([[@LINE]]:6): [True: 0, False: 1] + return 0; // BRCOV: | Branch ([[@LINE-1]]:6): [True: 1, False: 0] + else // BRCOV: | Branch ([[@LINE-2]]:6): [True: 0, False: 1] return 1; int j = 1; } // CHECK-LABEL: _Z4funcIiEiT_: - // CHECK: | | Branch ([[@LINE-8]]:6): [True: 0, False: 1] + // BRCOV: | | Branch ([[@LINE-8]]:6): [True: 0, False: 1] // CHECK-LABEL: _Z4funcIbEiT_: - // CHECK: | | Branch ([[@LINE-10]]:6): [True: 1, False: 0] + // BRCOV: | | Branch ([[@LINE-10]]:6): [True: 1, False: 0] // CHECK-LABEL: _Z4funcIfEiT_: - // CHECK: | | Branch ([[@LINE-12]]:6): [True: 0, False: 1] + // BRCOV: | | Branch ([[@LINE-12]]:6): [True: 0, False: 1] + -extern "C" { extern void __llvm_profile_write_file(void); } int main() { - if (func(0)) // CHECK: | Branch ([[@LINE]]:7): [True: 1, False: 0] + if (func(0)) // BRCOV: | Branch ([[@LINE]]:7): [True: 1, False: 0] printf("case1\n"); - if (func(true)) // CHECK: | Branch ([[@LINE]]:7): [True: 0, False: 1] + if (func(true)) // BRCOV: | Branch ([[@LINE]]:7): [True: 0, False: 1] printf("case2\n"); - if (func(0.0)) // CHECK: | Branch ([[@LINE]]:7): [True: 1, False: 0] + if (func(0.0)) // BRCOV: | Branch ([[@LINE]]:7): [True: 1, False: 0] printf("case3\n"); - __llvm_profile_write_file(); + (void)0; return 0; } diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext new file mode 100644 index 0000000000000..1b7b949de4962 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext @@ -0,0 +1,23 @@ +# Instrument block coverage +:single_byte_coverage +main +# Func Hash: +15239891155360101223 +# Num Counters: +14 +# Counter Values: +161 +0 +161 +161 +161 +161 +161 +161 +161 +161 +0 +161 +0 +161 + diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml new file mode 100644 index 0000000000000..84b184023f082 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml @@ -0,0 +1,45 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 + SectionHeaderStringTable: .strtab +Sections: + - Name: __llvm_covfun + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: FAD58DE7366495DB9A0000006733DBEA42F87ED3C60E0B951FF3509D0101001A01060C130210020100010101070008050009008A8080800805000A0204090204008A8080800809000A020410030100010D01030A02110013001A15001C001F19002000A180808008190021020410030100011D010306021D0007000D25000F0090808080082500100015290018001D2101030502210007000D31000F018980808008310109000E350109000E10010100012D0103000B + - Name: __llvm_covmap + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 00000000200000000000000006000000021D00001B73686F774C696E65457865637574696F6E436F756E74732E637070 + - Name: __llvm_prf_names + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] + AddressAlign: 0x1 + Content: 04006D61696E + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: __llvm_covfun + - Name: __llvm_covmap + - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0xB6 + Other: [ STV_HIDDEN ] +... diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp index c7e8c8fb0c75e..b14409f173849 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp @@ -3,26 +3,26 @@ // before any coverage // WHOLE-FILE: [[@LINE]]| |// before // FILTER-NOT: [[@LINE-1]]| |// before // HTML: // HTML-INDEX: Totals + +// RUN: yaml2obj %S/Inputs/branch-c-general-single.yaml -o %t.o +// RUN: llvm-profdata merge %S/Inputs/branch-c-general-single.proftext -o %t.profdata +// RUN: llvm-cov show --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs %S/Inputs/branch-c-general.c | FileCheck %S/Inputs/branch-c-general.c diff --git a/llvm/test/tools/llvm-cov/branch-logical-mixed.test b/llvm/test/tools/llvm-cov/branch-logical-mixed.test index a07d2357f2c34..b03cabeb01855 100644 --- a/llvm/test/tools/llvm-cov/branch-logical-mixed.test +++ b/llvm/test/tools/llvm-cov/branch-logical-mixed.test @@ -1,8 +1,14 @@ // RUN: llvm-profdata merge %S/Inputs/branch-logical-mixed.proftext -o %t.profdata -// RUN: llvm-cov show --show-branches=count %S/Inputs/branch-logical-mixed.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-logical-mixed.cpp +// RUN: llvm-cov show --show-branches=count %S/Inputs/branch-logical-mixed.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-logical-mixed.cpp -check-prefixes=CHECK,BRCOV // RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-logical-mixed.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-logical-mixed.cpp | FileCheck %s -check-prefix=REPORT +// RUN: yaml2obj %S/Inputs/branch-logical-mixed-single.yaml -o %t.o +// RUN: llvm-profdata merge %S/Inputs/branch-logical-mixed-single.proftext -o %t.profdata +// RUN: llvm-cov show --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/branch-logical-mixed.cpp +// RUN: llvm-cov report --show-branch-summary %t.o -instr-profile %t.profdata -show-functions -path-equivalence=.,%S/Inputs %S/Inputs/branch-logical-mixed.cpp +| FileCheck %s -check-prefix=REPORT + // REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover // REPORT-NEXT: --- // REPORT-NEXT: _Z4funcii 77 15 80.52% 60 2 96.67% 80 30 62.50% diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test index fbe7694b4f4e0..a4790afc53422 100644 --- a/llvm/test/tools/llvm-cov/branch-macros.test +++ b/llvm/test/tools/llvm-cov/branch-macros.test @@ -1,7 +1,11 @@ // RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata -// RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp +// RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV // RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=REPORT +// RUN: yaml2obj %S/Inputs/branch-macros-single.yaml -o %t.o +// RUN: llvm-profdata merge %S/Inputs/branch-macros-single.proftext -o %t.profdata +// RUN: llvm-cov show --show-expansions --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp + // REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover // REPORT-NEXT: --- // REPORT-NEXT: _Z4funcii 28 4 85.71% 18 0 100.00% 30 14 53.33% diff --git a/llvm/test/tools/llvm-cov/branch-templates.test b/llvm/test/tools/llvm-cov/branch-templates.test index 74aef16050228..d5535022239f5 100644 --- a/llvm/test/tools/llvm-cov/branch-templates.test +++ b/llvm/test/tools/llvm-cov/branch-templates.test @@ -3,6 +3,10 @@ // RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-templates.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-templates.cpp | FileCheck %s -check-prefix=REPORT // RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-templates.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %s -check-prefix=REPORTFILE +// RUN: yaml2obj %S/Inputs/branch-templates-single.yaml -o %t.o +// RUN: llvm-profdata merge %S/Inputs/branch-templates-single.proftext -o %t.profdata +// RUN: llvm-cov show --show-expansions --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/branch-templates.cpp + // REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover // REPORT-NEXT: --- // REPORT-NEXT: main 7 1 85.71% 10 1 90.00% 6 3 50.00% diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.test b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test index 997b16a0b8e94..2c0669a7cec42 100644 --- a/llvm/test/tools/llvm-cov/showLineExecutionCounts.test +++ b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test @@ -41,3 +41,10 @@ // HTML-INDEX: 72.73% (8/11) // HTML-INDEX: // HTML-INDEX: Totals + +// Single byte +// RUN: yaml2obj %S/Inputs/showLineExecutionCounts-single.yaml -o %t.o +// RUN: llvm-profdata merge %S/Inputs/showLineExecutionCounts-single.proftext -o %t.profdata + +// RUN: llvm-cov show %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE %S/Inputs/showLineExecutionCounts.cpp +// RUN: llvm-cov show %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs -name=main | FileCheck -check-prefixes=TEXT,FILTER %S/Inputs/showLineExecutionCounts.cpp From 5fc3408628a72560490c5271de171a636f5be50a Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 20 Nov 2024 23:46:58 +0900 Subject: [PATCH 08/35] Fix a test to fix linecount=1 --- llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp index b14409f173849..b63247341a28e 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp @@ -12,8 +12,8 @@ int main() { // TEXT: [[@LINE]]| [[C161:161|1]] x = 1; // TEXT: [[@LINE]]| [[C161]]| x = 1 } // TEXT: [[@LINE]]| [[C161]]| } - for (int i = 0; i < 100; ++i) { // TEXT: [[@LINE]]| [[C16K2:16\.2k|161]]| for ( - x = 1; // TEXT: [[@LINE]]| [[C16K1:16\.1k|161]]| x = 1 + for (int i = 0; i < 100; ++i) { // TEXT: [[@LINE]]| [[C16K2:16\.2k|1]]| for ( + x = 1; // TEXT: [[@LINE]]| [[C16K1:16\.1k|1]]| x = 1 } // TEXT: [[@LINE]]| [[C16K1]]| } x = x < 10 ? x + 1 : x - 1; // TEXT: [[@LINE]]| [[C161]]| x = From eb7fff9a3b8356851770d1b5c6a4f0a69a79af05 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 21 Nov 2024 07:57:37 +0900 Subject: [PATCH 09/35] threads.c: Fixup on the clean testdir --- llvm/test/tools/llvm-cov/threads.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/llvm/test/tools/llvm-cov/threads.c b/llvm/test/tools/llvm-cov/threads.c index b162b6ac5a801..73dd82c3a7464 100644 --- a/llvm/test/tools/llvm-cov/threads.c +++ b/llvm/test/tools/llvm-cov/threads.c @@ -1,9 +1,10 @@ // Coverage/profile data recycled from the showLineExecutionCounts.cpp test. // +// RUN: rm -rf %t*.dir // RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -j 1 -o %t1.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S %S/showLineExecutionCounts.cpp -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -num-threads 2 -o %t2.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S %S/showLineExecutionCounts.cpp -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t3.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S %S/showLineExecutionCounts.cpp +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -j 1 -o %t1.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -num-threads 2 -o %t2.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t3.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs // // RUN: diff %t1.dir/index.txt %t2.dir/index.txt // RUN: diff %t1.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %t2.dir/coverage/tmp/showLineExecutionCounts.cpp.txt From 75430950a1a347f4a1c3d9dc0804afe9a3f25aaa Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 21 Nov 2024 23:20:19 +0900 Subject: [PATCH 10/35] Rename threads.c to threads.test since it is no longer C source file. --- llvm/test/tools/llvm-cov/{threads.c => threads.test} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename llvm/test/tools/llvm-cov/{threads.c => threads.test} (100%) diff --git a/llvm/test/tools/llvm-cov/threads.c b/llvm/test/tools/llvm-cov/threads.test similarity index 100% rename from llvm/test/tools/llvm-cov/threads.c rename to llvm/test/tools/llvm-cov/threads.test From 00ac90d232a5793a94f6863dcba2274f4e0126cb Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 21 Nov 2024 23:25:06 +0900 Subject: [PATCH 11/35] llvm/test/tools/llvm-cov/Inputs: Avoid wildcards `rm -rf %t*.dir` --- .../llvm-cov/showLineExecutionCounts.test | 22 +++++++++---------- llvm/test/tools/llvm-cov/threads.test | 16 +++++++------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.test b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test index 2c0669a7cec42..1c1e894922827 100644 --- a/llvm/test/tools/llvm-cov/showLineExecutionCounts.test +++ b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test @@ -1,32 +1,32 @@ // Basic handling of line counts. -// RUN: rm -rf %t*.dir +// RUN: rm -rf %t.dir // RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata // RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE %S/Inputs/showLineExecutionCounts.cpp // RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main | FileCheck -check-prefixes=TEXT,FILTER %S/Inputs/showLineExecutionCounts.cpp // Test -output-dir. -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -output-dir %t.filtered.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main -// RUN: FileCheck -check-prefixes=TEXT,WHOLE-FILE -input-file %t.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp -// RUN: FileCheck -check-prefixes=TEXT,FILTER -input-file %t.filtered.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t.dir/show -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -output-dir %t.dir/show.filtered -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main +// RUN: FileCheck -check-prefixes=TEXT,WHOLE-FILE -input-file %t.dir/show/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp +// RUN: FileCheck -check-prefixes=TEXT,FILTER -input-file %t.dir/show.filtered/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp // // RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata 2>/dev/null -summary-only > %t.export-summary.json // RUN: not grep '"name":"main"' %t.export-summary.json // // Test html output. -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.html.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.html.filtered.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main -// RUN: FileCheck -check-prefixes=HTML,HTML-WHOLE-FILE -input-file %t.html.dir/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp -// RUN: FileCheck -check-prefixes=HTML,HTML-FILTER -input-file %t.html.filtered.dir/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.dir/html -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.dir/html.filtered -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main +// RUN: FileCheck -check-prefixes=HTML,HTML-WHOLE-FILE -input-file %t.dir/html/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp +// RUN: FileCheck -check-prefixes=HTML,HTML-FILTER -input-file %t.dir/html.filtered/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp // // Test index creation. -// RUN: FileCheck -check-prefix=TEXT-INDEX -input-file %t.dir/index.txt %s +// RUN: FileCheck -check-prefix=TEXT-INDEX -input-file %t.dir/show/index.txt %s // TEXT-INDEX: Filename // TEXT-INDEX-NEXT: --- // TEXT-INDEX-NEXT: {{.*}}showLineExecutionCounts.cpp // -// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.html.dir/index.html %s +// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.dir/html/index.html %s // HTML-INDEX-LABEL:
FilenameFunction CoverageLine CoverageRegion Coverage +// HTML-INDEX: 100.00% (1/1) +// HTML-INDEX: +// HTML-INDEX: 90.00% (18/20) +// HTML-INDEX: +// HTML-INDEX: 72.73% (8/11) +// HTML-INDEX:
[[@LINE+1]]
161
int main() {
-int main() {                              // TEXT: [[@LINE]]|   161|int main(
-  int x = 0;                              // TEXT: [[@LINE]]|   161|  int x
-                                          // TEXT: [[@LINE]]|   161|
-  if (x) {                                // TEXT: [[@LINE]]|   161|  if (x)
-    x = 0;                                // TEXT: [[@LINE]]|     0|    x = 0
-  } else {                                // TEXT: [[@LINE]]|   161|  } else
-    x = 1;                                // TEXT: [[@LINE]]|   161|    x = 1
-  }                                       // TEXT: [[@LINE]]|   161|  }
-                                          // TEXT: [[@LINE]]|   161|
-  for (int i = 0; i < 100; ++i) {         // TEXT: [[@LINE]]| 16.2k|  for (
-    x = 1;                                // TEXT: [[@LINE]]| 16.1k|    x = 1
-  }                                       // TEXT: [[@LINE]]| 16.1k|  }
-                                          // TEXT: [[@LINE]]|   161|
-  x = x < 10 ? x + 1 : x - 1;             // TEXT: [[@LINE]]|   161|  x =
-  x = x > 10 ?                            // TEXT: [[@LINE]]|   161|  x =
-        x - 1:                            // TEXT: [[@LINE]]|     0|        x
-        x + 1;                            // TEXT: [[@LINE]]|   161|        x
-                                          // TEXT: [[@LINE]]|   161|
-  return 0;                               // TEXT: [[@LINE]]|   161|  return
-}                                         // TEXT: [[@LINE]]|   161|}
+int main() {                              // TEXT: [[@LINE]]|     [[C161:161|1]]|int main(
+  int x = 0;                              // TEXT: [[@LINE]]|           [[C161]]|  int x
+
+  if (x) {                                // TEXT: [[@LINE]]|           [[C161]]|  if (x)
+    x = 0;                                // TEXT: [[@LINE]]|                  0|    x = 0
+  } else {                                // TEXT: [[@LINE]]|           [[C161]]|  } else
+    x = 1;                                // TEXT: [[@LINE]]|           [[C161]]|    x = 1
+  }                                       // TEXT: [[@LINE]]|           [[C161]]|  }
+
+  for (int i = 0; i < 100; ++i) {         // TEXT: [[@LINE]]| [[C16K2:16\.2k|161]]|  for (
+    x = 1;                                // TEXT: [[@LINE]]| [[C16K1:16\.1k|161]]|    x = 1
+  }                                       // TEXT: [[@LINE]]|          [[C16K1]]|  }
+
+  x = x < 10 ? x + 1 : x - 1;             // TEXT: [[@LINE]]|           [[C161]]|  x =
+  x = x > 10 ?                            // TEXT: [[@LINE]]|           [[C161]]|  x =
+        x - 1:                            // TEXT: [[@LINE]]|                  0|        x
+        x + 1;                            // TEXT: [[@LINE]]|           [[C161]]|        x
+
+  return 0;                               // TEXT: [[@LINE]]|           [[C161]]|  return
+}                                         // TEXT: [[@LINE]]|           [[C161]]|}
 // after coverage                   // WHOLE-FILE: [[@LINE]]|      |// after
                                     // FILTER-NOT: [[@LINE-1]]|    |// after
 // HTML-WHOLE-FILE: 
[[@LINE-2]]
// after
diff --git a/llvm/test/tools/llvm-cov/branch-c-general.test b/llvm/test/tools/llvm-cov/branch-c-general.test
index 865a2662460e8..3d0b7ee563222 100644
--- a/llvm/test/tools/llvm-cov/branch-c-general.test
+++ b/llvm/test/tools/llvm-cov/branch-c-general.test
@@ -164,3 +164,7 @@
 // HTML-INDEX: 79.07% (136/172)
 // HTML-INDEX: 
// HTML-INDEX: // HTML-INDEX: diff --git a/llvm/test/tools/llvm-cov/threads.test b/llvm/test/tools/llvm-cov/threads.test index 73dd82c3a7464..a51406ca14efa 100644 --- a/llvm/test/tools/llvm-cov/threads.test +++ b/llvm/test/tools/llvm-cov/threads.test @@ -1,12 +1,12 @@ // Coverage/profile data recycled from the showLineExecutionCounts.cpp test. // -// RUN: rm -rf %t*.dir +// RUN: rm -rf %t.dir // RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -j 1 -o %t1.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -num-threads 2 -o %t2.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t3.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -j 1 -o %t.dir/1 -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -num-threads 2 -o %t.dir/2 -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t.dir/3 -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs // -// RUN: diff %t1.dir/index.txt %t2.dir/index.txt -// RUN: diff %t1.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %t2.dir/coverage/tmp/showLineExecutionCounts.cpp.txt -// RUN: diff %t1.dir/index.txt %t3.dir/index.txt -// RUN: diff %t1.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %t3.dir/coverage/tmp/showLineExecutionCounts.cpp.txt +// RUN: diff %t.dir/1/index.txt %t.dir/2/index.txt +// RUN: diff %t.dir/1/coverage/tmp/showLineExecutionCounts.cpp.txt %t.dir/2/coverage/tmp/showLineExecutionCounts.cpp.txt +// RUN: diff %t.dir/1/index.txt %t.dir/3/index.txt +// RUN: diff %t.dir/1/coverage/tmp/showLineExecutionCounts.cpp.txt %t.dir/3/coverage/tmp/showLineExecutionCounts.cpp.txt From 5fa862ad60b75814c15f9317d6d59384524f5717 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 21 Dec 2024 17:30:24 +0900 Subject: [PATCH 12/35] Use `[[#min(C,n)]]` for tests --- .../tools/llvm-cov/Inputs/branch-c-general.c | 120 +++++++++--------- .../llvm-cov/Inputs/branch-logical-mixed.cpp | 54 ++++---- .../tools/llvm-cov/Inputs/branch-macros.cpp | 22 ++-- .../Inputs/showLineExecutionCounts.cpp | 45 +++---- .../test/tools/llvm-cov/branch-c-general.test | 2 +- .../tools/llvm-cov/branch-logical-mixed.test | 4 +- llvm/test/tools/llvm-cov/branch-macros.test | 4 +- .../llvm-cov/showLineExecutionCounts.test | 12 +- 8 files changed, 132 insertions(+), 131 deletions(-) diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c index 5ea9ecb42b0ed..9660e857092bc 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c @@ -6,27 +6,27 @@ void simple_loops() { // CHECK: @LINE|{{.*}}simple_loops() int i; - for (i = 0; i < 100; ++i) { // BRCOV: Branch ([[@LINE]]:15): [True: [[C100:100|1]], False: 1] + for (i = 0; i < 100; ++i) { // BRCOV: Branch ([[@LINE]]:15): [True: [[#min(C,100)]], False: 1] } - while (i > 0) // BRCOV: Branch ([[@LINE]]:10): [True: [[C100]], False: 1] + while (i > 0) // BRCOV: Branch ([[@LINE]]:10): [True: [[#min(C,100)]], False: 1] i--; - do {} while (i++ < 75); // BRCOV: Branch ([[@LINE]]:16): [True: [[C75:75|1]], False: 1] + do {} while (i++ < 75); // BRCOV: Branch ([[@LINE]]:16): [True: [[#min(C,75)]], False: 1] } void conditionals() { // CHECK: @LINE|{{.*}}conditionals() - for (int i = 0; i < 100; ++i) {//BRCOV: Branch ([[@LINE]]:19): [True: [[C100]], False: 1] - if (i % 2) { // BRCOV: Branch ([[@LINE]]:9): [True: [[C50:50|1]], False: [[C50]]] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C50]], False: 0] - } else if (i % 3) { // BRCOV: Branch ([[@LINE]]:16): [True: [[C33:33|1]], False: [[C17:17|1]]] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C33]], False: 0] + for (int i = 0; i < 100; ++i) {//BRCOV: Branch ([[@LINE]]:19): [True: [[#min(C,100)]], False: 1] + if (i % 2) { // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,50)]], False: [[#min(C,50)]]] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,50)]], False: 0] + } else if (i % 3) { // BRCOV: Branch ([[@LINE]]:16): [True: [[#min(C,33)]], False: [[#min(C,17)]]] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,33)]], False: 0] } else { - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C16:16|1]], False: 1] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,16)]], False: 1] } - // BRCOV: Branch ([[@LINE+1]]:9): [True: [[C100]], Folded] - if (1 && i) {} // BRCOV: Branch ([[@LINE]]:14): [True: [[C99:99|1]], False: 1] - if (0 || i) {} // BRCOV: Branch ([[@LINE]]:9): [Folded, False: [[C100]]] - } // BRCOV: Branch ([[@LINE-1]]:14): [True: [[C99]], False: 1] + // BRCOV: Branch ([[@LINE+1]]:9): [True: [[#min(C,100)]], Folded] + if (1 && i) {} // BRCOV: Branch ([[@LINE]]:14): [True: [[#min(C,99)]], False: 1] + if (0 || i) {} // BRCOV: Branch ([[@LINE]]:9): [Folded, False: [[#min(C,100)]]] + } // BRCOV: Branch ([[@LINE-1]]:14): [True: [[#min(C,99)]], False: 1] } @@ -35,22 +35,22 @@ void early_exits() { // CHECK: @LINE|{{.*}}early_exits() if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 1] - while (i < 100) { // BRCOV: Branch ([[@LINE]]:10): [True: [[C51:51|1]], False: 0] + while (i < 100) { // BRCOV: Branch ([[@LINE]]:10): [True: [[#min(C,51)]], False: 0] i++; - if (i > 50) // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[C50]]] + if (i > 50) // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[#min(C,50)]]] break; - if (i % 2) // BRCOV: Branch ([[@LINE]]:9): [True: [[C25:25|1]], False: [[C25]]] + if (i % 2) // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,25)]], False: [[#min(C,25)]]] continue; } if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 1, False: 0] do { - if (i > 75) // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[C25]]] + if (i > 75) // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[#min(C,25)]]] return; else i++; - } while (i < 100); // BRCOV: Branch ([[@LINE]]:12): [True: [[C25]], False: 0] + } while (i < 100); // BRCOV: Branch ([[@LINE]]:12): [True: [[#min(C,25)]], False: 0] if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 0] @@ -80,7 +80,7 @@ void jumps() { // CHECK: @LINE|{{.*}}jumps() second: third: i++; - if (i < 3) // BRCOV: Branch ([[@LINE]]:7): [True: [[C2:2|1]], False: 1] + if (i < 3) // BRCOV: Branch ([[@LINE]]:7): [True: [[#min(C,2)]], False: 1] goto loop2; while (i < 3) { // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1] @@ -95,12 +95,12 @@ void jumps() { // CHECK: @LINE|{{.*}}jumps() } } - for (i = 0; i < 10; ++i) { // BRCOV: Branch ([[@LINE]]:15): [True: [[C10:10|1]], False: 1] + for (i = 0; i < 10; ++i) { // BRCOV: Branch ([[@LINE]]:15): [True: [[#min(C,10)]], False: 1] goto withinloop; // never reached -> no weights if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 0] withinloop: - if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: [[C9:9|1]], False: 1] + if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,9)]], False: 1] } } @@ -113,28 +113,28 @@ void switches() { // CHECK: @LINE|{{.*}}switches() default: // BRCOV: Branch ([[@LINE]]:3): [True: 1, Folded] break; } - // BRCOV: Branch ([[@LINE+1]]:63): [True: [[C15:15|1]], False: 0] + // BRCOV: Branch ([[@LINE+1]]:63): [True: [[#min(C,15)]], False: 0] for (int i = 0, len = sizeof(weights) / sizeof(weights[0]); i < len; ++i) { switch (i[weights]) { case 1: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1] // fallthrough - case 2: // BRCOV: Branch ([[@LINE]]:5): [True: [[C2]], Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C2]], False: 1] + case 2: // BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,2)]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,2)]], False: 1] break; - case 3: // BRCOV: Branch ([[@LINE]]:5): [True: [[C3:3|1]], Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C3]], False: 0] + case 3: // BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,3)]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,3)]], False: 0] continue; - case 4: // BRCOV: Branch ([[@LINE]]:5): [True: [[C4:4|1]], Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C4]], False: 0] + case 4: // BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,4)]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,4)]], False: 0] switch (i) { - case 6 ... 9: // BRCOV: Branch ([[@LINE]]:7): [True: [[C4]], Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:13): [True: [[C4]], False: 0] + case 6 ... 9: // BRCOV: Branch ([[@LINE]]:7): [True: [[#min(C,4)]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,4)]], False: 0] continue; } - default: // BRCOV: Branch ([[@LINE]]:5): [True: [[C5:5|1]], Folded] - if (i == len - 1) // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: [[C4]]] + default: // BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,5)]], Folded] + if (i == len - 1) // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: [[#min(C,4)]]] return; } } @@ -145,7 +145,7 @@ void switches() { // CHECK: @LINE|{{.*}}switches() } void big_switch() { // CHECK: @LINE|{{.*}}big_switch() - for (int i = 0; i < 32; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[C32:32|1]], False: 1] + for (int i = 0; i < 32; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[#min(C,32)]], False: 1] switch (1 << i) { case (1 << 0): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1] @@ -153,24 +153,24 @@ void big_switch() { // CHECK: @LINE|{{.*}}big_switch() case (1 << 1): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 1] break; - case (1 << 2) ... (1 << 12):// BRCOV: Branch ([[@LINE]]:5): [True: [[C11:11|1]], Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C11]], False: 0] + case (1 << 2) ... (1 << 12):// BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,11)]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,11)]], False: 0] break; // The branch for the large case range above appears after the case body. case (1 << 13): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0] break; - case (1 << 14) ... (1 << 28)://BRCOV: Branch ([[@LINE]]:5): [True: [[C15]], Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C15]], False: 0] + case (1 << 14) ... (1 << 28)://BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,15)]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,15)]], False: 0] break; // The branch for the large case range above appears after the case body. case (1 << 29) ... ((1 << 29) + 1): if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0] break; - default: // BRCOV: Branch ([[@LINE]]:5): [True: [[C2]], Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C2]], False: 0] + default: // BRCOV: Branch ([[@LINE]]:5): [True: [[#min(C,2)]], Folded] + if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[#min(C,2)]], False: 0] break; } } @@ -180,30 +180,30 @@ void big_switch() { // CHECK: @LINE|{{.*}}big_switch() void boolean_operators() { // CHECK: @LINE|{{.*}}boolean_operators() int v; for (int i = 0; i < 100; ++i) { - v = i % 3 || i; // BRCOV: Branch ([[@LINE]]:9): [True: [[C66:66|1]], False: [[C34:34|1]]] - // BRCOV: Branch ([[@LINE-1]]:18): [True: [[C33]], False: 1] - v = i % 3 && i; // BRCOV: Branch ([[@LINE]]:9): [True: [[C66]], False: [[C34]]] - // BRCOV: Branch ([[@LINE-1]]:18): [True: [[C66]], False: 0] - v = i % 3 || i % 2 || i; // BRCOV: Branch ([[@LINE]]:9): [True: [[C66]], False: [[C34]]] - // BRCOV: Branch ([[@LINE-1]]:18): [True: [[C17]], False: [[C17]]] - v = i % 2 && i % 3 && i; // BRCOV: Branch ([[@LINE-2]]:27): [True: [[C16]], False: 1] - } // BRCOV: Branch ([[@LINE-1]]:9): [True: [[C50]], False: [[C50]]] - // BRCOV: Branch ([[@LINE-2]]:18): [True: [[C33]], False: [[C17]]] -} // BRCOV: Branch ([[@LINE-3]]:27): [True: [[C33]], False: 0] + v = i % 3 || i; // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,66)]], False: [[#min(C,34)]]] + // BRCOV: Branch ([[@LINE-1]]:18): [True: [[#min(C,33)]], False: 1] + v = i % 3 && i; // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,66)]], False: [[#min(C,34)]]] + // BRCOV: Branch ([[@LINE-1]]:18): [True: [[#min(C,66)]], False: 0] + v = i % 3 || i % 2 || i; // BRCOV: Branch ([[@LINE]]:9): [True: [[#min(C,66)]], False: [[#min(C,34)]]] + // BRCOV: Branch ([[@LINE-1]]:18): [True: [[#min(C,17)]], False: [[#min(C,17)]]] + v = i % 2 && i % 3 && i; // BRCOV: Branch ([[@LINE-2]]:27): [True: [[#min(C,16)]], False: 1] + } // BRCOV: Branch ([[@LINE-1]]:9): [True: [[#min(C,50)]], False: [[#min(C,50)]]] + // BRCOV: Branch ([[@LINE-2]]:18): [True: [[#min(C,33)]], False: [[#min(C,17)]]] +} // BRCOV: Branch ([[@LINE-3]]:27): [True: [[#min(C,33)]], False: 0] void boolop_loops() { // CHECK: @LINE|{{.*}}boolop_loops() int i = 100; - while (i && i > 50) // BRCOV: Branch ([[@LINE]]:10): [True: [[C51]], False: 0] - i--; // BRCOV: Branch ([[@LINE-1]]:15): [True: [[C50]], False: 1] + while (i && i > 50) // BRCOV: Branch ([[@LINE]]:10): [True: [[#min(C,51)]], False: 0] + i--; // BRCOV: Branch ([[@LINE-1]]:15): [True: [[#min(C,50)]], False: 1] - while ((i % 2) || (i > 0)) // BRCOV: Branch ([[@LINE]]:10): [True: [[C25]], False: [[C26:26|1]]] - i--; // BRCOV: Branch ([[@LINE-1]]:21): [True: [[C25]], False: 1] + while ((i % 2) || (i > 0)) // BRCOV: Branch ([[@LINE]]:10): [True: [[#min(C,25)]], False: [[#min(C,26)]]] + i--; // BRCOV: Branch ([[@LINE-1]]:21): [True: [[#min(C,25)]], False: 1] - for (i = 100; i && i > 50; --i); // BRCOV: Branch ([[@LINE]]:17): [True: [[C51]], False: 0] - // BRCOV: Branch ([[@LINE-1]]:22): [True: [[C50]], False: 1] - for (; (i % 2) || (i > 0); --i); // BRCOV: Branch ([[@LINE]]:10): [True: [[C25]], False: [[C26]]] - // BRCOV: Branch ([[@LINE-1]]:21): [True: [[C25]], False: 1] + for (i = 100; i && i > 50; --i); // BRCOV: Branch ([[@LINE]]:17): [True: [[#min(C,51)]], False: 0] + // BRCOV: Branch ([[@LINE-1]]:22): [True: [[#min(C,50)]], False: 1] + for (; (i % 2) || (i > 0); --i); // BRCOV: Branch ([[@LINE]]:10): [True: [[#min(C,25)]], False: [[#min(C,26)]]] + // BRCOV: Branch ([[@LINE-1]]:21): [True: [[#min(C,25)]], False: 1] } void conditional_operator() { // CHECK: @LINE|{{.*}}conditional_operator() @@ -216,7 +216,7 @@ void conditional_operator() { // CHECK: @LINE|{{.*}}conditional_operator() } void do_fallthrough() { // CHECK: @LINE|{{.*}}do_fallthrough() - for (int i = 0; i < 10; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[C10]], False: 1] + for (int i = 0; i < 10; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[#min(C,10)]], False: 1] int j = 0; do { // The number of exits out of this do-loop via the break statement @@ -224,12 +224,12 @@ void do_fallthrough() { // CHECK: @LINE|{{.*}}do_fallthrough() // fallthrough count). Make sure that does not violate any assertions. if (i < 8) break; j++; - } while (j < 2); // BRCOV: Branch ([[@LINE]]:14): [True: [[C2]], False: [[C2]]] + } while (j < 2); // BRCOV: Branch ([[@LINE]]:14): [True: [[#min(C,2)]], False: [[#min(C,2)]]] } } static void static_func() { // CHECK: @LINE|{{.*}}static_func() - for (int i = 0; i < 10; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[C10]], False: 1] + for (int i = 0; i < 10; ++i) {// BRCOV: Branch ([[@LINE]]:19): [True: [[#min(C,10)]], False: 1] } } diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp index 0eaf4c963ef9f..246b0389aa600 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp @@ -13,62 +13,62 @@ void func(int a, int b) { bool b4 = a > b; bool b5 = a != b; - bool c = b0 && // BRCOV: Branch ([[@LINE]]:12): [True: [[C3:3|1]], False: 1] - b1 && // BRCOV: Branch ([[@LINE]]:12): [True: [[C2:2|1]], False: 1] - b2 && // BRCOV: Branch ([[@LINE]]:12): [True: [[C2]], False: 0] - b3 && // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: [[C2]]] + bool c = b0 && // BRCOV: Branch ([[@LINE]]:12): [True: [[#min(C,3)]], False: 1] + b1 && // BRCOV: Branch ([[@LINE]]:12): [True: [[#min(C,2)]], False: 1] + b2 && // BRCOV: Branch ([[@LINE]]:12): [True: [[#min(C,2)]], False: 0] + b3 && // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: [[#min(C,2)]]] b4 && // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] b5; // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] - bool d = b0 || // BRCOV: Branch ([[@LINE]]:12): [True: [[C3]], False: 1] + bool d = b0 || // BRCOV: Branch ([[@LINE]]:12): [True: [[#min(C,3)]], False: 1] b1 || // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 1] b2 || // BRCOV: Branch ([[@LINE]]:12): [True: 1, False: 0] b3 || // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] b4 || // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] b5; // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] - bool e = (b0 && // BRCOV: Branch ([[@LINE]]:13): [True: [[C3]], False: 1] - b5) || // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] - (b1 && // BRCOV: Branch ([[@LINE]]:13): [True: [[C2]], False: 1] - b4) || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[C2]]] - (b2 && // BRCOV: Branch ([[@LINE]]:13): [True: [[C3]], False: 0] - b3) || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[C3]]] - (b3 && // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[C3]]] + bool e = (b0 && // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,3)]], False: 1] + b5) || // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[#min(C,2)]]] + (b1 && // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,2)]], False: 1] + b4) || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[#min(C,2)]]] + (b2 && // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,3)]], False: 0] + b3) || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[#min(C,3)]]] + (b3 && // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[#min(C,3)]]] b2) || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: 0] - (b4 && // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + (b4 && // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[#min(C,2)]]] b1) || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: 1] - (b5 && // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + (b5 && // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[#min(C,2)]]] b0); // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: 1] - bool f = (b0 || // BRCOV: Branch ([[@LINE]]:13): [True: [[C3]], False: 1] + bool f = (b0 || // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,3)]], False: 1] b5) && // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: 0] - (b1 || // BRCOV: Branch ([[@LINE]]:13): [True: [[C2]], False: [[C2]]] + (b1 || // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,2)]], False: [[#min(C,2)]]] b4) && // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: 1] - (b2 || // BRCOV: Branch ([[@LINE]]:13): [True: [[C3]], False: 0] + (b2 || // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,3)]], False: 0] b3) && // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: 0] - (b3 || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[C3]]] - b2) && // BRCOV: Branch ([[@LINE]]:13): [True: [[C3]], False: 0] - (b4 || // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] - b1) && // BRCOV: Branch ([[@LINE]]:13): [True: [[C2]], False: 0] - (b5 || // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] - b0); // BRCOV: Branch ([[@LINE]]:13): [True: [[C2]], False: 0] + (b3 || // BRCOV: Branch ([[@LINE]]:13): [True: 0, False: [[#min(C,3)]]] + b2) && // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,3)]], False: 0] + (b4 || // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[#min(C,2)]]] + b1) && // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,2)]], False: 0] + (b5 || // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[#min(C,2)]]] + b0); // BRCOV: Branch ([[@LINE]]:13): [True: [[#min(C,2)]], False: 0] - if (c) // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: [[C4]]] + if (c) // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: [[#min(C,4)]]] printf("case0\n"); else printf("case1\n"); - if (d) // BRCOV: Branch ([[@LINE]]:7): [True: [[C4]], False: 0] + if (d) // BRCOV: Branch ([[@LINE]]:7): [True: [[#min(C,4)]], False: 0] printf("case2\n"); else printf("case3\n"); - if (e) // BRCOV: Branch ([[@LINE]]:7): [True: 1, False: [[C3]]] + if (e) // BRCOV: Branch ([[@LINE]]:7): [True: 1, False: [[#min(C,3)]]] printf("case4\n"); else printf("case5\n"); - if (f) // BRCOV: Branch ([[@LINE]]:7): [True: [[C3]], False: 1] + if (f) // BRCOV: Branch ([[@LINE]]:7): [True: [[#min(C,3)]], False: 1] printf("case6\n"); else printf("case7\n"); diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp index 5dc5dcefd2c3f..ad627106f32bd 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp @@ -5,27 +5,27 @@ #define COND1 (a == b) #define COND2 (a != b) #define COND3 (COND1 && COND2) -#define COND4 (COND3 ? COND2 : COND1) // BRCOV: | Branch ([[@LINE]]:15): [True: 1, False: 2] +#define COND4 (COND3 ? COND2 : COND1) // BRCOV: | Branch ([[@LINE]]:15): [True: 1, False: [[#min(C,2)]]] #define MACRO1 COND3 #define MACRO2 MACRO1 #define MACRO3 MACRO2 #include -// CHECK: |{{ +}}[[C3:3|1]]|bool func( +// CHECK: |{{ +}}[[#min(C,3)]]|bool func( bool func(int a, int b) { - bool c = COND1 && COND2; // BRCOV: | | | Branch ([[@LINE-12]]:15): [True: 1, False: [[C2:2|1]]] + bool c = COND1 && COND2; // BRCOV: | | | Branch ([[@LINE-12]]:15): [True: 1, False: [[#min(C,2)]]] // BRCOV: | | | Branch ([[@LINE-12]]:15): [True: 0, False: 1] - bool d = COND3; // BRCOV: | | | | | Branch ([[@LINE-14]]:15): [True: 1, False: [[C2]]] + bool d = COND3; // BRCOV: | | | | | Branch ([[@LINE-14]]:15): [True: 1, False: [[#min(C,2)]]] // BRCOV: | | | | | Branch ([[@LINE-14]]:15): [True: 0, False: 1] - bool e = MACRO1; // BRCOV: | | | | | | | Branch ([[@LINE-16]]:15): [True: 1, False: [[C2]]] + bool e = MACRO1; // BRCOV: | | | | | | | Branch ([[@LINE-16]]:15): [True: 1, False: [[#min(C,2)]]] // BRCOV: | | | | | | | Branch ([[@LINE-16]]:15): [True: 0, False: 1] - bool f = MACRO2; // BRCOV: | | | | | | | | | Branch ([[@LINE-18]]:15): [True: 1, False: [[C2]]] + bool f = MACRO2; // BRCOV: | | | | | | | | | Branch ([[@LINE-18]]:15): [True: 1, False: [[#min(C,2)]]] // BRCOV: | | | | | | | | | Branch ([[@LINE-18]]:15): [True: 0, False: 1] - bool g = MACRO3; // BRCOV: | | | | | | | | | | | Branch ([[@LINE-20]]:15): [True: 1, False: [[C2]]] + bool g = MACRO3; // BRCOV: | | | | | | | | | | | Branch ([[@LINE-20]]:15): [True: 1, False: [[#min(C,2)]]] // BRCOV: | | | | | | | | | | | Branch ([[@LINE-20]]:15): [True: 0, False: 1] return c && d && e && f && g; - // BRCOV: | Branch ([[@LINE-1]]:10): [True: 0, False: [[C3]]] + // BRCOV: | Branch ([[@LINE-1]]:10): [True: 0, False: [[#min(C,3)]]] // BRCOV: | Branch ([[@LINE-2]]:15): [True: 0, False: 0] // BRCOV: | Branch ([[@LINE-3]]:20): [True: 0, False: 0] // BRCOV: | Branch ([[@LINE-4]]:25): [True: 0, False: 0] @@ -34,11 +34,11 @@ bool func(int a, int b) { bool func2(int a, int b) { - bool h = MACRO3 || COND4; // BRCOV: | | | | | | | | | | | Branch ([[@LINE-32]]:15): [True: 1, False: [[C2]]] + bool h = MACRO3 || COND4; // BRCOV: | | | | | | | | | | | Branch ([[@LINE-32]]:15): [True: 1, False: [[#min(C,2)]]] // BRCOV: | | | | | | | | | | | Branch ([[@LINE-32]]:15): [True: 0, False: 1] - // BRCOV: | | | | | | | Branch ([[@LINE-34]]:15): [True: 1, False: [[C2]]] + // BRCOV: | | | | | | | Branch ([[@LINE-34]]:15): [True: 1, False: [[#min(C,2)]]] // BRCOV: | | | | | | | Branch ([[@LINE-34]]:15): [True: 0, False: 1] - // BRCOV: | | | Branch ([[@LINE-33]]:15): [True: 1, False: [[C2]]] + // BRCOV: | | | Branch ([[@LINE-33]]:15): [True: 1, False: [[#min(C,2)]]] return h; } diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp index b14409f173849..be780b45f279c 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp @@ -1,29 +1,30 @@ // HTML-WHOLE-FILE:
FilenameFunction Coverage
[[@LINE+2]]
// before
 // HTML-FILTER-NOT: 
[[@LINE+1]]
// before
-// before any coverage              // WHOLE-FILE: [[@LINE]]|      |// before
-                                    // FILTER-NOT: [[@LINE-1]]|    |// before
+// before any coverage              // WHOLE-FILE: [[@LINE]]|                     |// before
+                                    // FILTER-NOT: [[@LINE-1]]|                   |// before
 // HTML: 
[[@LINE+1]]
161
int main() {
-int main() {                              // TEXT: [[@LINE]]|     [[C161:161|1]]|int main(
-  int x = 0;                              // TEXT: [[@LINE]]|           [[C161]]|  int x
+int main() {                              // TEXT: [[@LINE]]| [[#C161:min(C,161)]]|int main(
+  int x = 0;                              // TEXT: [[@LINE]]|            [[#C161]]|  int x
 
-  if (x) {                                // TEXT: [[@LINE]]|           [[C161]]|  if (x)
-    x = 0;                                // TEXT: [[@LINE]]|                  0|    x = 0
-  } else {                                // TEXT: [[@LINE]]|           [[C161]]|  } else
-    x = 1;                                // TEXT: [[@LINE]]|           [[C161]]|    x = 1
-  }                                       // TEXT: [[@LINE]]|           [[C161]]|  }
+  if (x) {                                // TEXT: [[@LINE]]|            [[#C161]]|  if (x)
+    x = 0;                                // TEXT: [[@LINE]]|                    0|    x = 0
+  } else {                                // TEXT: [[@LINE]]|            [[#C161]]|  } else
+    x = 1;                                // TEXT: [[@LINE]]|            [[#C161]]|    x = 1
+  }                                       // TEXT: [[@LINE]]|            [[#C161]]|  }
 
-  for (int i = 0; i < 100; ++i) {         // TEXT: [[@LINE]]| [[C16K2:16\.2k|161]]|  for (
-    x = 1;                                // TEXT: [[@LINE]]| [[C16K1:16\.1k|161]]|    x = 1
-  }                                       // TEXT: [[@LINE]]|          [[C16K1]]|  }
+  for (int i = 0; i < 100; ++i) {         // TEXT: [[@LINE]]|            [[C16K2]]|  for (
+    x = 1;                                // TEXT: [[@LINE]]|            [[C16K1]]|    x = 1
+  }                                       // TEXT: [[@LINE]]|            [[C16K1]]|  }
 
-  x = x < 10 ? x + 1 : x - 1;             // TEXT: [[@LINE]]|           [[C161]]|  x =
-  x = x > 10 ?                            // TEXT: [[@LINE]]|           [[C161]]|  x =
-        x - 1:                            // TEXT: [[@LINE]]|                  0|        x
-        x + 1;                            // TEXT: [[@LINE]]|           [[C161]]|        x
+  x = x < 10 ? x + 1 : x - 1;             // TEXT: [[@LINE]]|            [[#C161]]|  x =
+  x = x > 10 ?                            // TEXT: [[@LINE]]|            [[#C161]]|  x =
+        x - 1:                            // TEXT: [[@LINE]]|                    0|        x
+        x + 1;                            // TEXT: [[@LINE]]|            [[#C161]]|        x
 
-  return 0;                               // TEXT: [[@LINE]]|           [[C161]]|  return
-}                                         // TEXT: [[@LINE]]|           [[C161]]|}
-// after coverage                   // WHOLE-FILE: [[@LINE]]|      |// after
-                                    // FILTER-NOT: [[@LINE-1]]|    |// after
-// HTML-WHOLE-FILE: 
[[@LINE-2]]
// after
-// HTML-FILTER-NOT: 
[[@LINE-3]]
// after
+  return 0;                               // TEXT: [[@LINE]]|            [[#C161]]|  return
+}                                         // TEXT: [[@LINE]]|            [[#C161]]|}
+// after coverage                   // WHOLE-FILE: [[@LINE]]|                     |// after
+                                    // FILTER-NOT: [[@LINE-1]]|                   |// after
+// HTML-BINARY-NOT: 
16
+// HTML-WHOLE-FILE: 
[[@LINE-3]]
// after
+// HTML-FILTER-NOT: 
[[@LINE-4]]
// after
diff --git a/llvm/test/tools/llvm-cov/branch-c-general.test b/llvm/test/tools/llvm-cov/branch-c-general.test
index 3d0b7ee563222..3c163bf6de45c 100644
--- a/llvm/test/tools/llvm-cov/branch-c-general.test
+++ b/llvm/test/tools/llvm-cov/branch-c-general.test
@@ -167,4 +167,4 @@
 
 // RUN: yaml2obj %S/Inputs/branch-c-general-single.yaml -o %t.o
 // RUN: llvm-profdata merge %S/Inputs/branch-c-general-single.proftext -o %t.profdata
-// RUN: llvm-cov show --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs %S/Inputs/branch-c-general.c | FileCheck %S/Inputs/branch-c-general.c
+// RUN: llvm-cov show --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs %S/Inputs/branch-c-general.c | FileCheck %S/Inputs/branch-c-general.c -D#C=1
diff --git a/llvm/test/tools/llvm-cov/branch-logical-mixed.test b/llvm/test/tools/llvm-cov/branch-logical-mixed.test
index b03cabeb01855..2dfbbc53b93cf 100644
--- a/llvm/test/tools/llvm-cov/branch-logical-mixed.test
+++ b/llvm/test/tools/llvm-cov/branch-logical-mixed.test
@@ -1,11 +1,11 @@
 // RUN: llvm-profdata merge %S/Inputs/branch-logical-mixed.proftext -o %t.profdata
-// RUN: llvm-cov show --show-branches=count %S/Inputs/branch-logical-mixed.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-logical-mixed.cpp -check-prefixes=CHECK,BRCOV
+// RUN: llvm-cov show --show-branches=count %S/Inputs/branch-logical-mixed.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-logical-mixed.cpp -D#C=999
 // RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-logical-mixed.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-logical-mixed.cpp
 | FileCheck %s -check-prefix=REPORT
 
 // RUN: yaml2obj %S/Inputs/branch-logical-mixed-single.yaml -o %t.o
 // RUN: llvm-profdata merge %S/Inputs/branch-logical-mixed-single.proftext -o %t.profdata
-// RUN: llvm-cov show --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/branch-logical-mixed.cpp
+// RUN: llvm-cov show --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/branch-logical-mixed.cpp -D#C=1
 // RUN: llvm-cov report --show-branch-summary %t.o -instr-profile %t.profdata -show-functions -path-equivalence=.,%S/Inputs %S/Inputs/branch-logical-mixed.cpp
 | FileCheck %s -check-prefix=REPORT
 
diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test
index a4790afc53422..0a94e63608227 100644
--- a/llvm/test/tools/llvm-cov/branch-macros.test
+++ b/llvm/test/tools/llvm-cov/branch-macros.test
@@ -1,10 +1,10 @@
 // RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata
-// RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV
+// RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV -D#C=999
 // RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=REPORT
 
 // RUN: yaml2obj %S/Inputs/branch-macros-single.yaml -o %t.o
 // RUN: llvm-profdata merge %S/Inputs/branch-macros-single.proftext -o %t.profdata
-// RUN: llvm-cov show --show-expansions --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp
+// RUN: llvm-cov show --show-expansions --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -D#C=999
 
 // REPORT:      Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
 // REPORT-NEXT: ---
diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.test b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test
index 1c1e894922827..63a49341e6c17 100644
--- a/llvm/test/tools/llvm-cov/showLineExecutionCounts.test
+++ b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test
@@ -2,14 +2,14 @@
 // RUN: rm -rf %t.dir
 // RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata
 
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE %S/Inputs/showLineExecutionCounts.cpp
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main | FileCheck -check-prefixes=TEXT,FILTER %S/Inputs/showLineExecutionCounts.cpp
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE -D#C=999 -DC16K2=16.2k -DC16K1=16.1k %S/Inputs/showLineExecutionCounts.cpp
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main | FileCheck -check-prefixes=TEXT,FILTER -D#C=999 -DC16K2=16.2k -DC16K1=16.1k %S/Inputs/showLineExecutionCounts.cpp
 
 // Test -output-dir.
 // RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t.dir/show -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs
 // RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -output-dir %t.dir/show.filtered -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main
-// RUN: FileCheck -check-prefixes=TEXT,WHOLE-FILE -input-file %t.dir/show/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp
-// RUN: FileCheck -check-prefixes=TEXT,FILTER -input-file %t.dir/show.filtered/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp
+// RUN: FileCheck -check-prefixes=TEXT,WHOLE-FILE -D#C=999 -DC16K2=16.2k -DC16K1=16.1k -input-file %t.dir/show/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp
+// RUN: FileCheck -check-prefixes=TEXT,FILTER -D#C=999 -DC16K2=16.2k -DC16K1=16.1k -input-file %t.dir/show.filtered/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp
 //
 // RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata 2>/dev/null -summary-only > %t.export-summary.json
 // RUN: not grep '"name":"main"' %t.export-summary.json
@@ -46,5 +46,5 @@
 // RUN: yaml2obj %S/Inputs/showLineExecutionCounts-single.yaml -o %t.o
 // RUN: llvm-profdata merge %S/Inputs/showLineExecutionCounts-single.proftext -o %t.profdata
 
-// RUN: llvm-cov show %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE %S/Inputs/showLineExecutionCounts.cpp
-// RUN: llvm-cov show %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs -name=main | FileCheck -check-prefixes=TEXT,FILTER %S/Inputs/showLineExecutionCounts.cpp
+// RUN: llvm-cov show %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE -D#C=161 -DC16K2=161 -DC16K1=161 %S/Inputs/showLineExecutionCounts.cpp
+// RUN: llvm-cov show %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs -name=main | FileCheck -check-prefixes=TEXT,FILTER -D#C=161 -DC16K2=161 -DC16K1=161 %S/Inputs/showLineExecutionCounts.cpp

From 805e9a93093121a3cde6c569b0247be6f68601fb Mon Sep 17 00:00:00 2001
From: NAKAMURA Takumi 
Date: Sat, 21 Dec 2024 17:32:28 +0900
Subject: [PATCH 13/35] llvm-cov: Introduce `--binary-counters`

---
 .../tools/llvm-cov/Inputs/branch-macros.cpp   | 52 +++++++++++++
 .../Inputs/showLineExecutionCounts.cpp        | 30 ++++++++
 llvm/test/tools/llvm-cov/branch-macros.cpp    | 60 ---------------
 llvm/test/tools/llvm-cov/branch-macros.test   | 12 +++
 .../llvm-cov/showLineExecutionCounts.cpp      | 73 -------------------
 .../llvm-cov/showLineExecutionCounts.test     | 46 ++++++++++++
 llvm/tools/llvm-cov/CodeCoverage.cpp          |  6 ++
 llvm/tools/llvm-cov/CoverageViewOptions.h     |  1 +
 llvm/tools/llvm-cov/SourceCoverageView.h      |  9 ++-
 .../tools/llvm-cov/SourceCoverageViewHTML.cpp | 15 ++--
 .../tools/llvm-cov/SourceCoverageViewText.cpp |  6 +-
 11 files changed, 167 insertions(+), 143 deletions(-)
 create mode 100644 llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp
 create mode 100644 llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp
 delete mode 100644 llvm/test/tools/llvm-cov/branch-macros.cpp
 create mode 100644 llvm/test/tools/llvm-cov/branch-macros.test
 delete mode 100644 llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
 create mode 100644 llvm/test/tools/llvm-cov/showLineExecutionCounts.test

diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp
new file mode 100644
index 0000000000000..ad627106f32bd
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp
@@ -0,0 +1,52 @@
+
+
+
+
+#define COND1 (a == b)
+#define COND2 (a != b)
+#define COND3 (COND1 && COND2)
+#define COND4 (COND3 ? COND2 : COND1) // BRCOV: | Branch ([[@LINE]]:15): [True: 1, False: [[#min(C,2)]]]
+#define MACRO1 COND3
+#define MACRO2 MACRO1
+#define MACRO3 MACRO2
+
+#include 
+
+// CHECK: |{{ +}}[[#min(C,3)]]|bool func(
+bool func(int a, int b) {
+  bool c = COND1 && COND2; // BRCOV: |  |  |  Branch ([[@LINE-12]]:15): [True: 1, False: [[#min(C,2)]]]
+                           // BRCOV: |  |  |  Branch ([[@LINE-12]]:15): [True: 0, False: 1]
+  bool d = COND3;          // BRCOV: |  |  |  |  |  Branch ([[@LINE-14]]:15): [True: 1, False: [[#min(C,2)]]]
+                           // BRCOV: |  |  |  |  |  Branch ([[@LINE-14]]:15): [True: 0, False: 1]
+  bool e = MACRO1;         // BRCOV: |  |  |  |  |  |  |  Branch ([[@LINE-16]]:15): [True: 1, False: [[#min(C,2)]]]
+                           // BRCOV: |  |  |  |  |  |  |  Branch ([[@LINE-16]]:15): [True: 0, False: 1]
+  bool f = MACRO2;         // BRCOV: |  |  |  |  |  |  |  |  |  Branch ([[@LINE-18]]:15): [True: 1, False: [[#min(C,2)]]]
+                           // BRCOV: |  |  |  |  |  |  |  |  |  Branch ([[@LINE-18]]:15): [True: 0, False: 1]
+  bool g = MACRO3;         // BRCOV: |  |  |  |  |  |  |  |  |  |  |  Branch ([[@LINE-20]]:15): [True: 1, False: [[#min(C,2)]]]
+                           // BRCOV: |  |  |  |  |  |  |  |  |  |  |  Branch ([[@LINE-20]]:15): [True: 0, False: 1]
+  return c && d && e && f && g;
+                           // BRCOV: |  Branch ([[@LINE-1]]:10): [True: 0, False: [[#min(C,3)]]]
+                           // BRCOV: |  Branch ([[@LINE-2]]:15): [True: 0, False: 0]
+                           // BRCOV: |  Branch ([[@LINE-3]]:20): [True: 0, False: 0]
+                           // BRCOV: |  Branch ([[@LINE-4]]:25): [True: 0, False: 0]
+                           // BRCOV: |  Branch ([[@LINE-5]]:30): [True: 0, False: 0]
+}
+
+
+bool func2(int a, int b) {
+    bool h = MACRO3 || COND4;  // BRCOV: |  |  |  |  |  |  |  |  |  |  |  Branch ([[@LINE-32]]:15): [True: 1, False: [[#min(C,2)]]]
+                               // BRCOV: |  |  |  |  |  |  |  |  |  |  |  Branch ([[@LINE-32]]:15): [True: 0, False: 1]
+                               // BRCOV: |  |  |  |  |  |  |  Branch ([[@LINE-34]]:15): [True: 1, False: [[#min(C,2)]]]
+                               // BRCOV: |  |  |  |  |  |  |  Branch ([[@LINE-34]]:15): [True: 0, False: 1]
+                               // BRCOV: |  |  |  Branch ([[@LINE-33]]:15): [True: 1, False: [[#min(C,2)]]]
+  return h;
+}
+
+
+int main(int argc, char *argv[])
+{
+  func(atoi(argv[1]), atoi(argv[2]));
+  func2(atoi(argv[1]), atoi(argv[2]));
+  (void)0;
+  return 0;
+}
diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp
new file mode 100644
index 0000000000000..be780b45f279c
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts.cpp
@@ -0,0 +1,30 @@
+// HTML-WHOLE-FILE: 
[[@LINE+2]]
// before
+// HTML-FILTER-NOT: 
[[@LINE+1]]
// before
+// before any coverage              // WHOLE-FILE: [[@LINE]]|                     |// before
+                                    // FILTER-NOT: [[@LINE-1]]|                   |// before
+// HTML: 
[[@LINE+1]]
161
int main() {
+int main() {                              // TEXT: [[@LINE]]| [[#C161:min(C,161)]]|int main(
+  int x = 0;                              // TEXT: [[@LINE]]|            [[#C161]]|  int x
+
+  if (x) {                                // TEXT: [[@LINE]]|            [[#C161]]|  if (x)
+    x = 0;                                // TEXT: [[@LINE]]|                    0|    x = 0
+  } else {                                // TEXT: [[@LINE]]|            [[#C161]]|  } else
+    x = 1;                                // TEXT: [[@LINE]]|            [[#C161]]|    x = 1
+  }                                       // TEXT: [[@LINE]]|            [[#C161]]|  }
+
+  for (int i = 0; i < 100; ++i) {         // TEXT: [[@LINE]]|            [[C16K2]]|  for (
+    x = 1;                                // TEXT: [[@LINE]]|            [[C16K1]]|    x = 1
+  }                                       // TEXT: [[@LINE]]|            [[C16K1]]|  }
+
+  x = x < 10 ? x + 1 : x - 1;             // TEXT: [[@LINE]]|            [[#C161]]|  x =
+  x = x > 10 ?                            // TEXT: [[@LINE]]|            [[#C161]]|  x =
+        x - 1:                            // TEXT: [[@LINE]]|                    0|        x
+        x + 1;                            // TEXT: [[@LINE]]|            [[#C161]]|        x
+
+  return 0;                               // TEXT: [[@LINE]]|            [[#C161]]|  return
+}                                         // TEXT: [[@LINE]]|            [[#C161]]|}
+// after coverage                   // WHOLE-FILE: [[@LINE]]|                     |// after
+                                    // FILTER-NOT: [[@LINE-1]]|                   |// after
+// HTML-BINARY-NOT: 
16
+// HTML-WHOLE-FILE: 
[[@LINE-3]]
// after
+// HTML-FILTER-NOT: 
[[@LINE-4]]
// after
diff --git a/llvm/test/tools/llvm-cov/branch-macros.cpp b/llvm/test/tools/llvm-cov/branch-macros.cpp
deleted file mode 100644
index 7f3d1e8bffb82..0000000000000
--- a/llvm/test/tools/llvm-cov/branch-macros.cpp
+++ /dev/null
@@ -1,60 +0,0 @@
-// RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata
-// RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck %s
-// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S %s | FileCheck %s -check-prefix=REPORT
-
-#define COND1 (a == b)
-#define COND2 (a != b)
-#define COND3 (COND1 && COND2)
-#define COND4 (COND3 ? COND2 : COND1) // CHECK: | Branch ([[@LINE]]:15): [True: 1, False: 2]
-#define MACRO1 COND3
-#define MACRO2 MACRO1
-#define MACRO3 MACRO2
-
-#include 
-
-
-bool func(int a, int b) {
-  bool c = COND1 && COND2; // CHECK: |  |  |  Branch ([[@LINE-12]]:15): [True: 1, False: 2]
-                           // CHECK: |  |  |  Branch ([[@LINE-12]]:15): [True: 0, False: 1]
-  bool d = COND3;          // CHECK: |  |  |  |  |  Branch ([[@LINE-14]]:15): [True: 1, False: 2]
-                           // CHECK: |  |  |  |  |  Branch ([[@LINE-14]]:15): [True: 0, False: 1]
-  bool e = MACRO1;         // CHECK: |  |  |  |  |  |  |  Branch ([[@LINE-16]]:15): [True: 1, False: 2]
-                           // CHECK: |  |  |  |  |  |  |  Branch ([[@LINE-16]]:15): [True: 0, False: 1]
-  bool f = MACRO2;         // CHECK: |  |  |  |  |  |  |  |  |  Branch ([[@LINE-18]]:15): [True: 1, False: 2]
-                           // CHECK: |  |  |  |  |  |  |  |  |  Branch ([[@LINE-18]]:15): [True: 0, False: 1]
-  bool g = MACRO3;         // CHECK: |  |  |  |  |  |  |  |  |  |  |  Branch ([[@LINE-20]]:15): [True: 1, False: 2]
-                           // CHECK: |  |  |  |  |  |  |  |  |  |  |  Branch ([[@LINE-20]]:15): [True: 0, False: 1]
-  return c && d && e && f && g;
-                           // CHECK: |  Branch ([[@LINE-1]]:10): [True: 0, False: 3]
-                           // CHECK: |  Branch ([[@LINE-2]]:15): [True: 0, False: 0]
-                           // CHECK: |  Branch ([[@LINE-3]]:20): [True: 0, False: 0]
-                           // CHECK: |  Branch ([[@LINE-4]]:25): [True: 0, False: 0]
-                           // CHECK: |  Branch ([[@LINE-5]]:30): [True: 0, False: 0]
-}
-
-
-bool func2(int a, int b) {
-    bool h = MACRO3 || COND4;  // CHECK: |  |  |  |  |  |  |  |  |  |  |  Branch ([[@LINE-32]]:15): [True: 1, False: 2]
-                               // CHECK: |  |  |  |  |  |  |  |  |  |  |  Branch ([[@LINE-32]]:15): [True: 0, False: 1]
-                               // CHECK: |  |  |  |  |  |  |  Branch ([[@LINE-34]]:15): [True: 1, False: 2]
-                               // CHECK: |  |  |  |  |  |  |  Branch ([[@LINE-34]]:15): [True: 0, False: 1]
-                               // CHECK: |  |  |  Branch ([[@LINE-33]]:15): [True: 1, False: 2]
-  return h;
-}
-
-extern "C" { extern void __llvm_profile_write_file(void); }
-int main(int argc, char *argv[])
-{
-  func(atoi(argv[1]), atoi(argv[2]));
-  func2(atoi(argv[1]), atoi(argv[2]));
-  __llvm_profile_write_file();
-  return 0;
-}
-
-// REPORT: Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
-// REPORT-NEXT: ---
-// REPORT-NEXT: _Z4funcii                        28       4  85.71%        18       0 100.00%        30      14  53.33%
-// REPORT-NEXT: _Z5func2ii                       13       1  92.31%         8       0 100.00%        10       2  80.00%
-// REPORT-NEXT: main                              1       0 100.00%         6       0 100.00%         0       0   0.00%
-// REPORT-NEXT: ---
-// REPORT-NEXT: TOTAL                            42       5  88.10%        32       0 100.00% 40      16  60.00%
diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test
new file mode 100644
index 0000000000000..547a79ff94124
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/branch-macros.test
@@ -0,0 +1,12 @@
+// RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata
+// RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV -D#C=999
+// RUN: llvm-cov show --binary-counters=true --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV -D#C=1
+// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=REPORT
+
+// REPORT:      Name                        Regions    Miss   Cover     Lines    Miss   Cover  Branches    Miss   Cover
+// REPORT-NEXT: ---
+// REPORT-NEXT: _Z4funcii                        28       4  85.71%        18       0 100.00%        30      14  53.33%
+// REPORT-NEXT: _Z5func2ii                       13       1  92.31%         8       0 100.00%        10       2  80.00%
+// REPORT-NEXT: main                              1       0 100.00%         6       0 100.00%         0       0   0.00%
+// REPORT-NEXT: ---
+// REPORT-NEXT: TOTAL                            42       5  88.10%        32       0 100.00%        40      16  60.00%
diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp b/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
deleted file mode 100644
index f72a9978b8a73..0000000000000
--- a/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
+++ /dev/null
@@ -1,73 +0,0 @@
-// Basic handling of line counts.
-// RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata
-
-// before any coverage              // WHOLE-FILE: [[@LINE]]|      |// before
-                                    // FILTER-NOT: [[@LINE-1]]|    |// before
-int main() {                              // TEXT: [[@LINE]]|   161|int main(
-  int x = 0;                              // TEXT: [[@LINE]]|   161|  int x
-                                          // TEXT: [[@LINE]]|   161|
-  if (x) {                                // TEXT: [[@LINE]]|   161|  if (x)
-    x = 0;                                // TEXT: [[@LINE]]|     0|    x = 0
-  } else {                                // TEXT: [[@LINE]]|   161|  } else
-    x = 1;                                // TEXT: [[@LINE]]|   161|    x = 1
-  }                                       // TEXT: [[@LINE]]|   161|  }
-                                          // TEXT: [[@LINE]]|   161|
-  for (int i = 0; i < 100; ++i) {         // TEXT: [[@LINE]]| 16.2k|  for (
-    x = 1;                                // TEXT: [[@LINE]]| 16.1k|    x = 1
-  }                                       // TEXT: [[@LINE]]| 16.1k|  }
-                                          // TEXT: [[@LINE]]|   161|
-  x = x < 10 ? x + 1 : x - 1;             // TEXT: [[@LINE]]|   161|  x =
-  x = x > 10 ?                            // TEXT: [[@LINE]]|   161|  x =
-        x - 1:                            // TEXT: [[@LINE]]|     0|        x
-        x + 1;                            // TEXT: [[@LINE]]|   161|        x
-                                          // TEXT: [[@LINE]]|   161|
-  return 0;                               // TEXT: [[@LINE]]|   161|  return
-}                                         // TEXT: [[@LINE]]|   161|}
-// after coverage                   // WHOLE-FILE: [[@LINE]]|      |// after
-                                    // FILTER-NOT: [[@LINE-1]]|    |// after
-
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S %s | FileCheck -check-prefixes=TEXT,WHOLE-FILE %s
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S -name=main %s | FileCheck -check-prefixes=TEXT,FILTER %s
-
-// Test -output-dir.
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S %s
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -output-dir %t.filtered.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S -name=main %s
-// RUN: FileCheck -check-prefixes=TEXT,WHOLE-FILE -input-file %t.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %s
-// RUN: FileCheck -check-prefixes=TEXT,FILTER -input-file %t.filtered.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %s
-//
-// RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata 2>/dev/null -summary-only > %t.export-summary.json
-// RUN: not grep '"name":"main"' %t.export-summary.json
-//
-// Test html output.
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.html.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S %s
-// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.html.filtered.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S -name=main %s
-// RUN: FileCheck -check-prefixes=HTML,HTML-WHOLE-FILE -input-file %t.html.dir/coverage/tmp/showLineExecutionCounts.cpp.html %s
-// RUN: FileCheck -check-prefixes=HTML,HTML-FILTER -input-file %t.html.filtered.dir/coverage/tmp/showLineExecutionCounts.cpp.html %s
-//
-// HTML-WHOLE-FILE: 
4
// before
-// HTML-FILTER-NOT: 
4
// before
-// HTML: 
6
161
int main() {
-// HTML-WHOLE-FILE: 
26
// after
-// HTML-FILTER-NOT: 
26
// after
-//
-// Test index creation.
-// RUN: FileCheck -check-prefix=TEXT-INDEX -input-file %t.dir/index.txt %s
-// TEXT-INDEX: Filename
-// TEXT-INDEX-NEXT: ---
-// TEXT-INDEX-NEXT: {{.*}}showLineExecutionCounts.cpp
-//
-// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.html.dir/index.html %s
-// HTML-INDEX-LABEL: 
-// HTML-INDEX: 
-// HTML-INDEX: 
-// HTML-INDEX: 
-// HTML-INDEX: 
-// HTML-INDEX: 
-// HTML-INDEX: 
-// HTML-INDEX: Totals
diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.test b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test
new file mode 100644
index 0000000000000..3c24ec2094c97
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test
@@ -0,0 +1,46 @@
+// Basic handling of line counts.
+// RUN: rm -rf %t.dir
+// RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata
+
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE -D#C=999 -DC16K2=16.2k -DC16K1=16.1k %S/Inputs/showLineExecutionCounts.cpp
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -binary-counters=true -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE -D#C=1 -DC16K2=1 -DC16K1=1 %S/Inputs/showLineExecutionCounts.cpp
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main | FileCheck -check-prefixes=TEXT,FILTER -D#C=999 -DC16K2=16.2k -DC16K1=16.1k %S/Inputs/showLineExecutionCounts.cpp
+
+// Test -output-dir.
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t.dir/show -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -output-dir %t.dir/show.filtered -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main
+// RUN: FileCheck -check-prefixes=TEXT,WHOLE-FILE -D#C=999 -DC16K2=16.2k -DC16K1=16.1k -input-file %t.dir/show/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp
+// RUN: FileCheck -check-prefixes=TEXT,FILTER -D#C=999 -DC16K2=16.2k -DC16K1=16.1k -input-file %t.dir/show.filtered/coverage/tmp/showLineExecutionCounts.cpp.txt %S/Inputs/showLineExecutionCounts.cpp
+//
+// RUN: llvm-cov export %S/Inputs/lineExecutionCounts.covmapping -instr-profile %t.profdata 2>/dev/null -summary-only > %t.export-summary.json
+// RUN: not grep '"name":"main"' %t.export-summary.json
+//
+// Test html output.
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.dir/html -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.dir/html.binary -binary-counters=true -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs
+// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.dir/html.filtered -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs -name=main
+// RUN: FileCheck -check-prefixes=HTML,HTML-WHOLE-FILE -input-file %t.dir/html/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp
+// RUN: FileCheck -check-prefixes=HTML-BINARY,HTML-WHOLE-FILE -input-file %t.dir/html.binary/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp
+// RUN: FileCheck -check-prefixes=HTML,HTML-FILTER -input-file %t.dir/html.filtered/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp
+//
+// Test index creation.
+// RUN: FileCheck -check-prefix=TEXT-INDEX -input-file %t.dir/show/index.txt %s
+// TEXT-INDEX: Filename
+// TEXT-INDEX-NEXT: ---
+// TEXT-INDEX-NEXT: {{.*}}showLineExecutionCounts.cpp
+//
+// RUN: FileCheck -check-prefix HTML-INDEX -input-file %t.dir/html/index.html %s
+// HTML-INDEX-LABEL: 
FilenameFunction CoverageLine CoverageRegion Coverage -// HTML-INDEX: 100.00% (1/1) -// HTML-INDEX: -// HTML-INDEX: 90.00% (18/20) -// HTML-INDEX: -// HTML-INDEX: 72.73% (8/11) -// HTML-INDEX:
+// HTML-INDEX: +// HTML-INDEX: +// HTML-INDEX: +// HTML-INDEX: +// HTML-INDEX: +// HTML-INDEX: +// HTML-INDEX: Totals diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index 5db5c2e023541..0e8360a4ac6ed 100644 --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -1023,6 +1023,11 @@ int CodeCoverageTool::doShow(int argc, const char **argv, cl::alias ShowOutputDirectoryA("o", cl::desc("Alias for --output-dir"), cl::aliasopt(ShowOutputDirectory)); + cl::opt BinaryCounters( + "binary-counters", cl::Optional, + cl::desc("Show 1/0 instead of actual counter values."), + cl::cat(ViewCategory)); + cl::opt TabSize( "tab-size", cl::init(2), cl::desc( @@ -1100,6 +1105,7 @@ int CodeCoverageTool::doShow(int argc, const char **argv, ViewOpts.ShowFunctionInstantiations = ShowInstantiations; ViewOpts.ShowDirectoryCoverage = ShowDirectoryCoverage; ViewOpts.ShowOutputDirectory = ShowOutputDirectory; + ViewOpts.BinaryCounters = BinaryCounters; ViewOpts.TabSize = TabSize; ViewOpts.ProjectTitle = ProjectTitle; diff --git a/llvm/tools/llvm-cov/CoverageViewOptions.h b/llvm/tools/llvm-cov/CoverageViewOptions.h index 6925cffd8246d..b8d1a8b2d7c9b 100644 --- a/llvm/tools/llvm-cov/CoverageViewOptions.h +++ b/llvm/tools/llvm-cov/CoverageViewOptions.h @@ -45,6 +45,7 @@ struct CoverageViewOptions { bool SkipExpansions; bool SkipFunctions; bool SkipBranches; + bool BinaryCounters; OutputFormat Format; BranchOutputType ShowBranches; std::string ShowOutputDirectory; diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h index 2b1570d399dd0..9b72ca03c6d7f 100644 --- a/llvm/tools/llvm-cov/SourceCoverageView.h +++ b/llvm/tools/llvm-cov/SourceCoverageView.h @@ -180,6 +180,8 @@ class SourceCoverageView { /// on display. std::vector InstantiationSubViews; + bool BinaryCounters; + /// Get the first uncovered line number for the source file. unsigned getFirstUncoveredLineNo(); @@ -266,6 +268,10 @@ class SourceCoverageView { /// digits. static std::string formatCount(uint64_t N); + uint64_t Count1(uint64_t N) const { return (N && BinaryCounters ? 1 : N); } + + std::string formatCount1(uint64_t N) const { return formatCount(Count1(N)); } + /// Check if region marker output is expected for a line. bool shouldRenderRegionMarkers(const LineCoverageStats &LCS) const; @@ -276,7 +282,8 @@ class SourceCoverageView { const CoverageViewOptions &Options, CoverageData &&CoverageInfo) : SourceName(SourceName), File(File), Options(Options), - CoverageInfo(std::move(CoverageInfo)) {} + CoverageInfo(std::move(CoverageInfo)), + BinaryCounters(Options.BinaryCounters) {} public: static std::unique_ptr diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp index e2be576b93cda..f3aa7e801597c 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp @@ -1019,19 +1019,22 @@ void SourceCoverageViewHTML::renderLine(raw_ostream &OS, LineRef L, // Just consider the segments which start *and* end on this line. for (unsigned I = 0, E = Segments.size() - 1; I < E; ++I) { const auto *CurSeg = Segments[I]; + auto CurSegCount = Count1(CurSeg->Count); + auto LCSCount = Count1(LCS.getExecutionCount()); if (!CurSeg->IsRegionEntry) continue; - if (CurSeg->Count == LCS.getExecutionCount()) + if (CurSegCount == LCSCount) continue; Snippets[I + 1] = - tag("div", Snippets[I + 1] + tag("span", formatCount(CurSeg->Count), - "tooltip-content"), + tag("div", + Snippets[I + 1] + + tag("span", formatCount(CurSegCount), "tooltip-content"), "tooltip"); if (getOptions().Debug) errs() << "Marker at " << CurSeg->Line << ":" << CurSeg->Col << " = " - << formatCount(CurSeg->Count) << "\n"; + << formatCount(CurSegCount) << "\n"; } } @@ -1051,7 +1054,7 @@ void SourceCoverageViewHTML::renderLineCoverageColumn( raw_ostream &OS, const LineCoverageStats &Line) { std::string Count; if (Line.isMapped()) - Count = tag("pre", formatCount(Line.getExecutionCount())); + Count = tag("pre", formatCount1(Line.getExecutionCount())); std::string CoverageClass = (Line.getExecutionCount() > 0) ? "covered-line" @@ -1106,7 +1109,7 @@ void SourceCoverageViewHTML::renderBranchView(raw_ostream &OS, BranchView &BRV, OS << tag("span", Label, (Count ? "None" : "red branch")) << ": "; if (getOptions().ShowBranchCounts) - OS << tag("span", formatCount(Count), + OS << tag("span", formatCount1(Count), (Count ? "covered-line" : "uncovered-line")); else OS << format("%0.2f", (Total != 0 ? 100.0 * Count / Total : 0.0)) << "%"; diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp index 63f8248e3387b..f0c366e45c2c9 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp @@ -216,7 +216,7 @@ void SourceCoverageViewText::renderLineCoverageColumn( OS.indent(LineCoverageColumnWidth) << '|'; return; } - std::string C = formatCount(Line.getExecutionCount()); + std::string C = formatCount1(Line.getExecutionCount()); OS.indent(LineCoverageColumnWidth - C.size()); colored_ostream(OS, raw_ostream::MAGENTA, Line.hasMultipleRegions() && getOptions().Colors) @@ -263,7 +263,7 @@ void SourceCoverageViewText::renderRegionMarkers(raw_ostream &OS, if (getOptions().Debug) errs() << "Marker at " << S->Line << ":" << S->Col << " = " - << formatCount(S->Count) << "\n"; + << formatCount1(S->Count) << "\n"; } OS << '\n'; } @@ -307,7 +307,7 @@ void SourceCoverageViewText::renderBranchView(raw_ostream &OS, BranchView &BRV, << Label; if (getOptions().ShowBranchCounts) - OS << ": " << formatCount(Count); + OS << ": " << formatCount1(Count); else OS << ": " << format("%0.2f", (Total != 0 ? 100.0 * Count / Total : 0.0)) << "%"; From 5b6c0b02c00fb861877e8a35cdf9842b76e33f2c Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 21 Dec 2024 17:53:19 +0900 Subject: [PATCH 14/35] LLVMCoverage: Unify getCoverageForFile and getCoverageForFunction --- .../ProfileData/Coverage/CoverageMapping.h | 3 + .../ProfileData/Coverage/CoverageMapping.cpp | 77 ++++++++++--------- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 42da188fef34e..be902a20efc47 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -889,6 +889,7 @@ class InstantiationGroup { class CoverageData { friend class CoverageMapping; +protected: std::string Filename; std::vector Segments; std::vector Expansions; @@ -900,6 +901,8 @@ class CoverageData { CoverageData(StringRef Filename) : Filename(Filename) {} + 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 d51448567539f..c6756fafb268a 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -1343,6 +1343,36 @@ class SegmentBuilder { } }; +struct MergeableCoverageData : public CoverageData { + std::vector CodeRegions; + + MergeableCoverageData(StringRef Filename) : CoverageData(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 { @@ -1393,8 +1423,7 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) { } CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { - CoverageData FileCoverage(Filename); - std::vector Regions; + MergeableCoverageData FileCoverage(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. @@ -1404,26 +1433,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 @@ -1457,29 +1474,15 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { if (!MainFileID) return CoverageData(); - CoverageData FunctionCoverage(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(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( From 24457a7236f5dc76e49c78817b5a0de6ce4f7f93 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 22 Dec 2024 00:42:02 +0900 Subject: [PATCH 15/35] Update tests --- llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp | 2 +- llvm/test/tools/llvm-cov/branch-macros.test | 2 +- llvm/test/tools/llvm-cov/showLineExecutionCounts.test | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp index 246b0389aa600..cce61784f9c48 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp @@ -4,7 +4,7 @@ #include #include -// CHECK: |{{ +}}[[C4:4|1]]|void func( +// CHECK: | [[#min(C,4)]]|void func( void func(int a, int b) { bool b0 = a <= b; bool b1 = a == b; diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test index 0a94e63608227..e4bd14ec14f16 100644 --- a/llvm/test/tools/llvm-cov/branch-macros.test +++ b/llvm/test/tools/llvm-cov/branch-macros.test @@ -4,7 +4,7 @@ // RUN: yaml2obj %S/Inputs/branch-macros-single.yaml -o %t.o // RUN: llvm-profdata merge %S/Inputs/branch-macros-single.proftext -o %t.profdata -// RUN: llvm-cov show --show-expansions --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -D#C=999 +// RUN: llvm-cov show --show-expansions --show-branches=count %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -D#C=1 // REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover // REPORT-NEXT: --- diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.test b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test index 63a49341e6c17..4f505f9648eb8 100644 --- a/llvm/test/tools/llvm-cov/showLineExecutionCounts.test +++ b/llvm/test/tools/llvm-cov/showLineExecutionCounts.test @@ -46,5 +46,5 @@ // RUN: yaml2obj %S/Inputs/showLineExecutionCounts-single.yaml -o %t.o // RUN: llvm-profdata merge %S/Inputs/showLineExecutionCounts-single.proftext -o %t.profdata -// RUN: llvm-cov show %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE -D#C=161 -DC16K2=161 -DC16K1=161 %S/Inputs/showLineExecutionCounts.cpp -// RUN: llvm-cov show %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs -name=main | FileCheck -check-prefixes=TEXT,FILTER -D#C=161 -DC16K2=161 -DC16K1=161 %S/Inputs/showLineExecutionCounts.cpp +// RUN: llvm-cov show %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck -check-prefixes=TEXT,WHOLE-FILE -D#C=1 -DC16K2=1 -DC16K1=1 %S/Inputs/showLineExecutionCounts.cpp +// RUN: llvm-cov show %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs -name=main | FileCheck -check-prefixes=TEXT,FILTER -D#C=1 -DC16K2=1 -DC16K1=1 %S/Inputs/showLineExecutionCounts.cpp From f96b435e3c762fd6ae94eced63862289538b2a21 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 22 Dec 2024 00:48:52 +0900 Subject: [PATCH 16/35] New SingleByteCoverage --- .../ProfileData/Coverage/CoverageMapping.h | 34 +++++++++++-------- .../ProfileData/Coverage/CoverageMapping.cpp | 31 +++++++---------- llvm/tools/llvm-cov/SourceCoverageView.h | 3 +- 3 files changed, 33 insertions(+), 35 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 42da188fef34e..42aea623be165 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -364,19 +364,16 @@ struct CountedRegion : public CounterMappingRegion { uint64_t FalseExecutionCount; bool TrueFolded; bool FalseFolded; - bool HasSingleByteCoverage; - CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount, - bool HasSingleByteCoverage) + CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount) : CounterMappingRegion(R), ExecutionCount(ExecutionCount), - FalseExecutionCount(0), TrueFolded(false), FalseFolded(true), - HasSingleByteCoverage(HasSingleByteCoverage) {} + FalseExecutionCount(0), TrueFolded(false), FalseFolded(true) {} CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount, - uint64_t FalseExecutionCount, bool HasSingleByteCoverage) + uint64_t FalseExecutionCount) : CounterMappingRegion(R), ExecutionCount(ExecutionCount), FalseExecutionCount(FalseExecutionCount), TrueFolded(false), - FalseFolded(false), HasSingleByteCoverage(HasSingleByteCoverage) {} + FalseFolded(false) {} }; /// MCDC Record grouping all information together. @@ -719,10 +716,9 @@ struct FunctionRecord { } void pushRegion(CounterMappingRegion Region, uint64_t Count, - uint64_t FalseCount, bool HasSingleByteCoverage) { + uint64_t FalseCount) { if (Region.isBranch()) { - CountedBranchRegions.emplace_back(Region, Count, FalseCount, - HasSingleByteCoverage); + CountedBranchRegions.emplace_back(Region, Count, FalseCount); // If either counter is hard-coded to zero, then this region represents a // constant-folded branch. CountedBranchRegions.back().TrueFolded = Region.Count.isZero(); @@ -731,8 +727,7 @@ struct FunctionRecord { } if (CountedRegions.empty()) ExecutionCount = Count; - CountedRegions.emplace_back(Region, Count, FalseCount, - HasSingleByteCoverage); + CountedRegions.emplace_back(Region, Count, FalseCount); } }; @@ -895,14 +890,19 @@ class CoverageData { std::vector BranchRegions; std::vector MCDCRecords; + bool SingleByteCoverage; + public: - CoverageData() = default; + CoverageData() = delete; - CoverageData(StringRef Filename) : Filename(Filename) {} + CoverageData(bool Single, StringRef Filename = StringRef()) + : Filename(Filename), SingleByteCoverage(Single) {} /// Get the name of the file this data covers. StringRef getFilename() const { return Filename; } + bool getSingleByteCoverage() const { return SingleByteCoverage; } + /// Get an iterator over the coverage segments for this object. The segments /// are guaranteed to be uniqued and sorted by location. std::vector::const_iterator begin() const { @@ -935,7 +935,9 @@ class CoverageMapping { DenseMap> FilenameHash2RecordIndices; std::vector> FuncHashMismatches; - CoverageMapping() = default; + bool SingleByteCoverage; + + CoverageMapping(bool Single) : SingleByteCoverage(Single) {} // Load coverage records from readers. static Error loadFromReaders( @@ -979,6 +981,8 @@ class CoverageMapping { const object::BuildIDFetcher *BIDFetcher = nullptr, bool CheckBinaryIDs = false); + bool getSingleByteCoverage() const { return SingleByteCoverage; } + /// The number of functions that couldn't have their profiles mapped. /// /// This is a count of functions whose profile is out of date or otherwise diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 87d8bb1bbb79c..430e68ea94a02 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -805,7 +805,6 @@ Error CoverageMapping::loadFunctionRecord( else OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]); - bool SingleByteCoverage = ProfileReader.hasSingleByteCoverage(); CounterMappingContext Ctx(Record.Expressions); std::vector Counts; @@ -871,10 +870,7 @@ Error CoverageMapping::loadFunctionRecord( consumeError(std::move(E)); return Error::success(); } - Function.pushRegion( - Region, (SingleByteCoverage && *ExecutionCount ? 1 : *ExecutionCount), - (SingleByteCoverage && *AltExecutionCount ? 1 : *AltExecutionCount), - SingleByteCoverage); + Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount); // Record ExpansionRegion. if (Region.Kind == CounterMappingRegion::ExpansionRegion) { @@ -951,7 +947,8 @@ Error CoverageMapping::loadFromReaders( Expected> CoverageMapping::load( ArrayRef> CoverageReaders, IndexedInstrProfReader &ProfileReader) { - auto Coverage = std::unique_ptr(new CoverageMapping()); + auto Coverage = std::unique_ptr( + new CoverageMapping(ProfileReader.hasSingleByteCoverage())); if (Error E = loadFromReaders(CoverageReaders, ProfileReader, *Coverage)) return std::move(E); return std::move(Coverage); @@ -1013,7 +1010,8 @@ Expected> CoverageMapping::load( if (Error E = ProfileReaderOrErr.takeError()) return createFileError(ProfileFilename, std::move(E)); auto ProfileReader = std::move(ProfileReaderOrErr.get()); - auto Coverage = std::unique_ptr(new CoverageMapping()); + auto Coverage = std::unique_ptr( + new CoverageMapping(ProfileReader->hasSingleByteCoverage())); bool DataFound = false; auto GetArch = [&](size_t Idx) { @@ -1296,14 +1294,8 @@ class SegmentBuilder { // value for that area. // We add counts of the regions of the same kind as the active region // to handle the both situations. - if (I->Kind == Active->Kind) { - assert(I->HasSingleByteCoverage == Active->HasSingleByteCoverage && - "Regions are generated in different coverage modes"); - if (I->HasSingleByteCoverage) - Active->ExecutionCount = Active->ExecutionCount || I->ExecutionCount; - else - Active->ExecutionCount += I->ExecutionCount; - } + if (I->Kind == Active->Kind) + Active->ExecutionCount += I->ExecutionCount; } return Regions.drop_back(std::distance(++Active, End)); } @@ -1396,7 +1388,7 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) { } CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { - CoverageData FileCoverage(Filename); + CoverageData FileCoverage(SingleByteCoverage, Filename); std::vector Regions; // Look up the function records in the given file. Due to hash collisions on @@ -1458,9 +1450,10 @@ CoverageData CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { auto MainFileID = findMainViewFileID(Function); if (!MainFileID) - return CoverageData(); + return CoverageData(SingleByteCoverage); - CoverageData FunctionCoverage(Function.Filenames[*MainFileID]); + CoverageData FunctionCoverage(SingleByteCoverage, + Function.Filenames[*MainFileID]); std::vector Regions; for (const auto &CR : Function.CountedRegions) if (CR.FileID == *MainFileID) { @@ -1488,7 +1481,7 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { CoverageData CoverageMapping::getCoverageForExpansion( const ExpansionRecord &Expansion) const { CoverageData ExpansionCoverage( - Expansion.Function.Filenames[Expansion.FileID]); + SingleByteCoverage, Expansion.Function.Filenames[Expansion.FileID]); std::vector Regions; for (const auto &CR : Expansion.Function.CountedRegions) if (CR.FileID == Expansion.FileID) { diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h index 9b72ca03c6d7f..ed7e133d71e08 100644 --- a/llvm/tools/llvm-cov/SourceCoverageView.h +++ b/llvm/tools/llvm-cov/SourceCoverageView.h @@ -283,7 +283,8 @@ class SourceCoverageView { CoverageData &&CoverageInfo) : SourceName(SourceName), File(File), Options(Options), CoverageInfo(std::move(CoverageInfo)), - BinaryCounters(Options.BinaryCounters) {} + BinaryCounters(Options.BinaryCounters || + CoverageInfo.getSingleByteCoverage()) {} public: static std::unique_ptr From 47550d1cc07ba6407020d2a9417bb48bdc3a5156 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 22 Dec 2024 11:32:00 +0900 Subject: [PATCH 17/35] threads.c => threads.test (following #113114) --- llvm/test/tools/llvm-cov/threads.c | 11 ----------- llvm/test/tools/llvm-cov/threads.test | 12 ++++++++++++ 2 files changed, 12 insertions(+), 11 deletions(-) delete mode 100644 llvm/test/tools/llvm-cov/threads.c create mode 100644 llvm/test/tools/llvm-cov/threads.test diff --git a/llvm/test/tools/llvm-cov/threads.c b/llvm/test/tools/llvm-cov/threads.c deleted file mode 100644 index b162b6ac5a801..0000000000000 --- a/llvm/test/tools/llvm-cov/threads.c +++ /dev/null @@ -1,11 +0,0 @@ -// Coverage/profile data recycled from the showLineExecutionCounts.cpp test. -// -// RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -j 1 -o %t1.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S %S/showLineExecutionCounts.cpp -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -num-threads 2 -o %t2.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S %S/showLineExecutionCounts.cpp -// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t3.dir -instr-profile %t.profdata -path-equivalence=/tmp,%S %S/showLineExecutionCounts.cpp -// -// RUN: diff %t1.dir/index.txt %t2.dir/index.txt -// RUN: diff %t1.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %t2.dir/coverage/tmp/showLineExecutionCounts.cpp.txt -// RUN: diff %t1.dir/index.txt %t3.dir/index.txt -// RUN: diff %t1.dir/coverage/tmp/showLineExecutionCounts.cpp.txt %t3.dir/coverage/tmp/showLineExecutionCounts.cpp.txt diff --git a/llvm/test/tools/llvm-cov/threads.test b/llvm/test/tools/llvm-cov/threads.test new file mode 100644 index 0000000000000..a51406ca14efa --- /dev/null +++ b/llvm/test/tools/llvm-cov/threads.test @@ -0,0 +1,12 @@ +// Coverage/profile data recycled from the showLineExecutionCounts.cpp test. +// +// RUN: rm -rf %t.dir +// RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -j 1 -o %t.dir/1 -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -num-threads 2 -o %t.dir/2 -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs +// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -o %t.dir/3 -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs +// +// RUN: diff %t.dir/1/index.txt %t.dir/2/index.txt +// RUN: diff %t.dir/1/coverage/tmp/showLineExecutionCounts.cpp.txt %t.dir/2/coverage/tmp/showLineExecutionCounts.cpp.txt +// RUN: diff %t.dir/1/index.txt %t.dir/3/index.txt +// RUN: diff %t.dir/1/coverage/tmp/showLineExecutionCounts.cpp.txt %t.dir/3/coverage/tmp/showLineExecutionCounts.cpp.txt From f4dc4ebfd585869455be0e9f37294b7037ca9a65 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 23 Dec 2024 15:57:36 +0900 Subject: [PATCH 18/35] s/Count1/BinaryCount/ --- llvm/tools/llvm-cov/SourceCoverageView.h | 8 ++++++-- llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp | 8 ++++---- llvm/tools/llvm-cov/SourceCoverageViewText.cpp | 6 +++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h index 9b72ca03c6d7f..0b4e3978a4ba9 100644 --- a/llvm/tools/llvm-cov/SourceCoverageView.h +++ b/llvm/tools/llvm-cov/SourceCoverageView.h @@ -268,9 +268,13 @@ class SourceCoverageView { /// digits. static std::string formatCount(uint64_t N); - uint64_t Count1(uint64_t N) const { return (N && BinaryCounters ? 1 : N); } + uint64_t BinaryCount(uint64_t N) const { + return (N && BinaryCounters ? 1 : N); + } - std::string formatCount1(uint64_t N) const { return formatCount(Count1(N)); } + std::string formatBinaryCount(uint64_t N) const { + return formatCount(BinaryCount(N)); + } /// Check if region marker output is expected for a line. bool shouldRenderRegionMarkers(const LineCoverageStats &LCS) const; diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp index f3aa7e801597c..c94d3853fc014 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp @@ -1019,8 +1019,8 @@ void SourceCoverageViewHTML::renderLine(raw_ostream &OS, LineRef L, // Just consider the segments which start *and* end on this line. for (unsigned I = 0, E = Segments.size() - 1; I < E; ++I) { const auto *CurSeg = Segments[I]; - auto CurSegCount = Count1(CurSeg->Count); - auto LCSCount = Count1(LCS.getExecutionCount()); + auto CurSegCount = BinaryCount(CurSeg->Count); + auto LCSCount = BinaryCount(LCS.getExecutionCount()); if (!CurSeg->IsRegionEntry) continue; if (CurSegCount == LCSCount) @@ -1054,7 +1054,7 @@ void SourceCoverageViewHTML::renderLineCoverageColumn( raw_ostream &OS, const LineCoverageStats &Line) { std::string Count; if (Line.isMapped()) - Count = tag("pre", formatCount1(Line.getExecutionCount())); + Count = tag("pre", formatBinaryCount(Line.getExecutionCount())); std::string CoverageClass = (Line.getExecutionCount() > 0) ? "covered-line" @@ -1109,7 +1109,7 @@ void SourceCoverageViewHTML::renderBranchView(raw_ostream &OS, BranchView &BRV, OS << tag("span", Label, (Count ? "None" : "red branch")) << ": "; if (getOptions().ShowBranchCounts) - OS << tag("span", formatCount1(Count), + OS << tag("span", formatBinaryCount(Count), (Count ? "covered-line" : "uncovered-line")); else OS << format("%0.2f", (Total != 0 ? 100.0 * Count / Total : 0.0)) << "%"; diff --git a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp index f0c366e45c2c9..765f8bbbd8d1b 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewText.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewText.cpp @@ -216,7 +216,7 @@ void SourceCoverageViewText::renderLineCoverageColumn( OS.indent(LineCoverageColumnWidth) << '|'; return; } - std::string C = formatCount1(Line.getExecutionCount()); + std::string C = formatBinaryCount(Line.getExecutionCount()); OS.indent(LineCoverageColumnWidth - C.size()); colored_ostream(OS, raw_ostream::MAGENTA, Line.hasMultipleRegions() && getOptions().Colors) @@ -263,7 +263,7 @@ void SourceCoverageViewText::renderRegionMarkers(raw_ostream &OS, if (getOptions().Debug) errs() << "Marker at " << S->Line << ":" << S->Col << " = " - << formatCount1(S->Count) << "\n"; + << formatBinaryCount(S->Count) << "\n"; } OS << '\n'; } @@ -307,7 +307,7 @@ void SourceCoverageViewText::renderBranchView(raw_ostream &OS, BranchView &BRV, << Label; if (getOptions().ShowBranchCounts) - OS << ": " << formatCount1(Count); + OS << ": " << formatBinaryCount(Count); else OS << ": " << format("%0.2f", (Total != 0 ? 100.0 * Count / Total : 0.0)) << "%"; From 822620bea235792675202045b2b7d138aa069f0e Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 23 Dec 2024 15:55:49 +0900 Subject: [PATCH 19/35] Update desc --- llvm/tools/llvm-cov/CodeCoverage.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index 0e8360a4ac6ed..2d6da7efc6979 100644 --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -1025,7 +1025,8 @@ int CodeCoverageTool::doShow(int argc, const char **argv, cl::opt BinaryCounters( "binary-counters", cl::Optional, - cl::desc("Show 1/0 instead of actual counter values."), + cl::desc("Show when lines/branches are covered (1) or uncovered (0) " + "instead of showing actual counter values."), cl::cat(ViewCategory)); cl::opt TabSize( From dfc99bad0fd0baa6e0d9a39554da041dd02d6568 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 24 Dec 2024 17:29:27 +0900 Subject: [PATCH 20/35] Fix wrong merge resolutions --- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 21a296d89d214..430e68ea94a02 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -805,7 +805,6 @@ Error CoverageMapping::loadFunctionRecord( else OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]); - bool SingleByteCoverage = ProfileReader.hasSingleByteCoverage(); CounterMappingContext Ctx(Record.Expressions); std::vector Counts; @@ -871,10 +870,7 @@ Error CoverageMapping::loadFunctionRecord( consumeError(std::move(E)); return Error::success(); } - Function.pushRegion( - Region, (SingleByteCoverage && *ExecutionCount ? 1 : *ExecutionCount), - (SingleByteCoverage && *AltExecutionCount ? 1 : *AltExecutionCount), - SingleByteCoverage); + Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount); // Record ExpansionRegion. if (Region.Kind == CounterMappingRegion::ExpansionRegion) { From f3c9593037e8dbc4a5c9c5e5a5d5801e801019c4 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 25 Dec 2024 08:40:39 +0900 Subject: [PATCH 21/35] Reorganize CoverageMapping::SingleByteCoverage --- .../ProfileData/Coverage/CoverageMapping.h | 12 +++++------ .../ProfileData/Coverage/CoverageMapping.cpp | 20 +++++++++++-------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 42aea623be165..705a9f28c1241 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -890,12 +890,12 @@ class CoverageData { std::vector BranchRegions; std::vector MCDCRecords; - bool SingleByteCoverage; + bool SingleByteCoverage = false; public: - CoverageData() = delete; + CoverageData() = default; - CoverageData(bool Single, StringRef Filename = StringRef()) + CoverageData(bool Single, StringRef Filename) : Filename(Filename), SingleByteCoverage(Single) {} /// Get the name of the file this data covers. @@ -935,9 +935,9 @@ class CoverageMapping { DenseMap> FilenameHash2RecordIndices; std::vector> FuncHashMismatches; - bool SingleByteCoverage; + std::optional SingleByteCoverage; - CoverageMapping(bool Single) : SingleByteCoverage(Single) {} + CoverageMapping() = default; // Load coverage records from readers. static Error loadFromReaders( @@ -981,7 +981,7 @@ class CoverageMapping { const object::BuildIDFetcher *BIDFetcher = nullptr, bool CheckBinaryIDs = false); - bool getSingleByteCoverage() const { return SingleByteCoverage; } + // bool getSingleByteCoverage() const { return SingleByteCoverage; } /// The number of functions that couldn't have their profiles mapped. /// diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 430e68ea94a02..1bf2e8d627bc4 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -932,6 +932,9 @@ Error CoverageMapping::loadFunctionRecord( Error CoverageMapping::loadFromReaders( ArrayRef> CoverageReaders, IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage) { + assert(!Coverage.SingleByteCoverage || + *Coverage.SingleByteCoverage == ProfileReader.hasSingleByteCoverage()); + Coverage.SingleByteCoverage = ProfileReader.hasSingleByteCoverage(); for (const auto &CoverageReader : CoverageReaders) { for (auto RecordOrErr : *CoverageReader) { if (Error E = RecordOrErr.takeError()) @@ -947,8 +950,7 @@ Error CoverageMapping::loadFromReaders( Expected> CoverageMapping::load( ArrayRef> CoverageReaders, IndexedInstrProfReader &ProfileReader) { - auto Coverage = std::unique_ptr( - new CoverageMapping(ProfileReader.hasSingleByteCoverage())); + auto Coverage = std::unique_ptr(new CoverageMapping()); if (Error E = loadFromReaders(CoverageReaders, ProfileReader, *Coverage)) return std::move(E); return std::move(Coverage); @@ -1010,8 +1012,7 @@ Expected> CoverageMapping::load( if (Error E = ProfileReaderOrErr.takeError()) return createFileError(ProfileFilename, std::move(E)); auto ProfileReader = std::move(ProfileReaderOrErr.get()); - auto Coverage = std::unique_ptr( - new CoverageMapping(ProfileReader->hasSingleByteCoverage())); + auto Coverage = std::unique_ptr(new CoverageMapping()); bool DataFound = false; auto GetArch = [&](size_t Idx) { @@ -1388,7 +1389,8 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) { } CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { - CoverageData FileCoverage(SingleByteCoverage, Filename); + assert(SingleByteCoverage); + CoverageData FileCoverage(*SingleByteCoverage, Filename); std::vector Regions; // Look up the function records in the given file. Due to hash collisions on @@ -1450,9 +1452,10 @@ CoverageData CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { auto MainFileID = findMainViewFileID(Function); if (!MainFileID) - return CoverageData(SingleByteCoverage); + return CoverageData(); - CoverageData FunctionCoverage(SingleByteCoverage, + assert(SingleByteCoverage); + CoverageData FunctionCoverage(*SingleByteCoverage, Function.Filenames[*MainFileID]); std::vector Regions; for (const auto &CR : Function.CountedRegions) @@ -1480,8 +1483,9 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { CoverageData CoverageMapping::getCoverageForExpansion( const ExpansionRecord &Expansion) const { + assert(SingleByteCoverage); CoverageData ExpansionCoverage( - SingleByteCoverage, Expansion.Function.Filenames[Expansion.FileID]); + *SingleByteCoverage, Expansion.Function.Filenames[Expansion.FileID]); std::vector Regions; for (const auto &CR : Expansion.Function.CountedRegions) if (CR.FileID == Expansion.FileID) { From 3780e07c41b54c07e2cd61bee8a7c451e4f2cbf5 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 25 Dec 2024 08:43:24 +0900 Subject: [PATCH 22/35] Prune commented-out line --- llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 705a9f28c1241..0ad6f07bde989 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -981,8 +981,6 @@ class CoverageMapping { const object::BuildIDFetcher *BIDFetcher = nullptr, bool CheckBinaryIDs = false); - // bool getSingleByteCoverage() const { return SingleByteCoverage; } - /// The number of functions that couldn't have their profiles mapped. /// /// This is a count of functions whose profile is out of date or otherwise From 36b4aaf0248c85c3e3cf621f75b26e2734efafba Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 27 Dec 2024 15:31:05 +0900 Subject: [PATCH 23/35] [Coverage] Make `MCDCRecord::Folded` as `[false/true]` with BitVector. NFC. --- .../llvm/ProfileData/Coverage/CoverageMapping.h | 6 ++++-- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 11 ++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 42da188fef34e..5caba07f8ad43 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -442,7 +442,7 @@ struct MCDCRecord { }; using TestVectors = llvm::SmallVector>; - using BoolVector = llvm::SmallVector; + using BoolVector = std::array; using TVRowPair = std::pair; using TVPairMap = llvm::DenseMap; using CondIDMap = llvm::DenseMap; @@ -470,7 +470,9 @@ struct MCDCRecord { return Region.getDecisionParams().NumConditions; } unsigned getNumTestVectors() const { return TV.size(); } - bool isCondFolded(unsigned Condition) const { return Folded[Condition]; } + bool isCondFolded(unsigned Condition) const { + return Folded[false][Condition] || Folded[true][Condition]; + } /// Return the evaluation of a condition (indicated by Condition) in an /// executed test vector (indicated by TestVectorIndex), which will be True, diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 87d8bb1bbb79c..2eba1667306d1 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -392,8 +392,9 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { : NextIDsBuilder(Branches), TVIdxBuilder(this->NextIDs), Bitmap(Bitmap), Region(Region), DecisionParams(Region.getDecisionParams()), Branches(Branches), NumConditions(DecisionParams.NumConditions), - Folded(NumConditions, false), IndependencePairs(NumConditions), - ExecVectors(ExecVectorsByCond[false]), IsVersion11(IsVersion11) {} + Folded{{BitVector(NumConditions), BitVector(NumConditions)}}, + IndependencePairs(NumConditions), ExecVectors(ExecVectorsByCond[false]), + IsVersion11(IsVersion11) {} private: // Walk the binary decision diagram and try assigning both false and true to @@ -485,7 +486,6 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { /// location is also tracked, as well as whether it is constant folded (in /// which case it is excuded from the metric). MCDCRecord processMCDCRecord() { - unsigned I = 0; MCDCRecord::CondIDMap PosToID; MCDCRecord::LineColPairMap CondLoc; @@ -499,11 +499,12 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { // visualize where the condition is. // - Record whether the condition is constant folded so that we exclude it // from being measured. - for (const auto *B : Branches) { + for (auto [I, B] : enumerate(Branches)) { const auto &BranchParams = B->getBranchParams(); PosToID[I] = BranchParams.ID; CondLoc[I] = B->startLoc(); - Folded[I++] = (B->Count.isZero() || B->FalseCount.isZero()); + Folded[false][I] = B->FalseCount.isZero(); + Folded[true][I] = B->Count.isZero(); } // Using Profile Bitmap from runtime, mark the executed test vectors. From 978070d6aca594a49dc2ef0558e1e28e883ac1b0 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 27 Dec 2024 15:34:16 +0900 Subject: [PATCH 24/35] [Coverage] MCDC: Move `findIndependencePairs` into `MCDCRecord` --- .../ProfileData/Coverage/CoverageMapping.h | 27 +++++--- .../ProfileData/Coverage/CoverageMapping.cpp | 67 ++++++++++--------- 2 files changed, 51 insertions(+), 43 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 42da188fef34e..4f28f5da6cf81 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -451,19 +452,22 @@ struct MCDCRecord { private: CounterMappingRegion Region; TestVectors TV; - TVPairMap IndependencePairs; + std::optional IndependencePairs; BoolVector Folded; CondIDMap PosToID; LineColPairMap CondLoc; public: MCDCRecord(const CounterMappingRegion &Region, TestVectors &&TV, - TVPairMap &&IndependencePairs, BoolVector &&Folded, - CondIDMap &&PosToID, LineColPairMap &&CondLoc) - : Region(Region), TV(std::move(TV)), - IndependencePairs(std::move(IndependencePairs)), - Folded(std::move(Folded)), PosToID(std::move(PosToID)), - CondLoc(std::move(CondLoc)){}; + BoolVector &&Folded, CondIDMap &&PosToID, LineColPairMap &&CondLoc) + : Region(Region), TV(std::move(TV)), Folded(std::move(Folded)), + PosToID(std::move(PosToID)), CondLoc(std::move(CondLoc)) { + findIndependencePairs(); + } + + // Compare executed test vectors against each other to find an independence + // pairs for each condition. This processing takes the most time. + void findIndependencePairs(); const CounterMappingRegion &getDecisionRegion() const { return Region; } unsigned getNumConditions() const { @@ -494,10 +498,10 @@ struct MCDCRecord { /// TestVectors requires a translation from a ordinal position to actual /// condition ID. This is done via PosToID[]. bool isConditionIndependencePairCovered(unsigned Condition) const { + assert(IndependencePairs); auto It = PosToID.find(Condition); - if (It != PosToID.end()) - return IndependencePairs.contains(It->second); - llvm_unreachable("Condition ID without an Ordinal mapping"); + assert(It != PosToID.end() && "Condition ID without an Ordinal mapping"); + return IndependencePairs->contains(It->second); } /// Return the Independence Pair that covers the given condition. Because @@ -507,7 +511,8 @@ struct MCDCRecord { /// via PosToID[]. TVRowPair getConditionIndependencePair(unsigned Condition) { assert(isConditionIndependencePairCovered(Condition)); - return IndependencePairs[PosToID[Condition]]; + assert(IndependencePairs); + return (*IndependencePairs)[PosToID[Condition]]; } float getPercentCovered() const { diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 87d8bb1bbb79c..2c7a77bac0932 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -221,6 +221,40 @@ Expected CounterMappingContext::evaluate(const Counter &C) const { return LastPoppedValue; } +// Find an independence pair for each condition: +// - The condition is true in one test and false in the other. +// - The decision outcome is true one test and false in the other. +// - All other conditions' values must be equal or marked as "don't care". +void MCDCRecord::findIndependencePairs() { + if (IndependencePairs) + return; + + IndependencePairs.emplace(); + + unsigned NumTVs = TV.size(); + // Will be replaced to shorter expr. + unsigned TVTrueIdx = std::distance( + TV.begin(), + std::find_if(TV.begin(), TV.end(), + [&](auto I) { return (I.second == MCDCRecord::MCDC_True); }) + + ); + for (unsigned I = TVTrueIdx; I < NumTVs; ++I) { + const auto &[A, ACond] = TV[I]; + assert(ACond == MCDCRecord::MCDC_True); + for (unsigned J = 0; J < TVTrueIdx; ++J) { + const auto &[B, BCond] = TV[J]; + assert(BCond == MCDCRecord::MCDC_False); + // If the two vectors differ in exactly one condition, ignoring DontCare + // conditions, we have found an independence pair. + auto AB = A.getDifferences(B); + if (AB.count() == 1) + IndependencePairs->insert( + {AB.find_first(), std::make_pair(J + 1, I + 1)}); + } + } +} + mcdc::TVIdxBuilder::TVIdxBuilder(const SmallVectorImpl &NextIDs, int Offset) : Indices(NextIDs.size()) { @@ -375,9 +409,6 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { /// ExecutedTestVectorBitmap. MCDCRecord::TestVectors &ExecVectors; - /// Number of False items in ExecVectors - unsigned NumExecVectorsF; - #ifndef NDEBUG DenseSet TVIdxs; #endif @@ -446,34 +477,11 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { // Fill ExecVectors order by False items and True items. // ExecVectors is the alias of ExecVectorsByCond[false], so // Append ExecVectorsByCond[true] on it. - NumExecVectorsF = ExecVectors.size(); auto &ExecVectorsT = ExecVectorsByCond[true]; ExecVectors.append(std::make_move_iterator(ExecVectorsT.begin()), std::make_move_iterator(ExecVectorsT.end())); } - // Find an independence pair for each condition: - // - The condition is true in one test and false in the other. - // - The decision outcome is true one test and false in the other. - // - All other conditions' values must be equal or marked as "don't care". - void findIndependencePairs() { - unsigned NumTVs = ExecVectors.size(); - for (unsigned I = NumExecVectorsF; I < NumTVs; ++I) { - const auto &[A, ACond] = ExecVectors[I]; - assert(ACond == MCDCRecord::MCDC_True); - for (unsigned J = 0; J < NumExecVectorsF; ++J) { - const auto &[B, BCond] = ExecVectors[J]; - assert(BCond == MCDCRecord::MCDC_False); - // If the two vectors differ in exactly one condition, ignoring DontCare - // conditions, we have found an independence pair. - auto AB = A.getDifferences(B); - if (AB.count() == 1) - IndependencePairs.insert( - {AB.find_first(), std::make_pair(J + 1, I + 1)}); - } - } - } - public: /// Process the MC/DC Record in order to produce a result for a boolean /// expression. This process includes tracking the conditions that comprise @@ -509,13 +517,8 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { // Using Profile Bitmap from runtime, mark the executed test vectors. findExecutedTestVectors(); - // Compare executed test vectors against each other to find an independence - // pairs for each condition. This processing takes the most time. - findIndependencePairs(); - // Record Test vectors, executed vectors, and independence pairs. - return MCDCRecord(Region, std::move(ExecVectors), - std::move(IndependencePairs), std::move(Folded), + return MCDCRecord(Region, std::move(ExecVectors), std::move(Folded), std::move(PosToID), std::move(CondLoc)); } }; From 3abe2ac361822bf6513e5f3ef9fead37842af862 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 27 Dec 2024 15:40:47 +0900 Subject: [PATCH 25/35] [Coverage] Sort `MCDCRecord::ExecVectors` order by Bitmap index --- .../ProfileData/Coverage/CoverageMapping.cpp | 40 +++++++++++++------ llvm/test/tools/llvm-cov/mcdc-const.test | 32 +++++++-------- llvm/test/tools/llvm-cov/mcdc-general.test | 8 ++-- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 3bbee70be0fe9..53445b1030c9f 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -401,13 +401,27 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { /// Mapping of calculated MC/DC Independence Pairs for each condition. MCDCRecord::TVPairMap IndependencePairs; - /// Storage for ExecVectors - /// ExecVectors is the alias of its 0th element. - std::array ExecVectorsByCond; + /// Helper for sorting ExecVectors. + struct TVIdxTuple { + MCDCRecord::CondState MCDCCond; /// True/False + unsigned BIdx; /// Bitmap Index + unsigned Ord; /// Last position on ExecVectors + + TVIdxTuple(MCDCRecord::CondState MCDCCond, unsigned BIdx, unsigned Ord) + : MCDCCond(MCDCCond), BIdx(BIdx), Ord(Ord) {} + + bool operator<(const TVIdxTuple &RHS) const { + return (std::tie(this->MCDCCond, this->BIdx, this->Ord) < + std::tie(RHS.MCDCCond, RHS.BIdx, RHS.Ord)); + } + }; + + // Indices for sorted TestVectors; + std::vector ExecVectorIdxs; /// Actual executed Test Vectors for the boolean expression, based on /// ExecutedTestVectorBitmap. - MCDCRecord::TestVectors &ExecVectors; + MCDCRecord::TestVectors ExecVectors; #ifndef NDEBUG DenseSet TVIdxs; @@ -424,8 +438,7 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { Region(Region), DecisionParams(Region.getDecisionParams()), Branches(Branches), NumConditions(DecisionParams.NumConditions), Folded{{BitVector(NumConditions), BitVector(NumConditions)}}, - IndependencePairs(NumConditions), ExecVectors(ExecVectorsByCond[false]), - IsVersion11(IsVersion11) {} + IndependencePairs(NumConditions), IsVersion11(IsVersion11) {} private: // Walk the binary decision diagram and try assigning both false and true to @@ -453,10 +466,12 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { : DecisionParams.BitmapIdx - NumTestVectors + NextTVIdx]) continue; + ExecVectorIdxs.emplace_back(MCDCCond, NextTVIdx, ExecVectors.size()); + // Copy the completed test vector to the vector of testvectors. // The final value (T,F) is equal to the last non-dontcare state on the // path (in a short-circuiting system). - ExecVectorsByCond[MCDCCond].push_back({TV, MCDCCond}); + ExecVectors.push_back({TV, MCDCCond}); } // Reset back to DontCare. @@ -475,12 +490,11 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { assert(TVIdxs.size() == unsigned(NumTestVectors) && "TVIdxs wasn't fulfilled"); - // Fill ExecVectors order by False items and True items. - // ExecVectors is the alias of ExecVectorsByCond[false], so - // Append ExecVectorsByCond[true] on it. - auto &ExecVectorsT = ExecVectorsByCond[true]; - ExecVectors.append(std::make_move_iterator(ExecVectorsT.begin()), - std::make_move_iterator(ExecVectorsT.end())); + llvm::sort(ExecVectorIdxs); + MCDCRecord::TestVectors NewTestVectors; + for (const auto &IdxTuple : ExecVectorIdxs) + NewTestVectors.push_back(std::move(ExecVectors[IdxTuple.Ord])); + ExecVectors = std::move(NewTestVectors); } public: diff --git a/llvm/test/tools/llvm-cov/mcdc-const.test b/llvm/test/tools/llvm-cov/mcdc-const.test index 5424625cf6a6b..76eb7cf706d73 100644 --- a/llvm/test/tools/llvm-cov/mcdc-const.test +++ b/llvm/test/tools/llvm-cov/mcdc-const.test @@ -61,8 +61,8 @@ // CHECKFULLCASE: | C1-Pair: constant folded // CHECKFULLCASE-NEXT: | C2-Pair: not covered // CHECKFULLCASE: | MC/DC Coverage for Decision: 0.00% -// CHECKFULLCASE: | 1 { F, C = T } -// CHECKFULLCASE-NEXT: | 2 { T, C = T } +// CHECKFULLCASE: | 1 { T, C = T } +// CHECKFULLCASE-NEXT: | 2 { F, C = T } // CHECKFULLCASE: | C1-Pair: not covered // CHECKFULLCASE-NEXT: | C2-Pair: constant folded // CHECKFULLCASE: | MC/DC Coverage for Decision: 0.00% @@ -106,20 +106,20 @@ // CHECKFULLCASE-NEXT: | C2-Pair: not covered // CHECKFULLCASE-NEXT: | C3-Pair: not covered // CHECKFULLCASE: | MC/DC Coverage for Decision: 0.00% -// CHECKFULLCASE: | 1 { F, C, - = T } -// CHECKFULLCASE-NEXT: | 2 { T, C, - = T } +// CHECKFULLCASE: | 1 { T, C, - = T } +// CHECKFULLCASE-NEXT: | 2 { F, C, - = T } // CHECKFULLCASE: | C1-Pair: not covered // CHECKFULLCASE-NEXT: | C2-Pair: constant folded // CHECKFULLCASE-NEXT: | C3-Pair: not covered // CHECKFULLCASE: | MC/DC Coverage for Decision: 0.00% -// CHECKFULLCASE: | 1 { C, F, T = T } -// CHECKFULLCASE-NEXT: | 2 { C, T, - = T } +// CHECKFULLCASE: | 1 { C, T, - = T } +// CHECKFULLCASE-NEXT: | 2 { C, F, T = T } // CHECKFULLCASE: | C1-Pair: constant folded // CHECKFULLCASE-NEXT: | C2-Pair: not covered // CHECKFULLCASE-NEXT: | C3-Pair: not covered // CHECKFULLCASE: | MC/DC Coverage for Decision: 0.00% -// CHECKFULLCASE: | 1 { F, C, T = T } -// CHECKFULLCASE-NEXT: | 2 { T, C, - = T } +// CHECKFULLCASE: | 1 { T, C, - = T } +// CHECKFULLCASE-NEXT: | 2 { F, C, T = T } // CHECKFULLCASE: | C1-Pair: not covered // CHECKFULLCASE-NEXT: | C2-Pair: constant folded // CHECKFULLCASE-NEXT: | C3-Pair: not covered @@ -151,26 +151,26 @@ // CHECKFULLCASE-NEXT: | C2-Pair: constant folded // CHECKFULLCASE-NEXT: | C3-Pair: covered: (2,3) // CHECKFULLCASE: | MC/DC Coverage for Decision: 100.00% -// CHECKFULLCASE: | 1 { F, T, C = T } -// CHECKFULLCASE-NEXT: | 2 { T, -, C = T } +// CHECKFULLCASE: | 1 { T, -, C = T } +// CHECKFULLCASE-NEXT: | 2 { F, T, C = T } // CHECKFULLCASE: | C1-Pair: not covered // CHECKFULLCASE-NEXT: | C2-Pair: not covered // CHECKFULLCASE-NEXT: | C3-Pair: constant folded // CHECKFULLCASE: | MC/DC Coverage for Decision: 0.00% -// CHECKFULLCASE: | 1 { F, C, - = T } -// CHECKFULLCASE-NEXT: | 2 { T, C, - = T } +// CHECKFULLCASE: | 1 { T, C, - = T } +// CHECKFULLCASE-NEXT: | 2 { F, C, - = T } // CHECKFULLCASE: | C1-Pair: not covered // CHECKFULLCASE-NEXT: | C2-Pair: constant folded // CHECKFULLCASE-NEXT: | C3-Pair: not covered // CHECKFULLCASE: | MC/DC Coverage for Decision: 0.00% -// CHECKFULLCASE: | 1 { F, T, C = T } -// CHECKFULLCASE-NEXT: | 2 { T, -, C = T } +// CHECKFULLCASE: | 1 { T, -, C = T } +// CHECKFULLCASE-NEXT: | 2 { F, T, C = T } // CHECKFULLCASE: | C1-Pair: not covered // CHECKFULLCASE-NEXT: | C2-Pair: not covered // CHECKFULLCASE-NEXT: | C3-Pair: constant folded // CHECKFULLCASE: | MC/DC Coverage for Decision: 0.00% -// CHECKFULLCASE: | 1 { F, C, T = T } -// CHECKFULLCASE-NEXT: | 2 { T, C, - = T } +// CHECKFULLCASE: | 1 { T, C, - = T } +// CHECKFULLCASE-NEXT: | 2 { F, C, T = T } // CHECKFULLCASE: | C1-Pair: not covered // CHECKFULLCASE-NEXT: | C2-Pair: constant folded // CHECKFULLCASE-NEXT: | C3-Pair: not covered diff --git a/llvm/test/tools/llvm-cov/mcdc-general.test b/llvm/test/tools/llvm-cov/mcdc-general.test index c1e95cb2bd92a..1835af9a4c6b5 100644 --- a/llvm/test/tools/llvm-cov/mcdc-general.test +++ b/llvm/test/tools/llvm-cov/mcdc-general.test @@ -19,15 +19,15 @@ // CHECK-NEXT: | // CHECK-NEXT: | C1, C2, C3, C4 Result // CHECK-NEXT: | 1 { F, -, F, - = F } -// CHECK-NEXT: | 2 { F, -, T, F = F } -// CHECK-NEXT: | 3 { T, F, F, - = F } +// CHECK-NEXT: | 2 { T, F, F, - = F } +// CHECK-NEXT: | 3 { F, -, T, F = F } // CHECK-NEXT: | 4 { T, F, T, F = F } // CHECK-NEXT: | 5 { T, F, T, T = T } // CHECK-NEXT: | 6 { T, T, -, - = T } // CHECK-NEXT: | // CHECK-NEXT: | C1-Pair: covered: (1,6) -// CHECK-NEXT: | C2-Pair: covered: (3,6) -// CHECK-NEXT: | C3-Pair: covered: (3,5) +// CHECK-NEXT: | C2-Pair: covered: (2,6) +// CHECK-NEXT: | C3-Pair: covered: (2,5) // CHECK-NEXT: | C4-Pair: covered: (4,5) // CHECK-NEXT: | MC/DC Coverage for Decision: 100.00% // CHECK-NEXT: | From f86c537e2c9224cddf10d0b05333e35bdc169361 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 27 Dec 2024 15:42:07 +0900 Subject: [PATCH 26/35] llvm-cov: Refactor CoverageSummaryInfo. NFC. --- llvm/tools/llvm-cov/CoverageSummaryInfo.cpp | 51 +++++++++++---------- llvm/tools/llvm-cov/CoverageSummaryInfo.h | 45 +++++++++--------- 2 files changed, 50 insertions(+), 46 deletions(-) diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp index ad7561d3dc62c..5c002a694f66a 100644 --- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp +++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp @@ -16,8 +16,9 @@ using namespace llvm; using namespace coverage; -static void sumBranches(size_t &NumBranches, size_t &CoveredBranches, - const ArrayRef &Branches) { +static auto sumBranches(const ArrayRef &Branches) { + size_t NumBranches = 0; + size_t CoveredBranches = 0; for (const auto &BR : Branches) { if (!BR.TrueFolded) { // "True" Condition Branches. @@ -32,20 +33,22 @@ static void sumBranches(size_t &NumBranches, size_t &CoveredBranches, ++CoveredBranches; } } + return BranchCoverageInfo(CoveredBranches, NumBranches); } -static void sumBranchExpansions(size_t &NumBranches, size_t &CoveredBranches, - const CoverageMapping &CM, - ArrayRef Expansions) { +static BranchCoverageInfo +sumBranchExpansions(const CoverageMapping &CM, + ArrayRef Expansions) { + BranchCoverageInfo BranchCoverage; for (const auto &Expansion : Expansions) { auto CE = CM.getCoverageForExpansion(Expansion); - sumBranches(NumBranches, CoveredBranches, CE.getBranches()); - sumBranchExpansions(NumBranches, CoveredBranches, CM, CE.getExpansions()); + BranchCoverage += sumBranches(CE.getBranches()); + BranchCoverage += sumBranchExpansions(CM, CE.getExpansions()); } + return BranchCoverage; } -static std::pair -sumMCDCPairs(const ArrayRef &Records) { +auto sumMCDCPairs(const ArrayRef &Records) { size_t NumPairs = 0, CoveredPairs = 0; for (const auto &Record : Records) { const auto NumConditions = Record.getNumConditions(); @@ -56,7 +59,7 @@ sumMCDCPairs(const ArrayRef &Records) { ++CoveredPairs; } } - return {NumPairs, CoveredPairs}; + return MCDCCoverageInfo(CoveredPairs, NumPairs); } static std::pair @@ -85,24 +88,27 @@ sumRegions(ArrayRef CodeRegions, const CoverageData &CD) { LineCoverageInfo(CoveredLines, NumLines)}; } +CoverageDataSummary::CoverageDataSummary(const CoverageData &CD, + ArrayRef CodeRegions) { + std::tie(RegionCoverage, LineCoverage) = sumRegions(CodeRegions, CD); + BranchCoverage = sumBranches(CD.getBranches()); + MCDCCoverage = sumMCDCPairs(CD.getMCDCRecords()); +} + FunctionCoverageSummary FunctionCoverageSummary::get(const CoverageMapping &CM, const coverage::FunctionRecord &Function) { CoverageData CD = CM.getCoverageForFunction(Function); - auto [RegionCoverage, LineCoverage] = sumRegions(Function.CountedRegions, CD); - // Compute the branch coverage, including branches from expansions. - size_t NumBranches = 0, CoveredBranches = 0; - sumBranches(NumBranches, CoveredBranches, CD.getBranches()); - sumBranchExpansions(NumBranches, CoveredBranches, CM, CD.getExpansions()); + auto Summary = + FunctionCoverageSummary(Function.Name, Function.ExecutionCount); - size_t NumPairs = 0, CoveredPairs = 0; - std::tie(NumPairs, CoveredPairs) = sumMCDCPairs(CD.getMCDCRecords()); + Summary += CoverageDataSummary(CD, Function.CountedRegions); - return FunctionCoverageSummary( - Function.Name, Function.ExecutionCount, RegionCoverage, LineCoverage, - BranchCoverageInfo(CoveredBranches, NumBranches), - MCDCCoverageInfo(CoveredPairs, NumPairs)); + // Compute the branch coverage, including branches from expansions. + Summary.BranchCoverage += sumBranchExpansions(CM, CD.getExpansions()); + + return Summary; } FunctionCoverageSummary @@ -117,8 +123,7 @@ FunctionCoverageSummary::get(const InstantiationGroup &Group, << Group.getColumn(); } - FunctionCoverageSummary Summary(Name); - Summary.ExecutionCount = Group.getTotalExecutionCount(); + FunctionCoverageSummary Summary(Name, Group.getTotalExecutionCount()); Summary.RegionCoverage = Summaries[0].RegionCoverage; Summary.LineCoverage = Summaries[0].LineCoverage; Summary.BranchCoverage = Summaries[0].BranchCoverage; diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.h b/llvm/tools/llvm-cov/CoverageSummaryInfo.h index 64c2c8406cf3e..d9210676c41bf 100644 --- a/llvm/tools/llvm-cov/CoverageSummaryInfo.h +++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.h @@ -223,26 +223,32 @@ class FunctionCoverageInfo { } }; -/// A summary of function's code coverage. -struct FunctionCoverageSummary { - std::string Name; - uint64_t ExecutionCount; +struct CoverageDataSummary { RegionCoverageInfo RegionCoverage; LineCoverageInfo LineCoverage; BranchCoverageInfo BranchCoverage; MCDCCoverageInfo MCDCCoverage; - FunctionCoverageSummary(const std::string &Name) - : Name(Name), ExecutionCount(0) {} + CoverageDataSummary() = default; + CoverageDataSummary(const coverage::CoverageData &CD, + ArrayRef CodeRegions); - FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount, - const RegionCoverageInfo &RegionCoverage, - const LineCoverageInfo &LineCoverage, - const BranchCoverageInfo &BranchCoverage, - const MCDCCoverageInfo &MCDCCoverage) - : Name(Name), ExecutionCount(ExecutionCount), - RegionCoverage(RegionCoverage), LineCoverage(LineCoverage), - BranchCoverage(BranchCoverage), MCDCCoverage(MCDCCoverage) {} + auto &operator+=(const CoverageDataSummary &RHS) { + RegionCoverage += RHS.RegionCoverage; + LineCoverage += RHS.LineCoverage; + BranchCoverage += RHS.BranchCoverage; + MCDCCoverage += RHS.MCDCCoverage; + return *this; + } +}; + +/// A summary of function's code coverage. +struct FunctionCoverageSummary : CoverageDataSummary { + std::string Name; + uint64_t ExecutionCount; + + FunctionCoverageSummary(const std::string &Name, uint64_t ExecutionCount = 0) + : Name(Name), ExecutionCount(ExecutionCount) {} /// Compute the code coverage summary for the given function coverage /// mapping record. @@ -257,12 +263,8 @@ struct FunctionCoverageSummary { }; /// A summary of file's code coverage. -struct FileCoverageSummary { +struct FileCoverageSummary : CoverageDataSummary { StringRef Name; - RegionCoverageInfo RegionCoverage; - LineCoverageInfo LineCoverage; - BranchCoverageInfo BranchCoverage; - MCDCCoverageInfo MCDCCoverage; FunctionCoverageInfo FunctionCoverage; FunctionCoverageInfo InstantiationCoverage; @@ -270,11 +272,8 @@ struct FileCoverageSummary { FileCoverageSummary(StringRef Name) : Name(Name) {} FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) { - RegionCoverage += RHS.RegionCoverage; - LineCoverage += RHS.LineCoverage; + *static_cast(this) += RHS; FunctionCoverage += RHS.FunctionCoverage; - BranchCoverage += RHS.BranchCoverage; - MCDCCoverage += RHS.MCDCCoverage; InstantiationCoverage += RHS.InstantiationCoverage; return *this; } From 92bf1c1eeaa79a1f9a6d410744d38dd5bf342040 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 27 Dec 2024 15:44:28 +0900 Subject: [PATCH 27/35] llvm-cov: Emit RegionCoverage based on `CoverageData::Segments` --- llvm/test/tools/llvm-cov/branch-c-general.test | 12 ++++++------ llvm/test/tools/llvm-cov/branch-export-json.test | 2 +- llvm/test/tools/llvm-cov/branch-macros.test | 6 +++--- .../test/tools/llvm-cov/branch-noShowBranch.test | 12 ++++++------ llvm/test/tools/llvm-cov/mcdc-general-none.test | 6 +++--- llvm/test/tools/llvm-cov/mcdc-general.test | 6 +++--- llvm/tools/llvm-cov/CoverageSummaryInfo.cpp | 16 ++++++++-------- llvm/tools/llvm-cov/CoverageSummaryInfo.h | 3 +-- 8 files changed, 31 insertions(+), 32 deletions(-) diff --git a/llvm/test/tools/llvm-cov/branch-c-general.test b/llvm/test/tools/llvm-cov/branch-c-general.test index 3c163bf6de45c..9ee15ec75428e 100644 --- a/llvm/test/tools/llvm-cov/branch-c-general.test +++ b/llvm/test/tools/llvm-cov/branch-c-general.test @@ -117,19 +117,19 @@ // REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover // REPORT-NEXT: --- // REPORT-NEXT: simple_loops 8 0 100.00% 9 0 100.00% 6 0 100.00% -// REPORT-NEXT: conditionals 24 0 100.00% 15 0 100.00% 16 2 87.50% +// REPORT-NEXT: conditionals 22 0 100.00% 15 0 100.00% 16 2 87.50% // REPORT-NEXT: early_exits 20 4 80.00% 25 2 92.00% 16 6 62.50% // REPORT-NEXT: jumps 39 12 69.23% 48 2 95.83% 26 9 65.38% -// REPORT-NEXT: switches 28 5 82.14% 38 4 89.47% 28 7 75.00% +// REPORT-NEXT: switches 27 4 85.19% 38 4 89.47% 28 7 75.00% // REPORT-NEXT: big_switch 25 1 96.00% 32 0 100.00% 30 6 80.00% -// REPORT-NEXT: boolean_operators 16 0 100.00% 13 0 100.00% 22 2 90.91% -// REPORT-NEXT: boolop_loops 19 0 100.00% 14 0 100.00% 16 2 87.50% +// REPORT-NEXT: boolean_operators 14 0 100.00% 13 0 100.00% 22 2 90.91% +// REPORT-NEXT: boolop_loops 15 0 100.00% 14 0 100.00% 16 2 87.50% // REPORT-NEXT: conditional_operator 4 2 50.00% 8 0 100.00% 4 2 50.00% // REPORT-NEXT: do_fallthrough 9 0 100.00% 12 0 100.00% 6 0 100.00% // REPORT-NEXT: main 1 0 100.00% 16 0 100.00% 0 0 0.00% // REPORT-NEXT: c-general.c:static_func 4 0 100.00% 4 0 100.00% 2 0 100.00% // REPORT-NEXT: --- -// REPORT-NEXT: TOTAL 197 24 87.82% 234 8 96.58% 172 36 79.07% +// REPORT-NEXT: TOTAL 188 23 87.77% 234 8 96.58% 172 36 79.07% // Test file-level report. // RUN: llvm-profdata merge %S/Inputs/branch-c-general.proftext -o %t.profdata @@ -159,7 +159,7 @@ // HTML-INDEX: diff --git a/llvm/test/tools/llvm-cov/branch-export-json.test b/llvm/test/tools/llvm-cov/branch-export-json.test index 7cf4286087982..4278482c6d870 100644 --- a/llvm/test/tools/llvm-cov/branch-export-json.test +++ b/llvm/test/tools/llvm-cov/branch-export-json.test @@ -18,7 +18,7 @@ // CHECK: 45,5,45,11,0,5,0,0,4 // CHECK: 47,5,47,12,3,2,0,0,4 // CHECK: 53,12,53,20,50,5,0,0,4 -// CHECK: {"count":30,"covered":26,"notcovered":4,"percent":86.666666666666671} +// CHECK: {"count":30,"covered":26,"notcovered":4,"percent":86.6[[#]]} // Check recursive macro-expansions. // RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test index e4bd14ec14f16..b3b163f5457b0 100644 --- a/llvm/test/tools/llvm-cov/branch-macros.test +++ b/llvm/test/tools/llvm-cov/branch-macros.test @@ -8,8 +8,8 @@ // REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover // REPORT-NEXT: --- -// REPORT-NEXT: _Z4funcii 28 4 85.71% 18 0 100.00% 30 14 53.33% -// REPORT-NEXT: _Z5func2ii 13 1 92.31% 8 0 100.00% 10 2 80.00% +// REPORT-NEXT: _Z4funcii 12 4 66.67% 18 0 100.00% 30 14 53.33% +// REPORT-NEXT: _Z5func2ii 3 0 100.00% 8 0 100.00% 10 2 80.00% // REPORT-NEXT: main 1 0 100.00% 6 0 100.00% 0 0 0.00% // REPORT-NEXT: --- -// REPORT-NEXT: TOTAL 42 5 88.10% 32 0 100.00% 40 16 60.00% +// REPORT-NEXT: TOTAL 16 4 75.00% 32 0 100.00% 40 16 60.00% diff --git a/llvm/test/tools/llvm-cov/branch-noShowBranch.test b/llvm/test/tools/llvm-cov/branch-noShowBranch.test index 9f3cfd55f029b..11a9a5a665b70 100644 --- a/llvm/test/tools/llvm-cov/branch-noShowBranch.test +++ b/llvm/test/tools/llvm-cov/branch-noShowBranch.test @@ -9,16 +9,16 @@ // REPORT-NOT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover // REPORT: --- // REPORT-NOT: simple_loops 8 0 100.00% 9 0 100.00% 6 0 100.00% -// REPORT-NOT: conditionals 24 0 100.00% 15 0 100.00% 16 2 87.50% +// REPORT-NOT: conditionals 22 0 100.00% 15 0 100.00% 16 2 87.50% // REPORT-NOT: early_exits 20 4 80.00% 25 2 92.00% 16 6 62.50% // REPORT-NOT: jumps 39 12 69.23% 48 2 95.83% 26 9 65.38% -// REPORT-NOT: switches 28 5 82.14% 38 4 89.47% 28 7 75.00% +// REPORT-NOT: switches 27 4 85.19% 38 4 89.47% 28 7 75.00% // REPORT-NOT: big_switch 25 1 96.00% 32 0 100.00% 30 6 80.00% -// REPORT-NOT: boolean_operators 16 0 100.00% 13 0 100.00% 22 2 90.91% -// REPORT-NOT: boolop_loops 19 0 100.00% 14 0 100.00% 16 2 87.50% +// REPORT-NOT: boolean_operators 14 0 100.00% 13 0 100.00% 22 2 90.91% +// REPORT-NOT: boolop_loops 15 0 100.00% 14 0 100.00% 16 2 87.50% // REPORT-NOT: conditional_operator 4 2 50.00% 8 0 100.00% 4 2 50.00% // REPORT-NOT: do_fallthrough 9 0 100.00% 12 0 100.00% 6 0 100.00% // REPORT-NOT: main 1 0 100.00% 16 0 100.00% 0 0 0.00% // REPORT-NOT: c-general.c:static_func 4 0 100.00% 4 0 100.00% 2 0 100.00% -// REPORT: TOTAL 197 24 87.82% 234 8 96.58% -// REPORT-NOT: TOTAL 197 24 87.82% 234 8 96.58% 172 36 79.07% +// REPORT: TOTAL 188 23 87.77% 234 8 96.58% +// REPORT-NOT: TOTAL 188 23 87.77% 234 8 96.58% 172 36 79.07% diff --git a/llvm/test/tools/llvm-cov/mcdc-general-none.test b/llvm/test/tools/llvm-cov/mcdc-general-none.test index b57b35d49c8c1..db95314ac950a 100644 --- a/llvm/test/tools/llvm-cov/mcdc-general-none.test +++ b/llvm/test/tools/llvm-cov/mcdc-general-none.test @@ -34,10 +34,10 @@ // REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover MC/DC Conditions Miss Cover // REPORT-NEXT: ------------------------------------------------------------------------------------------------------------------------------------------- -// REPORT-NEXT: _Z4testbbbb 25 0 100.00% 9 0 100.00% 24 2 91.67% 12 12 0.00% +// REPORT-NEXT: _Z4testbbbb 21 0 100.00% 9 0 100.00% 24 2 91.67% 12 12 0.00% // REPORT-NEXT: main 1 0 100.00% 11 0 100.00% 0 0 0.00% 0 0 0.00% // REPORT-NEXT: --- -// REPORT-NEXT: TOTAL 26 0 100.00% 20 0 100.00% 24 2 91.67% 12 12 0.00% +// REPORT-NEXT: TOTAL 22 0 100.00% 20 0 100.00% 24 2 91.67% 12 12 0.00% // Turn off MC/DC summary. // RUN: llvm-cov report %S/Inputs/mcdc-general.o -instr-profile %t.profdata -show-functions -path-equivalence=.,%S/Inputs %S/Inputs/mcdc-general.cpp | FileCheck %s -check-prefix=REPORT_NOMCDC @@ -67,7 +67,7 @@ // HTML-INDEX: -RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -format html -show-region-summary -show-instantiation-summary -o %t.html.dir -path-equivalence=/tmp,%S -coverage-watermark 80,70 %S/showTemplateInstantiations.cpp +RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -format html -show-region-summary -show-instantiation-summary -o %t.html.dir -path-equivalence=/tmp,%S -coverage-watermark 90,70 %S/showTemplateInstantiations.cpp RUN: FileCheck -check-prefix=DOWNGRADE1 %s -input-file %t.html.dir/index.html DOWNGRADE:1 Totals @@ -35,9 +35,9 @@ DOWNGRADE1: 100.00% (2/2) DOWNGRADE1: @@ -51,9 +51,9 @@ DOWNGRADE2: 100.00% (2/2) DOWNGRADE2: diff --git a/llvm/test/tools/llvm-cov/zeroFunctionFile.c b/llvm/test/tools/llvm-cov/zeroFunctionFile.c index f463007fe7f60..28caa5ac24165 100644 --- a/llvm/test/tools/llvm-cov/zeroFunctionFile.c +++ b/llvm/test/tools/llvm-cov/zeroFunctionFile.c @@ -16,5 +16,4 @@ int main() { // RUN: llvm-cov show -j 1 %S/Inputs/zeroFunctionFile.covmapping -format html -instr-profile %t.profdata -o %t.dir // RUN: FileCheck %s -input-file=%t.dir/index.html -check-prefix=HTML // HTML-NO: 0.00% (0/0) -// HTML: Files which contain no functions -// HTML: zeroFunctionFile.h +// HTML-NOT: Files which contain no functions diff --git a/llvm/tools/llvm-cov/CoverageReport.cpp b/llvm/tools/llvm-cov/CoverageReport.cpp index 00aea4039bfde..0046b968756dd 100644 --- a/llvm/tools/llvm-cov/CoverageReport.cpp +++ b/llvm/tools/llvm-cov/CoverageReport.cpp @@ -446,27 +446,47 @@ void CoverageReport::prepareSingleFileReport(const StringRef Filename, const coverage::CoverageMapping *Coverage, const CoverageViewOptions &Options, const unsigned LCP, FileCoverageSummary *FileReport, const CoverageFilter *Filters) { + DenseSet FilteredOutFunctions; + assert(FileReport->empty()); for (const auto &Group : Coverage->getInstantiationGroups(Filename)) { - std::vector InstantiationSummaries; + bool Updated = false; for (const coverage::FunctionRecord *F : Group.getInstantiations()) { - if (!Filters->matches(*Coverage, *F)) + if (!Filters->matches(*Coverage, *F)) { + FilteredOutFunctions.insert(F); continue; - auto InstantiationSummary = FunctionCoverageSummary::get(*Coverage, *F); - FileReport->addInstantiation(InstantiationSummary); - InstantiationSummaries.push_back(InstantiationSummary); + } + FileReport->InstantiationCoverage.addFunction( + /*Covered=*/F->ExecutionCount > 0); + Updated = true; } - if (InstantiationSummaries.empty()) + if (!Updated) continue; - auto GroupSummary = - FunctionCoverageSummary::get(Group, InstantiationSummaries); + if (Options.Debug) { + std::string Name; + if (Group.hasName()) { + Name = std::string(Group.getName()); + } else { + llvm::raw_string_ostream OS(Name); + OS << "Definition at line " << Group.getLine() << ", column " + << Group.getColumn(); + } - if (Options.Debug) - outs() << "InstantiationGroup: " << GroupSummary.Name << " with " + outs() << "InstantiationGroup: " << Name << " with " << "size = " << Group.size() << "\n"; + } - FileReport->addFunction(GroupSummary); + FileReport->FunctionCoverage.addFunction( + /*Covered=*/Group.getTotalExecutionCount() > 0); } + + auto FileCoverage = + Coverage->getCoverageForFile(Filename, FilteredOutFunctions); + if (FileCoverage.empty()) + return; + + *static_cast(FileReport) += + CoverageDataSummary(FileCoverage); } std::vector CoverageReport::prepareFileReports( diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp index 86d11266ecdd7..745a92103bccc 100644 --- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp +++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp @@ -110,29 +110,3 @@ FunctionCoverageSummary::get(const CoverageMapping &CM, return Summary; } - -FunctionCoverageSummary -FunctionCoverageSummary::get(const InstantiationGroup &Group, - ArrayRef Summaries) { - std::string Name; - if (Group.hasName()) { - Name = std::string(Group.getName()); - } else { - llvm::raw_string_ostream OS(Name); - OS << "Definition at line " << Group.getLine() << ", column " - << Group.getColumn(); - } - - FunctionCoverageSummary Summary(Name, Group.getTotalExecutionCount()); - Summary.RegionCoverage = Summaries[0].RegionCoverage; - Summary.LineCoverage = Summaries[0].LineCoverage; - Summary.BranchCoverage = Summaries[0].BranchCoverage; - Summary.MCDCCoverage = Summaries[0].MCDCCoverage; - for (const auto &FCS : Summaries.drop_front()) { - Summary.RegionCoverage.merge(FCS.RegionCoverage); - Summary.LineCoverage.merge(FCS.LineCoverage); - Summary.BranchCoverage.merge(FCS.BranchCoverage); - Summary.MCDCCoverage.merge(FCS.MCDCCoverage); - } - return Summary; -} diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.h b/llvm/tools/llvm-cov/CoverageSummaryInfo.h index 42398ee06100e..09ceba5de7271 100644 --- a/llvm/tools/llvm-cov/CoverageSummaryInfo.h +++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.h @@ -41,11 +41,6 @@ class RegionCoverageInfo { return *this; } - void merge(const RegionCoverageInfo &RHS) { - Covered = std::max(Covered, RHS.Covered); - NumRegions = std::max(NumRegions, RHS.NumRegions); - } - size_t getCovered() const { return Covered; } size_t getNumRegions() const { return NumRegions; } @@ -82,11 +77,6 @@ class LineCoverageInfo { return *this; } - void merge(const LineCoverageInfo &RHS) { - Covered = std::max(Covered, RHS.Covered); - NumLines = std::max(NumLines, RHS.NumLines); - } - size_t getCovered() const { return Covered; } size_t getNumLines() const { return NumLines; } @@ -123,11 +113,6 @@ class BranchCoverageInfo { return *this; } - void merge(const BranchCoverageInfo &RHS) { - Covered = std::max(Covered, RHS.Covered); - NumBranches = std::max(NumBranches, RHS.NumBranches); - } - size_t getCovered() const { return Covered; } size_t getNumBranches() const { return NumBranches; } @@ -164,11 +149,6 @@ class MCDCCoverageInfo { return *this; } - void merge(const MCDCCoverageInfo &RHS) { - CoveredPairs = std::max(CoveredPairs, RHS.CoveredPairs); - NumPairs = std::max(NumPairs, RHS.NumPairs); - } - size_t getCoveredPairs() const { return CoveredPairs; } size_t getNumPairs() const { return NumPairs; } @@ -232,6 +212,13 @@ struct CoverageDataSummary { CoverageDataSummary() = default; CoverageDataSummary(const coverage::CoverageData &CD); + bool empty() const { + return (RegionCoverage.getNumRegions() == 0 && + LineCoverage.getNumLines() == 0 && + BranchCoverage.getNumBranches() == 0 && + MCDCCoverage.getNumPairs() == 0); + } + auto &operator+=(const CoverageDataSummary &RHS) { RegionCoverage += RHS.RegionCoverage; LineCoverage += RHS.LineCoverage; @@ -253,12 +240,6 @@ struct FunctionCoverageSummary : CoverageDataSummary { /// mapping record. static FunctionCoverageSummary get(const coverage::CoverageMapping &CM, const coverage::FunctionRecord &Function); - - /// Compute the code coverage summary for an instantiation group \p Group, - /// given a list of summaries for each instantiation in \p Summaries. - static FunctionCoverageSummary - get(const coverage::InstantiationGroup &Group, - ArrayRef Summaries); }; /// A summary of file's code coverage. @@ -270,24 +251,18 @@ struct FileCoverageSummary : CoverageDataSummary { FileCoverageSummary() = default; FileCoverageSummary(StringRef Name) : Name(Name) {} + bool empty() const { + return (CoverageDataSummary::empty() && + FunctionCoverage.getNumFunctions() == 0 && + InstantiationCoverage.getNumFunctions() == 0); + } + FileCoverageSummary &operator+=(const FileCoverageSummary &RHS) { *static_cast(this) += RHS; FunctionCoverage += RHS.FunctionCoverage; InstantiationCoverage += RHS.InstantiationCoverage; return *this; } - - void addFunction(const FunctionCoverageSummary &Function) { - RegionCoverage += Function.RegionCoverage; - LineCoverage += Function.LineCoverage; - BranchCoverage += Function.BranchCoverage; - MCDCCoverage += Function.MCDCCoverage; - FunctionCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); - } - - void addInstantiation(const FunctionCoverageSummary &Function) { - InstantiationCoverage.addFunction(/*Covered=*/Function.ExecutionCount > 0); - } }; /// A cache for demangled symbols. diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp index c94d3853fc014..cb0ea6e0cdafc 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp @@ -23,6 +23,16 @@ using namespace llvm; namespace { +template +bool IsSummaryEmpty(const SummaryTy &Report, const CoverageViewOptions &Opts) { + return !(Report.FunctionCoverage.getNumFunctions() || + (Opts.ShowInstantiationSummary && + Report.InstantiationCoverage.getNumFunctions()) || + (Opts.ShowRegionSummary && Report.RegionCoverage.getNumRegions()) || + (Opts.ShowBranchSummary && Report.BranchCoverage.getNumBranches()) || + (Opts.ShowMCDCSummary && Report.MCDCCoverage.getNumPairs())); +} + // Return a string with the special characters in \p Str escaped. std::string escape(StringRef Str, const CoverageViewOptions &Opts) { std::string TabExpandedResult; @@ -666,7 +676,7 @@ Error CoveragePrinterHTML::createIndexFile( Coverage, Totals, SourceFiles, Opts, Filters); bool EmptyFiles = false; for (unsigned I = 0, E = FileReports.size(); I < E; ++I) { - if (FileReports[I].FunctionCoverage.getNumFunctions()) + if (!IsSummaryEmpty(FileReports[I], Opts)) emitFileSummary(OSRef, SourceFiles[I], FileReports[I]); else EmptyFiles = true; @@ -734,7 +744,7 @@ struct CoveragePrinterHTMLDirectory::Reporter : public DirectoryCoverageReport { // Make directories at the top of the table. for (auto &&SubDir : SubDirs) { auto &Report = SubDir.second.first; - if (!Report.FunctionCoverage.getNumFunctions()) + if (IsSummaryEmpty(Report, Printer.Opts)) EmptyFiles.push_back(&Report); else emitTableRow(OSRef, Options, buildRelLinkToFile(Report.Name), Report, @@ -743,7 +753,7 @@ struct CoveragePrinterHTMLDirectory::Reporter : public DirectoryCoverageReport { for (auto &&SubFile : SubFiles) { auto &Report = SubFile.second; - if (!Report.FunctionCoverage.getNumFunctions()) + if (IsSummaryEmpty(Report, Printer.Opts)) EmptyFiles.push_back(&Report); else emitTableRow(OSRef, Options, buildRelLinkToFile(Report.Name), Report, From 273eea73c158acbf7140bd599554b2ba02d88097 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 27 Dec 2024 16:14:24 +0900 Subject: [PATCH 29/35] llvm-cov: Introduce `--merge-instantiations=` --- .../ProfileData/Coverage/CoverageMapping.h | 82 ++++++++- .../ProfileData/Coverage/CoverageMapping.cpp | 170 ++++++++++++++++-- .../llvm-cov/Inputs/branch-templates.cpp | 6 +- .../llvm-cov/Inputs/mcdc-templates-merge.cpp | 54 ++++++ .../Inputs/mcdc-templates-merge.proftext | 73 ++++++++ .../llvm-cov/Inputs/mcdc-templates-merge.yaml | 105 +++++++++++ .../tools/llvm-cov/branch-export-json.test | 2 +- .../tools/llvm-cov/branch-export-lcov.test | 4 +- llvm/test/tools/llvm-cov/branch-macros.test | 9 + .../test/tools/llvm-cov/branch-templates.test | 4 +- .../tools/llvm-cov/mcdc-templates-merge.test | 41 +++++ llvm/tools/llvm-cov/CodeCoverage.cpp | 12 +- llvm/tools/llvm-cov/CoverageReport.cpp | 4 +- llvm/tools/llvm-cov/CoverageViewOptions.h | 2 + llvm/tools/llvm-cov/SourceCoverageView.cpp | 4 +- 15 files changed, 540 insertions(+), 32 deletions(-) create mode 100644 llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp create mode 100644 llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext create mode 100644 llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml create mode 100644 llvm/test/tools/llvm-cov/mcdc-templates-merge.test diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 64416fdba1b24..d6df8403a2cd1 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -59,6 +59,12 @@ namespace coverage { class CoverageMappingReader; struct CoverageMappingRecord; +enum class MergeStrategy { + Merge, + Any, + All, +}; + enum class coveragemap_error { success = 0, eof, @@ -375,6 +381,32 @@ struct CountedRegion : public CounterMappingRegion { : CounterMappingRegion(R), ExecutionCount(ExecutionCount), FalseExecutionCount(FalseExecutionCount), TrueFolded(false), FalseFolded(false) {} + + LineColPair viewLoc() const { return startLoc(); } + + bool isMergeable(const CountedRegion &RHS) const { + return (this->viewLoc() == RHS.viewLoc()); + } + + void merge(const CountedRegion &RHS, MergeStrategy Strategy); + + /// Returns comparable rank value in selecting a better Record for merging. + auto getMergeRank(MergeStrategy Strategy) const { + assert(isBranch() && "Dedicated to Branch"); + assert(Strategy == MergeStrategy::Any && "Dedicated to Any"); + unsigned m = 0; + // Prefer both Counts have values. + m = (m << 1) | (ExecutionCount != 0 && FalseExecutionCount != 0); + // Prefer both are unfolded. + m = (m << 1) | (!TrueFolded && !FalseFolded); + // Prefer either Count has value. + m = (m << 1) | (ExecutionCount != 0 || FalseExecutionCount != 0); + // Prefer either is unfolded. + m = (m << 1) | (!TrueFolded || !FalseFolded); + return std::make_pair(m, ExecutionCount + FalseExecutionCount); + } + + void commit() const {} }; /// MCDC Record grouping all information together. @@ -462,6 +494,19 @@ struct MCDCRecord { findIndependencePairs(); } + inline LineColPair viewLoc() const { return Region.endLoc(); } + + bool isMergeable(const MCDCRecord &RHS) const { + return (this->viewLoc() == RHS.viewLoc() && this->PosToID == RHS.PosToID && + this->CondLoc == RHS.CondLoc); + } + + // This may invalidate IndependencePairs + // MCDCRecord &operator+=(const MCDCRecord &RHS); + void merge(MCDCRecord &&RHS, MergeStrategy Strategy); + + void commit() { findIndependencePairs(); } + // Compare executed test vectors against each other to find an independence // pairs for each condition. This processing takes the most time. void findIndependencePairs(); @@ -512,15 +557,42 @@ struct MCDCRecord { return (*IndependencePairs)[PosToID[Condition]]; } - float getPercentCovered() const { - unsigned Folded = 0; + std::pair getCoveredCount() const { unsigned Covered = 0; + unsigned Folded = 0; for (unsigned C = 0; C < getNumConditions(); C++) { if (isCondFolded(C)) Folded++; else if (isConditionIndependencePairCovered(C)) Covered++; } + return {Covered, Folded}; + } + + /// Returns comparable rank value in selecting a better Record for merging. + std::tuple + getMergeRank(MergeStrategy Strategy) const { + auto [Covered, Folded] = getCoveredCount(); + auto NumTVs = getNumTestVectors(); + switch (Strategy) { + case MergeStrategy::Merge: + case MergeStrategy::Any: + return { + Covered, // The largest covered number + ~Folded, // Less folded is better + NumTVs, // Show more test vectors + }; + case MergeStrategy::All: + return { + ~Covered, // The smallest covered number + ~Folded, // Less folded is better + NumTVs, // Show more test vectors + }; + } + } + + float getPercentCovered() const { + auto [Covered, Folded] = getCoveredCount(); unsigned Total = getNumConditions() - Folded; if (Total == 0) @@ -1013,11 +1085,13 @@ class CoverageMapping { /// information. That is, only names returned from getUniqueSourceFiles will /// yield a result. CoverageData getCoverageForFile( - StringRef Filename, + StringRef Filename, MergeStrategy Strategy = MergeStrategy::Merge, const DenseSet &FilteredOutFunctions = {}) const; /// Get the coverage for a particular function. - CoverageData getCoverageForFunction(const FunctionRecord &Function) const; + CoverageData + getCoverageForFunction(const FunctionRecord &Function, + MergeStrategy Strategy = MergeStrategy::Merge) const; /// Get the coverage for an expansion within a coverage set. CoverageData getCoverageForExpansion(const ExpansionRecord &Expansion) const; diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index e7780b465186d..dbbf5b03d0205 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -221,6 +221,58 @@ Expected CounterMappingContext::evaluate(const Counter &C) const { return LastPoppedValue; } +void CountedRegion::merge(const CountedRegion &RHS, MergeStrategy Strategy) { + assert(this->isBranch() && RHS.isBranch()); + auto MergeCounts = [Strategy](uint64_t &LHSCount, bool &LHSFolded, + uint64_t RHSCount, bool RHSFolded) { + switch (Strategy) { + default: + llvm_unreachable("Don't perform by-parameter merging"); + case MergeStrategy::Merge: + LHSCount += RHSCount; + LHSFolded = (LHSFolded && !LHSCount && RHSFolded); + break; + case MergeStrategy::All: + LHSCount = (LHSFolded ? RHSCount + : RHSFolded ? LHSCount + : std::min(LHSCount, RHSCount)); + LHSFolded = (LHSFolded && RHSFolded); + break; + } + }; + + switch (Strategy) { + case MergeStrategy::Any: + // Take either better (more satisfied) hand side. + // FIXME: Really needed? Better just to merge? + if (this->getMergeRank(Strategy) < RHS.getMergeRank(Strategy)) + *this = RHS; + break; + case MergeStrategy::Merge: + case MergeStrategy::All: + // Able to merge by parameter. + MergeCounts(this->ExecutionCount, this->TrueFolded, RHS.ExecutionCount, + RHS.TrueFolded); + MergeCounts(this->FalseExecutionCount, this->FalseFolded, + RHS.FalseExecutionCount, RHS.FalseFolded); + break; + } +} + +void MCDCRecord::merge(MCDCRecord &&RHS, MergeStrategy Strategy) { + assert(this->PosToID == RHS.PosToID); + assert(this->CondLoc == RHS.CondLoc); + + switch (Strategy) { + case MergeStrategy::Merge: + case MergeStrategy::Any: + case MergeStrategy::All: + if (this->getMergeRank(Strategy) < RHS.getMergeRank(Strategy)) + *this = std::move(RHS); + return; + } +} + // Find an independence pair for each condition: // - The condition is true in one test and false in the other. // - The decision outcome is true one test and false in the other. @@ -1272,7 +1324,8 @@ class SegmentBuilder { /// Combine counts of regions which cover the same area. static ArrayRef - combineRegions(MutableArrayRef Regions) { + combineRegions(MutableArrayRef Regions, + MergeStrategy Strategy) { if (Regions.empty()) return Regions; auto Active = Regions.begin(); @@ -1298,8 +1351,22 @@ class SegmentBuilder { // value for that area. // We add counts of the regions of the same kind as the active region // to handle the both situations. - if (I->Kind == Active->Kind) + if (I->Kind != Active->Kind) + continue; + + switch (Strategy) { + case MergeStrategy::Merge: Active->ExecutionCount += I->ExecutionCount; + break; + case MergeStrategy::Any: + Active->ExecutionCount = + std::max(Active->ExecutionCount, I->ExecutionCount); + break; + case MergeStrategy::All: + Active->ExecutionCount = + std::min(Active->ExecutionCount, I->ExecutionCount); + break; + } } return Regions.drop_back(std::distance(++Active, End)); } @@ -1307,12 +1374,13 @@ class SegmentBuilder { public: /// Build a sorted list of CoverageSegments from a list of Regions. static std::vector - buildSegments(MutableArrayRef Regions) { + buildSegments(MutableArrayRef Regions, + MergeStrategy Strategy) { std::vector Segments; SegmentBuilder Builder(Segments); sortNestedRegions(Regions); - ArrayRef CombinedRegions = combineRegions(Regions); + ArrayRef CombinedRegions = combineRegions(Regions, Strategy); LLVM_DEBUG({ dbgs() << "Combined regions:\n"; @@ -1342,11 +1410,78 @@ class SegmentBuilder { } }; +template +static void mergeRecords(std::vector &Records, MergeStrategy Strategy) { + if (Records.empty()) + return; + + std::vector NewRecords; + + assert(Records.size() <= std::numeric_limits::max()); + + // Build up sorted indices (rather than pointers) of Records. + SmallVector BIdxs(Records.size()); + std::iota(BIdxs.begin(), BIdxs.end(), 0); + llvm::stable_sort(BIdxs, [&](auto A, auto B) { + auto StartA = Records[A].viewLoc(); + auto StartB = Records[B].viewLoc(); + return (std::tie(StartA, A) < std::tie(StartB, B)); + }); + + // 1st element should be stored into SubView. + auto I = BIdxs.begin(), E = BIdxs.end(); + SmallVector ViewRecords{Records[*I++]}; + + auto findMergeableInViewRecords = [&](const RecTy &Branch) { + auto I = ViewRecords.rbegin(), E = ViewRecords.rend(); + for (; I != E; ++I) + if (I->isMergeable(Branch)) + return I; + + // Not mergeable. + return E; + }; + + auto addRecordToSubView = [&] { + assert(!ViewRecords.empty() && "Should have the back"); + for (auto &Acc : ViewRecords) { + Acc.commit(); + NewRecords.push_back(std::move(Acc)); + } + }; + + for (; I != E; ++I) { + assert(!ViewRecords.empty() && "Should have the back in the loop"); + auto &AccB = ViewRecords.back(); + auto &Branch = Records[*I]; + + // Flush current and create the next SubView at the different line. + if (AccB.viewLoc().first != Branch.viewLoc().first) { + addRecordToSubView(); + ViewRecords = {Branch}; + } else if (auto AccI = findMergeableInViewRecords(Branch); + AccI != ViewRecords.rend()) { + // Merge the current Branch into the back of SubView. + AccI->merge(std::move(Branch), Strategy); + } else { + // Not mergeable. + ViewRecords.push_back(Branch); + } + } + + // Flush the last SubView. + addRecordToSubView(); + + // Replace + Records = std::move(NewRecords); +} + struct MergeableCoverageData : public CoverageData { std::vector CodeRegions; + MergeStrategy Strategy; - MergeableCoverageData(bool Single, StringRef Filename) - : CoverageData(Single, Filename) {} + MergeableCoverageData(MergeStrategy Strategy, bool Single, StringRef Filename) + : CoverageData(Single, Filename), Strategy(Strategy) {} void addFunctionRegions( const FunctionRecord &Function, @@ -1368,8 +1503,11 @@ struct MergeableCoverageData : public CoverageData { MCDCRecords.push_back(MR); } - CoverageData buildSegments() { - Segments = SegmentBuilder::buildSegments(CodeRegions); + CoverageData merge(MergeStrategy Strategy) { + mergeRecords(BranchRegions, Strategy); + mergeRecords(MCDCRecords, Strategy); + + Segments = SegmentBuilder::buildSegments(CodeRegions, Strategy); return CoverageData(std::move(*this)); } }; @@ -1423,10 +1561,10 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) { } CoverageData CoverageMapping::getCoverageForFile( - StringRef Filename, + StringRef Filename, MergeStrategy Strategy, const DenseSet &FilteredOutFunctions) const { assert(SingleByteCoverage); - MergeableCoverageData FileCoverage(*SingleByteCoverage, Filename); + MergeableCoverageData FileCoverage(Strategy, *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. @@ -1445,7 +1583,7 @@ CoverageData CoverageMapping::getCoverageForFile( LLVM_DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n"); - return FileCoverage.buildSegments(); + return FileCoverage.merge(Strategy); } std::vector @@ -1474,13 +1612,14 @@ CoverageMapping::getInstantiationGroups(StringRef Filename) const { } CoverageData -CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { +CoverageMapping::getCoverageForFunction(const FunctionRecord &Function, + MergeStrategy Strategy) const { auto MainFileID = findMainViewFileID(Function); if (!MainFileID) return CoverageData(); assert(SingleByteCoverage); - MergeableCoverageData FunctionCoverage(*SingleByteCoverage, + MergeableCoverageData FunctionCoverage(Strategy, *SingleByteCoverage, Function.Filenames[*MainFileID]); FunctionCoverage.addFunctionRegions( Function, [&](auto &CR) { return (CR.FileID == *MainFileID); }, @@ -1489,7 +1628,7 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { LLVM_DEBUG(dbgs() << "Emitting segments for function: " << Function.Name << "\n"); - return FunctionCoverage.buildSegments(); + return FunctionCoverage.merge(Strategy); } CoverageData CoverageMapping::getCoverageForExpansion( @@ -1511,7 +1650,8 @@ CoverageData CoverageMapping::getCoverageForExpansion( LLVM_DEBUG(dbgs() << "Emitting segments for expansion of file " << Expansion.FileID << "\n"); - ExpansionCoverage.Segments = SegmentBuilder::buildSegments(Regions); + ExpansionCoverage.Segments = + SegmentBuilder::buildSegments(Regions, MergeStrategy::Merge); return ExpansionCoverage; } diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp index 4d932eaf5944a..d8a7c056f3677 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp @@ -11,9 +11,9 @@ void unused(T x) { template int func(T x) { - if(x) // BRCOV: | Branch ([[@LINE]]:6): [True: 0, False: 1] - return 0; // BRCOV: | Branch ([[@LINE-1]]:6): [True: 1, False: 0] - else // BRCOV: | Branch ([[@LINE-2]]:6): [True: 0, False: 1] + if(x) // BRCOV: | Branch ([[@LINE]]:6): [True: 1, False: {{2|1}}] + return 0; + else return 1; int j = 1; } diff --git a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp new file mode 100644 index 0000000000000..09c2e0980cca8 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp @@ -0,0 +1,54 @@ +#include + +template +bool ab(Ty a, Ty b) { + return (a && b); +} +// MERGE: [[@LINE-2]]| 4| return +// ANY: [[@LINE-3]]| 2| return +// ALL: [[@LINE-4]]| 0| return + +// MERGE: MC/DC Coverage for Decision{{[:]}} 50.00% +// ANY: MC/DC Coverage for Decision{{[:]}} 50.00% +// ALL: MC/DC Coverage for Decision{{[:]}} 0.00% + +// CHECK: _Z2abIbEbT_S0_{{[:]}} +// CHECK: MC/DC Coverage for Decision{{[:]}} 50.00% + +// CHECK: _Z2abIxEbT_S0_{{[:]}} +// CHECK: MC/DC Coverage for Decision{{[:]}} 50.00% + +// CHECK: Unexecuted instantiation{{[:]}} _Z2abIdEbT_S0_ + +template +bool Cab(bool a, bool b) { + return (a && b && C); +} +// MERGE: [[@LINE-2]]| 4| return +// ANY: [[@LINE-3]]| 2| return +// ALL: [[@LINE-4]]| 2| return + +// MERGE: MC/DC Coverage for Decision{{[:]}} 50.00% +// ANY: MC/DC Coverage for Decision{{[:]}} 50.00% +// ALL: MC/DC Coverage for Decision{{[:]}} 0.00% + +// CHECK: _Z3CabILb0EEbbb{{[:]}} +// CHECK: MC/DC Coverage for Decision{{[:]}} 0.00% + +// CHECK: _Z3CabILb1EEbbb{{[:]}} +// CHECK: MC/DC Coverage for Decision{{[:]}} 50.00% + +// CHECK: [[@LINE+1]]| 1|int main +int main(int argc, char **argv) { + printf("%d\n", Cab(false, false)); + printf("%d\n", Cab(true, true)); + printf("%d\n", Cab(true, false)); + printf("%d\n", Cab(true, true)); + printf("%d\n", ab(false, false)); + printf("%d\n", ab(true, true)); + printf("%d\n", ab(1LL, 0LL)); + printf("%d\n", ab(1LL, 1LL)); + if (argc == 2) + printf("%d\n", ab(0.0, 0.0)); + return 0; +} diff --git a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext new file mode 100644 index 0000000000000..61369462b2fd4 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext @@ -0,0 +1,73 @@ +_Z2abIbEbT_S0_ +# Func Hash: +1550 +# Num Counters: +3 +# Counter Values: +2 +1 +1 +# Num Bitmap Bytes: +$1 +# Bitmap Byte Values: +0x5 + + +_Z2abIxEbT_S0_ +# Func Hash: +1550 +# Num Counters: +3 +# Counter Values: +2 +2 +1 +# Num Bitmap Bytes: +$1 +# Bitmap Byte Values: +0x6 + + +_Z3CabILb0EEbbb +# Func Hash: +99214 +# Num Counters: +5 +# Counter Values: +2 +1 +0 +1 +1 +# Num Bitmap Bytes: +$1 +# Bitmap Byte Values: +0x5 + + +_Z3CabILb1EEbbb +# Func Hash: +99214 +# Num Counters: +5 +# Counter Values: +2 +1 +1 +2 +1 +# Num Bitmap Bytes: +$1 +# Bitmap Byte Values: +0xa + + +main +# Func Hash: +175973464 +# Num Counters: +2 +# Counter Values: +1 +0 + diff --git a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml new file mode 100644 index 0000000000000..91d701a2172f8 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml @@ -0,0 +1,105 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 + SectionHeaderStringTable: .strtab +Sections: + - Name: __llvm_covfun + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: FAD58DE7366495DB2500000058247D0A00000000249EC986A505B62F010101010505012A210C020109070010200502000700100500110185808080080501050021 + - Name: '__llvm_covfun (1)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 9CC3B348501DBFE8480000008E83010000000000249EC986A505B62F010103010D0D1105090901181A020201010B000C01000B0011280403000B0016300D02010300000B000C0D0010001130110603020000100011050015001630000A02000000150016 + - Name: '__llvm_covfun (2)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 9873627177A03F8E460000008E83010000000000249EC986A505B62F010102010D0D110901181A020201010B000C01000B0011280403000B0016300D02010300000B000C0D0010001130110603020000100011050015001630090002000000150016 + - Name: '__llvm_covfun (3)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: BF407A207503B266320000000E06000000000000249EC986A505B62F0101020105050906010415020201010B000C280302000B0011300502010200000B000C050010001130090602000000100011 + - Name: '__llvm_covfun (4)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 8A05A22CB467C37D320000000E06000000000000249EC986A505B62F0101020105050906010415020201010B000C280302000B0011300502010200000B000C050010001130090602000000100011 + - Name: '__llvm_covfun (5)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 1700192CAC8F3F26320000000E06000000000000249EC986A505B62F0101020105050906010415020201010B000C280302000B0011300502010200000B000C050010001130090602000000100011 + - Name: __llvm_covmap + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 000000001D0000000000000006000000021A0000186D6364632D74656D706C617465732D6D657267652E637070000000 + - Name: __llvm_prf_names + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] + AddressAlign: 0x1 + Content: 51006D61696E015F5A33436162494C62304545626262015F5A33436162494C62314545626262015F5A32616249624562545F53305F015F5A32616249784562545F53305F015F5A32616249644562545F53305F + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: __llvm_covfun + - Name: '__llvm_covfun (1)' + - Name: '__llvm_covfun (2)' + - Name: '__llvm_covfun (3)' + - Name: '__llvm_covfun (4)' + - Name: '__llvm_covfun (5)' + - Name: __llvm_covmap + - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0x41 + Other: [ STV_HIDDEN ] + - Name: __covrec_E8BF1D5048B3C39Cu + Type: STT_OBJECT + Section: '__llvm_covfun (1)' + Binding: STB_WEAK + Size: 0x64 + Other: [ STV_HIDDEN ] + - Name: __covrec_8E3FA07771627398u + Type: STT_OBJECT + Section: '__llvm_covfun (2)' + Binding: STB_WEAK + Size: 0x62 + Other: [ STV_HIDDEN ] + - Name: __covrec_66B20375207A40BFu + Type: STT_OBJECT + Section: '__llvm_covfun (3)' + Binding: STB_WEAK + Size: 0x4E + Other: [ STV_HIDDEN ] + - Name: __covrec_7DC367B42CA2058Au + Type: STT_OBJECT + Section: '__llvm_covfun (4)' + Binding: STB_WEAK + Size: 0x4E + Other: [ STV_HIDDEN ] + - Name: __covrec_263F8FAC2C190017u + Type: STT_OBJECT + Section: '__llvm_covfun (5)' + Binding: STB_WEAK + Size: 0x4E + Other: [ STV_HIDDEN ] +... diff --git a/llvm/test/tools/llvm-cov/branch-export-json.test b/llvm/test/tools/llvm-cov/branch-export-json.test index 4278482c6d870..77e2bab7d9eb3 100644 --- a/llvm/test/tools/llvm-cov/branch-export-json.test +++ b/llvm/test/tools/llvm-cov/branch-export-json.test @@ -46,4 +46,4 @@ // MACROS: 5,15,5,23,1,2,8,0,4 // MACROS: 6,15,6,23,0,1,9,0,4 // MACROS: 8,15,8,38,1,2,2,0,4 -// MACROS: {"count":40,"covered":24,"notcovered":16,"percent":60} +// MACROS: {"count":16,"covered":6,"notcovered":10,"percent":37.5} diff --git a/llvm/test/tools/llvm-cov/branch-export-lcov.test b/llvm/test/tools/llvm-cov/branch-export-lcov.test index fe43dd66de8d0..444277435d60d 100644 --- a/llvm/test/tools/llvm-cov/branch-export-lcov.test +++ b/llvm/test/tools/llvm-cov/branch-export-lcov.test @@ -71,8 +71,8 @@ // MACROS-COUNT-10: BRDA:37 // MACROS-NOT: BRDA:37 // MACROS-NOT: BRDA -// MACROS: BRF:40 -// MACROS: BRH:24 +// MACROS: BRF:16 +// MACROS: BRH:6 // NOBRANCH-NOT: BRDA // NOBRANCH-NOT: BRF diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test index b892aba0a044a..1023d7cc47d4d 100644 --- a/llvm/test/tools/llvm-cov/branch-macros.test +++ b/llvm/test/tools/llvm-cov/branch-macros.test @@ -1,5 +1,8 @@ // RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata // RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV -D#C=999 +// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=REPORT +// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=FILE + // RUN: llvm-cov show --binary-counters=true --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV -D#C=1 // RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=REPORT @@ -14,3 +17,9 @@ // REPORT-NEXT: main 1 0 100.00% 6 0 100.00% 0 0 0.00% // REPORT-NEXT: --- // REPORT-NEXT: TOTAL 16 4 75.00% 32 0 100.00% 40 16 60.00% + +// FILE: Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover Branches Missed Branches Cover +// FILE-NEXT: --- +// FILE-NEXT: branch-macros.cpp 28 5 82.14% 3 0 100.00% 39 0 100.00% 16 10 37.50% +// FILE-NEXT: --- +// FILE-NEXT: TOTAL 28 5 82.14% 3 0 100.00% 39 0 100.00% 16 10 37.50% diff --git a/llvm/test/tools/llvm-cov/branch-templates.test b/llvm/test/tools/llvm-cov/branch-templates.test index 594a3ca533678..c4fc9cafbfd80 100644 --- a/llvm/test/tools/llvm-cov/branch-templates.test +++ b/llvm/test/tools/llvm-cov/branch-templates.test @@ -26,6 +26,6 @@ // REPORTFILE: Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover Branches Missed Branches Cover // REPORTFILE-NEXT: --- -// REPORTFILE-NEXT: branch-templates.cpp 12 2 83.33% 2 0 100.00% 17 3 82.35% 12 6 50.00% +// REPORTFILE-NEXT: branch-templates.cpp 12 2 83.33% 2 0 100.00% 17 3 82.35% 8 3 62.50% // REPORTFILE-NEXT: --- -// REPORTFILE-NEXT: TOTAL 12 2 83.33% 2 0 100.00% 17 3 82.35% 12 6 50.00% +// REPORTFILE-NEXT: TOTAL 12 2 83.33% 2 0 100.00% 17 3 82.35% 8 3 62.50% diff --git a/llvm/test/tools/llvm-cov/mcdc-templates-merge.test b/llvm/test/tools/llvm-cov/mcdc-templates-merge.test new file mode 100644 index 0000000000000..21c5458edfa84 --- /dev/null +++ b/llvm/test/tools/llvm-cov/mcdc-templates-merge.test @@ -0,0 +1,41 @@ +# Test `merge-instantiations=merge/any/all` + +RUN: yaml2obj %S/Inputs/mcdc-templates-merge.yaml -o %t.o +RUN: llvm-profdata merge %S/Inputs/mcdc-templates-merge.proftext -o %t.profdata + +RUN: llvm-cov show -merge-instantiations=merge --show-mcdc -show-instantiations=true %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/mcdc-templates-merge.cpp --check-prefixes=CHECK,MERGE +RUN: llvm-cov show -merge-instantiations=any --show-mcdc -show-instantiations=true %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/mcdc-templates-merge.cpp --check-prefixes=CHECK,ANY +RUN: llvm-cov show -merge-instantiations=all --show-mcdc -show-instantiations=true %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/mcdc-templates-merge.cpp --check-prefixes=CHECK,ALL + +RUN: llvm-cov report -merge-instantiations=merge --show-mcdc-summary %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s -check-prefixes=REPORT,MERGE +RUN: llvm-cov report -merge-instantiations=any --show-mcdc-summary %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s -check-prefixes=REPORT,ANY +RUN: llvm-cov report -merge-instantiations=all --show-mcdc-summary %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s -check-prefixes=REPORT,ALL + +REPORT: mcdc-templates-merge.cpp + +# Regions +MERGE: 10 1 90.00% +ANY: 10 1 90.00% +ALL: 10 4 60.00% + +# Functions +MERGE: 3 0 100.00% +ANY: 3 0 100.00% +ALL: 3 0 100.00% + +# Lines +MERGE: 19 1 94.74% +ANY: 19 1 94.74% +ALL: 19 4 78.95% + +# Branches +MERGE: 12 1 91.67% +ANY: 11 1 90.91% +ALL: 12 7 41.67% + +# MC/DC Conditions +MERGE: 4 2 50.00% +ANY: 4 2 50.00% +ALL: 4 4 0.00% + +REPORT: TOTAL diff --git a/llvm/tools/llvm-cov/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index 2d6da7efc6979..4ae4fff64ad4b 100644 --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -395,7 +395,8 @@ CodeCoverageTool::createSourceFileView(StringRef SourceFile, auto SourceBuffer = getSourceFile(SourceFile); if (!SourceBuffer) return nullptr; - auto FileCoverage = Coverage.getCoverageForFile(SourceFile); + auto FileCoverage = + Coverage.getCoverageForFile(SourceFile, ViewOpts.MergeStrategyOpts); if (FileCoverage.empty()) return nullptr; @@ -795,6 +796,14 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { "check-binary-ids", cl::desc("Fail if an object couldn't be found for a " "binary ID in the profile")); + cl::opt MergeStrategyOpts( + "merge-instantiations", cl::desc("Merge instantiations"), + cl::values( + clEnumValN(MergeStrategy::Merge, "merge", "Merge entries by adding"), + clEnumValN(MergeStrategy::Any, "any", "Pick up any better entries"), + clEnumValN(MergeStrategy::All, "all", "Pick up the worst entries")), + cl::init(MergeStrategy::Merge)); + auto commandLineParser = [&, this](int argc, const char **argv) -> int { cl::ParseCommandLineOptions(argc, argv, "LLVM code coverage tool\n"); ViewOpts.Debug = DebugDump; @@ -951,6 +960,7 @@ int CodeCoverageTool::run(Command Cmd, int argc, const char **argv) { ViewOpts.ExportSummaryOnly = SummaryOnly; ViewOpts.NumThreads = NumThreads; ViewOpts.CompilationDirectory = CompilationDirectory; + ViewOpts.MergeStrategyOpts = MergeStrategyOpts; return 0; }; diff --git a/llvm/tools/llvm-cov/CoverageReport.cpp b/llvm/tools/llvm-cov/CoverageReport.cpp index 0046b968756dd..9215e2421f514 100644 --- a/llvm/tools/llvm-cov/CoverageReport.cpp +++ b/llvm/tools/llvm-cov/CoverageReport.cpp @@ -480,8 +480,8 @@ void CoverageReport::prepareSingleFileReport(const StringRef Filename, /*Covered=*/Group.getTotalExecutionCount() > 0); } - auto FileCoverage = - Coverage->getCoverageForFile(Filename, FilteredOutFunctions); + auto FileCoverage = Coverage->getCoverageForFile( + Filename, Options.MergeStrategyOpts, FilteredOutFunctions); if (FileCoverage.empty()) return; diff --git a/llvm/tools/llvm-cov/CoverageViewOptions.h b/llvm/tools/llvm-cov/CoverageViewOptions.h index 81e69c3814e30..d2135a19e11f6 100644 --- a/llvm/tools/llvm-cov/CoverageViewOptions.h +++ b/llvm/tools/llvm-cov/CoverageViewOptions.h @@ -11,6 +11,7 @@ #include "RenderingSupport.h" #include "llvm/Config/llvm-config.h" +#include "llvm/ProfileData/Coverage/CoverageMapping.h" #include namespace llvm { @@ -48,6 +49,7 @@ struct CoverageViewOptions { bool BinaryCounters; OutputFormat Format; BranchOutputType ShowBranches; + coverage::MergeStrategy MergeStrategyOpts; std::string ShowOutputDirectory; std::vector DemanglerOpts; uint32_t TabSize; diff --git a/llvm/tools/llvm-cov/SourceCoverageView.cpp b/llvm/tools/llvm-cov/SourceCoverageView.cpp index dfecddfaf4143..1ef1952e691c9 100644 --- a/llvm/tools/llvm-cov/SourceCoverageView.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageView.cpp @@ -207,8 +207,8 @@ void SourceCoverageView::print(raw_ostream &OS, bool WholeFile, // through them while we iterate lines. llvm::stable_sort(ExpansionSubViews); llvm::stable_sort(InstantiationSubViews); - llvm::stable_sort(BranchSubViews); - llvm::stable_sort(MCDCSubViews); + // BranchSubViews is sorted. + // MCDCSubViews is sorted. auto NextESV = ExpansionSubViews.begin(); auto EndESV = ExpansionSubViews.end(); auto NextISV = InstantiationSubViews.begin(); From dc0ef8f682f704422ec52b484248cdfee1a6e804 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 27 Dec 2024 16:19:01 +0900 Subject: [PATCH 30/35] llvm-cov: [MCDC] Merge and recalculate independence pairs on template instantiations. --- .../ProfileData/Coverage/CoverageMapping.h | 16 ++++-- .../ProfileData/Coverage/CoverageMapping.cpp | 57 ++++++++++++++++--- .../llvm-cov/Inputs/mcdc-templates-merge.cpp | 4 +- .../tools/llvm-cov/mcdc-templates-merge.test | 2 +- 4 files changed, 62 insertions(+), 17 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index cfaee39565529..5d7d555a10bd3 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -471,6 +471,7 @@ struct MCDCRecord { } }; + using BitmapByCondTy = std::array; using TestVectors = llvm::SmallVector>; using BoolVector = std::array; using TVRowPair = std::pair; @@ -481,6 +482,7 @@ struct MCDCRecord { private: CounterMappingRegion Region; TestVectors TV; + BitmapByCondTy BitmapByCond; std::optional IndependencePairs; BoolVector Folded; CondIDMap PosToID; @@ -488,8 +490,10 @@ struct MCDCRecord { public: MCDCRecord(const CounterMappingRegion &Region, TestVectors &&TV, - BoolVector &&Folded, CondIDMap &&PosToID, LineColPairMap &&CondLoc) - : Region(Region), TV(std::move(TV)), Folded(std::move(Folded)), + BitmapByCondTy &&BitmapByCond, BoolVector &&Folded, + CondIDMap &&PosToID, LineColPairMap &&CondLoc) + : Region(Region), TV(std::move(TV)), + BitmapByCond(std::move(BitmapByCond)), Folded(std::move(Folded)), PosToID(std::move(PosToID)), CondLoc(std::move(CondLoc)) { findIndependencePairs(); } @@ -497,8 +501,9 @@ struct MCDCRecord { inline LineColPair viewLoc() const { return Region.endLoc(); } bool isMergeable(const MCDCRecord &RHS) const { - return (this->viewLoc() == RHS.viewLoc() && this->PosToID == RHS.PosToID && - this->CondLoc == RHS.CondLoc); + return (this->viewLoc() == RHS.viewLoc() && + this->BitmapByCond[false].size() == RHS.BitmapByCond[true].size() && + this->PosToID == RHS.PosToID && this->CondLoc == RHS.CondLoc); } // This may invalidate IndependencePairs @@ -577,7 +582,8 @@ struct MCDCRecord { auto [Covered, Folded] = getCoveredCount(); auto NumTVs = getNumTestVectors(); switch (Strategy) { - case MergeStrategy::Merge: + default: + llvm_unreachable("Not supported"); case MergeStrategy::Any: return { Covered, // The largest covered number diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 76aa008886291..8dd354f512225 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -260,17 +260,55 @@ void CountedRegion::merge(const CountedRegion &RHS, MergeStrategy Strategy) { } void MCDCRecord::merge(MCDCRecord &&RHS, MergeStrategy Strategy) { + assert(this->TV.size() == + this->BitmapByCond[false].count() + this->BitmapByCond[true].count()); + assert(RHS.TV.size() == + RHS.BitmapByCond[false].count() + RHS.BitmapByCond[true].count()); assert(this->PosToID == RHS.PosToID); assert(this->CondLoc == RHS.CondLoc); switch (Strategy) { case MergeStrategy::Merge: + break; case MergeStrategy::Any: case MergeStrategy::All: if (this->getMergeRank(Strategy) < RHS.getMergeRank(Strategy)) *this = std::move(RHS); return; } + + std::array LHSTV; + auto LHSI = this->TV.begin(); + auto RHSI = RHS.TV.begin(); + bool Merged = false; + for (auto MCDCCond : {MCDCRecord::MCDC_False, MCDCRecord::MCDC_True}) { + auto &LHSBitmap = this->BitmapByCond[MCDCCond]; + auto &RHSBitmap = RHS.BitmapByCond[MCDCCond]; + for (unsigned I = 0, E = LHSBitmap.size(); I != E; ++I) { + if (LHSBitmap[I]) { + if (RHSBitmap[I]) + ++RHSI; + LHSTV[LHSI->second].push_back(std::move(*LHSI++)); + } else if (RHSBitmap[I]) { + LHSTV[RHSI->second].push_back(std::move(*RHSI++)); + LHSBitmap[I] = true; + Merged = true; + } + } + + this->Folded[MCDCCond] &= RHS.Folded[MCDCCond]; + } + + if (Merged) + IndependencePairs.reset(); + + assert(LHSI == this->TV.end()); + assert(RHSI == RHS.TV.end()); + this->TV = std::move(LHSTV[false]); + this->TV.append(std::make_move_iterator(LHSTV[true].begin()), + std::make_move_iterator(LHSTV[true].end())); + assert(this->TV.size() == + this->BitmapByCond[false].count() + this->BitmapByCond[true].count()); } // Find an independence pair for each condition: @@ -284,13 +322,7 @@ void MCDCRecord::findIndependencePairs() { IndependencePairs.emplace(); unsigned NumTVs = TV.size(); - // Will be replaced to shorter expr. - unsigned TVTrueIdx = std::distance( - TV.begin(), - std::find_if(TV.begin(), TV.end(), - [&](auto I) { return (I.second == MCDCRecord::MCDC_True); }) - - ); + unsigned TVTrueIdx = BitmapByCond[false].count(); for (unsigned I = TVTrueIdx; I < NumTVs; ++I) { const auto &[A, ACond] = TV[I]; assert(ACond == MCDCRecord::MCDC_True); @@ -435,6 +467,7 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { /// with a bit value of '1' indicates that the corresponding Test Vector /// identified by that index was executed. const BitVector &Bitmap; + MCDCRecord::BitmapByCondTy BitmapByCond; /// Decision Region to which the ExecutedTestVectorBitmap applies. const CounterMappingRegion &Region; @@ -487,6 +520,7 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { ArrayRef Branches, bool IsVersion11) : NextIDsBuilder(Branches), TVIdxBuilder(this->NextIDs), Bitmap(Bitmap), + BitmapByCond{{BitVector(NumTestVectors), BitVector(NumTestVectors)}}, Region(Region), DecisionParams(Region.getDecisionParams()), Branches(Branches), NumConditions(DecisionParams.NumConditions), Folded{{BitVector(NumConditions), BitVector(NumConditions)}}, @@ -518,6 +552,8 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { : DecisionParams.BitmapIdx - NumTestVectors + NextTVIdx]) continue; + assert(!BitmapByCond[MCDCCond][NextTVIdx]); + BitmapByCond[MCDCCond][NextTVIdx] = true; ExecVectorIdxs.emplace_back(MCDCCond, NextTVIdx, ExecVectors.size()); // Copy the completed test vector to the vector of testvectors. @@ -547,6 +583,8 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { for (const auto &IdxTuple : ExecVectorIdxs) NewTestVectors.push_back(std::move(ExecVectors[IdxTuple.Ord])); ExecVectors = std::move(NewTestVectors); + + assert(!BitmapByCond[false].anyCommon(BitmapByCond[true])); } public: @@ -585,8 +623,9 @@ class MCDCRecordProcessor : NextIDsBuilder, mcdc::TVIdxBuilder { findExecutedTestVectors(); // Record Test vectors, executed vectors, and independence pairs. - return MCDCRecord(Region, std::move(ExecVectors), std::move(Folded), - std::move(PosToID), std::move(CondLoc)); + return MCDCRecord(Region, std::move(ExecVectors), std::move(BitmapByCond), + std::move(Folded), std::move(PosToID), + std::move(CondLoc)); } }; diff --git a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp index 09c2e0980cca8..46d1260d12274 100644 --- a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp @@ -8,7 +8,7 @@ bool ab(Ty a, Ty b) { // ANY: [[@LINE-3]]| 2| return // ALL: [[@LINE-4]]| 0| return -// MERGE: MC/DC Coverage for Decision{{[:]}} 50.00% +// MERGE: MC/DC Coverage for Decision{{[:]}} 100.00% // ANY: MC/DC Coverage for Decision{{[:]}} 50.00% // ALL: MC/DC Coverage for Decision{{[:]}} 0.00% @@ -28,7 +28,7 @@ bool Cab(bool a, bool b) { // ANY: [[@LINE-3]]| 2| return // ALL: [[@LINE-4]]| 2| return -// MERGE: MC/DC Coverage for Decision{{[:]}} 50.00% +// MERGE: MC/DC Coverage for Decision{{[:]}} 100.00% // ANY: MC/DC Coverage for Decision{{[:]}} 50.00% // ALL: MC/DC Coverage for Decision{{[:]}} 0.00% diff --git a/llvm/test/tools/llvm-cov/mcdc-templates-merge.test b/llvm/test/tools/llvm-cov/mcdc-templates-merge.test index 21c5458edfa84..d4369dc2db293 100644 --- a/llvm/test/tools/llvm-cov/mcdc-templates-merge.test +++ b/llvm/test/tools/llvm-cov/mcdc-templates-merge.test @@ -34,7 +34,7 @@ ANY: 11 1 90.91% ALL: 12 7 41.67% # MC/DC Conditions -MERGE: 4 2 50.00% +MERGE: 5 0 100.00% ANY: 4 2 50.00% ALL: 4 4 0.00% From 71b5be74823e64fc27ed3a5753e196c7f6d36344 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 6 Jan 2025 23:08:13 +0900 Subject: [PATCH 31/35] s/IsSummaryEmpty/isSummaryEmpty/ --- llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp index cb0ea6e0cdafc..e53f7618dc0bf 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp @@ -24,7 +24,7 @@ using namespace llvm; namespace { template -bool IsSummaryEmpty(const SummaryTy &Report, const CoverageViewOptions &Opts) { +bool isSummaryEmpty(const SummaryTy &Report, const CoverageViewOptions &Opts) { return !(Report.FunctionCoverage.getNumFunctions() || (Opts.ShowInstantiationSummary && Report.InstantiationCoverage.getNumFunctions()) || @@ -676,7 +676,7 @@ Error CoveragePrinterHTML::createIndexFile( Coverage, Totals, SourceFiles, Opts, Filters); bool EmptyFiles = false; for (unsigned I = 0, E = FileReports.size(); I < E; ++I) { - if (!IsSummaryEmpty(FileReports[I], Opts)) + if (!isSummaryEmpty(FileReports[I], Opts)) emitFileSummary(OSRef, SourceFiles[I], FileReports[I]); else EmptyFiles = true; @@ -744,7 +744,7 @@ struct CoveragePrinterHTMLDirectory::Reporter : public DirectoryCoverageReport { // Make directories at the top of the table. for (auto &&SubDir : SubDirs) { auto &Report = SubDir.second.first; - if (IsSummaryEmpty(Report, Printer.Opts)) + if (isSummaryEmpty(Report, Printer.Opts)) EmptyFiles.push_back(&Report); else emitTableRow(OSRef, Options, buildRelLinkToFile(Report.Name), Report, @@ -753,7 +753,7 @@ struct CoveragePrinterHTMLDirectory::Reporter : public DirectoryCoverageReport { for (auto &&SubFile : SubFiles) { auto &Report = SubFile.second; - if (IsSummaryEmpty(Report, Printer.Opts)) + if (isSummaryEmpty(Report, Printer.Opts)) EmptyFiles.push_back(&Report); else emitTableRow(OSRef, Options, buildRelLinkToFile(Report.Name), Report, From 694a772457b2999b7bd68625a16bf0755e95dcdb Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 7 Jan 2025 11:26:52 +0900 Subject: [PATCH 32/35] Revert "Merge branch 'users/chapuni/cov/single/unify' into users/chapuni/cov/merge/mcdcsort-base" This reverts commit c33e8987289f2775792977ee279c4e458f8091d5, reversing changes made to ad6726dbfac5074c856f41adadb3b5bc14580311. --- .../ProfileData/Coverage/CoverageMapping.h | 3 - .../ProfileData/Coverage/CoverageMapping.cpp | 80 +++++++++---------- 2 files changed, 38 insertions(+), 45 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index a9ad258716a1c..504c24c27d84c 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -891,7 +891,6 @@ class InstantiationGroup { class CoverageData { friend class CoverageMapping; -protected: std::string Filename; std::vector Segments; std::vector Expansions; @@ -906,8 +905,6 @@ 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 a8e13d5c73fb5..c196dbaab6694 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -1357,37 +1357,6 @@ 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 { @@ -1439,7 +1408,8 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) { CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { assert(SingleByteCoverage); - MergeableCoverageData FileCoverage(*SingleByteCoverage, Filename); + CoverageData FileCoverage(*SingleByteCoverage, Filename); + std::vector Regions; // 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. @@ -1449,14 +1419,26 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { const FunctionRecord &Function = Functions[RecordIndex]; auto MainFileID = findMainViewFileID(Filename, Function); auto FileIDs = gatherFileIDs(Filename, Function); - FileCoverage.addFunctionRegions( - Function, [&](auto &CR) { return FileIDs.test(CR.FileID); }, - [&](auto &CR) { return (MainFileID && isExpansion(CR, *MainFileID)); }); + 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); } LLVM_DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n"); + FileCoverage.Segments = SegmentBuilder::buildSegments(Regions); - return FileCoverage.buildSegments(); + return FileCoverage; } std::vector @@ -1491,16 +1473,30 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { return CoverageData(); assert(SingleByteCoverage); - MergeableCoverageData FunctionCoverage(*SingleByteCoverage, - Function.Filenames[*MainFileID]); - FunctionCoverage.addFunctionRegions( - Function, [&](auto &CR) { return (CR.FileID == *MainFileID); }, - [&](auto &CR) { return isExpansion(CR, *MainFileID); }); + 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); LLVM_DEBUG(dbgs() << "Emitting segments for function: " << Function.Name << "\n"); + FunctionCoverage.Segments = SegmentBuilder::buildSegments(Regions); - return FunctionCoverage.buildSegments(); + return FunctionCoverage; } CoverageData CoverageMapping::getCoverageForExpansion( From 0350c1eba1c1a6b73a8d9c271a7f3c8b33202579 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 10 Jan 2025 19:24:41 +0900 Subject: [PATCH 33/35] Move mcdc-templates-merge.test from #121194 --- .../llvm-cov/Inputs/mcdc-templates-merge.cpp | 51 +++++++++ .../Inputs/mcdc-templates-merge.proftext | 73 ++++++++++++ .../llvm-cov/Inputs/mcdc-templates-merge.yaml | 105 ++++++++++++++++++ llvm/test/tools/llvm-cov/branch-macros.test | 8 ++ .../tools/llvm-cov/mcdc-templates-merge.test | 27 +++++ 5 files changed, 264 insertions(+) create mode 100644 llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp create mode 100644 llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext create mode 100644 llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml create mode 100644 llvm/test/tools/llvm-cov/mcdc-templates-merge.test diff --git a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp new file mode 100644 index 0000000000000..0abb308848b68 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.cpp @@ -0,0 +1,51 @@ +#include + +template +bool ab(Ty a, Ty b) { + return (a && b); +} +// CHECK: [[@LINE-2]]| 4| return + +// CHECK: MC/DC Coverage for Decision{{[:]}} 50.00% +// CHECK: MC/DC Coverage for Decision{{[:]}} 50.00% +// CHECK: MC/DC Coverage for Decision{{[:]}} 0.00% +// CHECK-NOT: MC/DC Coverage for Decision{{[:]}} + +// CHECK: _Z2abIbEbT_S0_{{[:]}} +// CHECK: | | MC/DC Coverage for Decision{{[:]}} 50.00% + +// CHECK: _Z2abIxEbT_S0_{{[:]}} +// CHECK: | | MC/DC Coverage for Decision{{[:]}} 50.00% + +// CHECK: Unexecuted instantiation{{[:]}} _Z2abIdEbT_S0_ + +template +bool Cab(bool a, bool b) { + return (a && b && C); +} +// CHECK: [[@LINE-2]]| 4| return + +// CHECK: MC/DC Coverage for Decision{{[:]}} 0.00% +// CHECK: MC/DC Coverage for Decision{{[:]}} 50.00% +// CHECK-NOT: MC/DC Coverage for Decision{{[:]}} + +// CHECK: _Z3CabILb0EEbbb{{[:]}} +// CHECK: | | MC/DC Coverage for Decision{{[:]}} 0.00% + +// CHECK: _Z3CabILb1EEbbb{{[:]}} +// CHECK: | | MC/DC Coverage for Decision{{[:]}} 50.00% + +// CHECK: [[@LINE+1]]| 1|int main +int main(int argc, char **argv) { + printf("%d\n", Cab(false, false)); + printf("%d\n", Cab(true, true)); + printf("%d\n", Cab(true, false)); + printf("%d\n", Cab(true, true)); + printf("%d\n", ab(false, false)); + printf("%d\n", ab(true, true)); + printf("%d\n", ab(1LL, 0LL)); + printf("%d\n", ab(1LL, 1LL)); + if (argc == 2) + printf("%d\n", ab(0.0, 0.0)); + return 0; +} diff --git a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext new file mode 100644 index 0000000000000..61369462b2fd4 --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.proftext @@ -0,0 +1,73 @@ +_Z2abIbEbT_S0_ +# Func Hash: +1550 +# Num Counters: +3 +# Counter Values: +2 +1 +1 +# Num Bitmap Bytes: +$1 +# Bitmap Byte Values: +0x5 + + +_Z2abIxEbT_S0_ +# Func Hash: +1550 +# Num Counters: +3 +# Counter Values: +2 +2 +1 +# Num Bitmap Bytes: +$1 +# Bitmap Byte Values: +0x6 + + +_Z3CabILb0EEbbb +# Func Hash: +99214 +# Num Counters: +5 +# Counter Values: +2 +1 +0 +1 +1 +# Num Bitmap Bytes: +$1 +# Bitmap Byte Values: +0x5 + + +_Z3CabILb1EEbbb +# Func Hash: +99214 +# Num Counters: +5 +# Counter Values: +2 +1 +1 +2 +1 +# Num Bitmap Bytes: +$1 +# Bitmap Byte Values: +0xa + + +main +# Func Hash: +175973464 +# Num Counters: +2 +# Counter Values: +1 +0 + diff --git a/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml new file mode 100644 index 0000000000000..ba46319a63e8a --- /dev/null +++ b/llvm/test/tools/llvm-cov/Inputs/mcdc-templates-merge.yaml @@ -0,0 +1,105 @@ +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + OSABI: ELFOSABI_GNU + Type: ET_REL + Machine: EM_X86_64 + SectionHeaderStringTable: .strtab +Sections: + - Name: __llvm_covfun + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: FAD58DE7366495DB2500000058247D0A00000000249EC986A505B62F0101010105050127210C020109070010200502000700100500110185808080080501050021 + - Name: '__llvm_covfun (1)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 9CC3B348501DBFE8480000008E83010000000000249EC986A505B62F010103010D0D1105090901171A020201010B000C01000B0011280403000B0016300D02010300000B000C0D0010001130110603020000100011050015001630000A02000000150016 + - Name: '__llvm_covfun (2)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 9873627177A03F8E460000008E83010000000000249EC986A505B62F010102010D0D110901171A020201010B000C01000B0011280403000B0016300D02010300000B000C0D0010001130110603020000100011050015001630090002000000150016 + - Name: '__llvm_covfun (3)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: BF407A207503B266320000000E06000000000000249EC986A505B62F0101020105050906010415020201010B000C280302000B0011300502010200000B000C050010001130090602000000100011 + - Name: '__llvm_covfun (4)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 8A05A22CB467C37D320000000E06000000000000249EC986A505B62F0101020105050906010415020201010B000C280302000B0011300502010200000B000C050010001130090602000000100011 + - Name: '__llvm_covfun (5)' + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 1700192CAC8F3F26320000000E06000000000000249EC986A505B62F0101020105050906010415020201010B000C280302000B0011300502010200000B000C050010001130090602000000100011 + - Name: __llvm_covmap + Type: SHT_PROGBITS + Flags: [ SHF_GNU_RETAIN ] + AddressAlign: 0x8 + Content: 000000001D0000000000000006000000021A0000186D6364632D74656D706C617465732D6D657267652E637070000000 + - Name: __llvm_prf_names + Type: SHT_PROGBITS + Flags: [ SHF_ALLOC, SHF_GNU_RETAIN ] + AddressAlign: 0x1 + Content: 51006D61696E015F5A33436162494C62304545626262015F5A33436162494C62314545626262015F5A32616249624562545F53305F015F5A32616249784562545F53305F015F5A32616249644562545F53305F + - Type: SectionHeaderTable + Sections: + - Name: .strtab + - Name: __llvm_covfun + - Name: '__llvm_covfun (1)' + - Name: '__llvm_covfun (2)' + - Name: '__llvm_covfun (3)' + - Name: '__llvm_covfun (4)' + - Name: '__llvm_covfun (5)' + - Name: __llvm_covmap + - Name: __llvm_prf_names + - Name: .symtab +Symbols: + - Name: __llvm_covmap + Type: STT_SECTION + Section: __llvm_covmap + - Name: __llvm_prf_names + Type: STT_SECTION + Section: __llvm_prf_names + - Name: __covrec_DB956436E78DD5FAu + Type: STT_OBJECT + Section: __llvm_covfun + Binding: STB_WEAK + Size: 0x41 + Other: [ STV_HIDDEN ] + - Name: __covrec_E8BF1D5048B3C39Cu + Type: STT_OBJECT + Section: '__llvm_covfun (1)' + Binding: STB_WEAK + Size: 0x64 + Other: [ STV_HIDDEN ] + - Name: __covrec_8E3FA07771627398u + Type: STT_OBJECT + Section: '__llvm_covfun (2)' + Binding: STB_WEAK + Size: 0x62 + Other: [ STV_HIDDEN ] + - Name: __covrec_66B20375207A40BFu + Type: STT_OBJECT + Section: '__llvm_covfun (3)' + Binding: STB_WEAK + Size: 0x4E + Other: [ STV_HIDDEN ] + - Name: __covrec_7DC367B42CA2058Au + Type: STT_OBJECT + Section: '__llvm_covfun (4)' + Binding: STB_WEAK + Size: 0x4E + Other: [ STV_HIDDEN ] + - Name: __covrec_263F8FAC2C190017u + Type: STT_OBJECT + Section: '__llvm_covfun (5)' + Binding: STB_WEAK + Size: 0x4E + Other: [ STV_HIDDEN ] +... diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test index 2ff4355def234..b60da157810cf 100644 --- a/llvm/test/tools/llvm-cov/branch-macros.test +++ b/llvm/test/tools/llvm-cov/branch-macros.test @@ -1,5 +1,7 @@ // RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata // RUN: llvm-cov show --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV -D#C=999 +// RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=FILE + // RUN: llvm-cov show --binary-counters --show-expansions --show-branches=count %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs | FileCheck %S/Inputs/branch-macros.cpp -check-prefixes=CHECK,BRCOV -D#C=1 // RUN: llvm-cov report --show-branch-summary %S/Inputs/branch-macros.o32l -instr-profile %t.profdata -show-functions -path-equivalence=/tmp,%S/Inputs %S/Inputs/branch-macros.cpp | FileCheck %s -check-prefix=REPORT @@ -14,3 +16,9 @@ // REPORT-NEXT: main 1 0 100.00% 6 0 100.00% 0 0 0.00% // REPORT-NEXT: --- // REPORT-NEXT: TOTAL 16 4 75.00% 32 0 100.00% 40 16 60.00% + +// FILE: Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover Branches Missed Branches Cover +// FILE-NEXT: --- +// FILE-NEXT: branch-macros.cpp 16 4 75.00% 3 0 100.00% 32 0 100.00% 40 16 60.00% +// FILE-NEXT: --- +// FILE-NEXT: TOTAL 16 4 75.00% 3 0 100.00% 32 0 100.00% 40 16 60.00% diff --git a/llvm/test/tools/llvm-cov/mcdc-templates-merge.test b/llvm/test/tools/llvm-cov/mcdc-templates-merge.test new file mode 100644 index 0000000000000..cacd3b6bc6d84 --- /dev/null +++ b/llvm/test/tools/llvm-cov/mcdc-templates-merge.test @@ -0,0 +1,27 @@ +# Test `merge-instantiations=merge/any/all` + +RUN: yaml2obj %S/Inputs/mcdc-templates-merge.yaml -o %t.o +RUN: llvm-profdata merge %S/Inputs/mcdc-templates-merge.proftext -o %t.profdata + +RUN: llvm-cov show --show-mcdc -show-instantiations=true %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %S/Inputs/mcdc-templates-merge.cpp + +RUN: llvm-cov report --show-mcdc-summary %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s + +REPORT: mcdc-templates-merge.cpp + +# Regions +CHECK: 10 1 90.00% + +# Functions +CHECK: 3 0 100.00% + +# Lines +CHECK: 19 1 94.74% + +# Branches +CHECK: 11 3 72.73% + +# MC/DC Conditions +CHECK: 4 2 50.00% + +REPORT: TOTAL From 33f28e8719a98111e19eaf90e986b2955e9d517f Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 10 Jan 2025 19:28:27 +0900 Subject: [PATCH 34/35] Update tests --- llvm/test/tools/llvm-cov/branch-macros.test | 4 ++-- llvm/test/tools/llvm-cov/mcdc-templates-merge.test | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test index b60da157810cf..469f24dbcd810 100644 --- a/llvm/test/tools/llvm-cov/branch-macros.test +++ b/llvm/test/tools/llvm-cov/branch-macros.test @@ -19,6 +19,6 @@ // FILE: Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover Branches Missed Branches Cover // FILE-NEXT: --- -// FILE-NEXT: branch-macros.cpp 16 4 75.00% 3 0 100.00% 32 0 100.00% 40 16 60.00% +// FILE-NEXT: branch-macros.cpp 28 5 82.14% 3 0 100.00% 39 0 100.00% 40 16 60.00% // FILE-NEXT: --- -// FILE-NEXT: TOTAL 16 4 75.00% 3 0 100.00% 32 0 100.00% 40 16 60.00% +// FILE-NEXT: TOTAL 28 5 82.14% 3 0 100.00% 39 0 100.00% 40 16 60.00% diff --git a/llvm/test/tools/llvm-cov/mcdc-templates-merge.test b/llvm/test/tools/llvm-cov/mcdc-templates-merge.test index cacd3b6bc6d84..3ba8d159b9a19 100644 --- a/llvm/test/tools/llvm-cov/mcdc-templates-merge.test +++ b/llvm/test/tools/llvm-cov/mcdc-templates-merge.test @@ -19,9 +19,9 @@ CHECK: 3 0 100.00% CHECK: 19 1 94.74% # Branches -CHECK: 11 3 72.73% +CHECK: 24 9 62.50% # MC/DC Conditions -CHECK: 4 2 50.00% +CHECK: 10 7 30.00% REPORT: TOTAL From 5cf0511fdc928f3f1ae3bdae9d20612ad4978740 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 10 Jan 2025 23:35:04 +0900 Subject: [PATCH 35/35] std::iota --- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 1a00519806b8c..4c99e81d4f6d0 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -36,6 +36,7 @@ #include #include #include +#include #include #include #include
FilenameFunction CoverageLine CoverageRegion Coverage +// HTML-INDEX: 100.00% (1/1) +// HTML-INDEX: +// HTML-INDEX: 90.00% (18/20) +// HTML-INDEX: +// HTML-INDEX: 72.73% (8/11) +// HTML-INDEX:
// HTML-INDEX: 96.58% (226/234) // HTML-INDEX: -// HTML-INDEX: 87.82% (173/197) +// HTML-INDEX: 87.77% (165/188) // HTML-INDEX: // HTML-INDEX: 79.07% (136/172) // HTML-INDEX:
// HTML-INDEX: 100.00% (2/2) // HTML-INDEX: 100.00% (20/20) -// HTML-INDEX: 100.00% (26/26) +// HTML-INDEX: 100.00% (22/22) // HTML-INDEX: 91.67% (22/24) // HTML-INDEX: 0.00% (0/12) // HTML-INDEX: Totals diff --git a/llvm/test/tools/llvm-cov/mcdc-general.test b/llvm/test/tools/llvm-cov/mcdc-general.test index c1e95cb2bd92a..7ae9e180c00c2 100644 --- a/llvm/test/tools/llvm-cov/mcdc-general.test +++ b/llvm/test/tools/llvm-cov/mcdc-general.test @@ -100,10 +100,10 @@ // REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover MC/DC Conditions Miss Cover // REPORT-NEXT: ------------------------------------------------------------------------------------------------------------------------------------------- -// REPORT-NEXT: _Z4testbbbb 25 0 100.00% 9 0 100.00% 24 2 91.67% 12 2 83.33% +// REPORT-NEXT: _Z4testbbbb 21 0 100.00% 9 0 100.00% 24 2 91.67% 12 2 83.33% // REPORT-NEXT: main 1 0 100.00% 11 0 100.00% 0 0 0.00% 0 0 0.00% // REPORT-NEXT: --- -// REPORT-NEXT: TOTAL 26 0 100.00% 20 0 100.00% 24 2 91.67% 12 2 83.33% +// REPORT-NEXT: TOTAL 22 0 100.00% 20 0 100.00% 24 2 91.67% 12 2 83.33% // Turn off MC/DC summary. // RUN: llvm-cov report %S/Inputs/mcdc-general.o -instr-profile %t.profdata -show-functions -path-equivalence=.,%S/Inputs %S/Inputs/mcdc-general.cpp | FileCheck %s -check-prefix=REPORT_NOMCDC @@ -133,7 +133,7 @@ // HTML-INDEX: // HTML-INDEX: 100.00% (2/2) // HTML-INDEX: 100.00% (20/20) -// HTML-INDEX: 100.00% (26/26) +// HTML-INDEX: 100.00% (22/22) // HTML-INDEX: 91.67% (22/24) // HTML-INDEX: 83.33% (10/12) // HTML-INDEX: Totals diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp index 5c002a694f66a..86d11266ecdd7 100644 --- a/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp +++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.cpp @@ -63,14 +63,15 @@ auto sumMCDCPairs(const ArrayRef &Records) { } static std::pair -sumRegions(ArrayRef CodeRegions, const CoverageData &CD) { +sumRegions(const CoverageData &CD) { // Compute the region coverage. size_t NumCodeRegions = 0, CoveredRegions = 0; - for (auto &CR : CodeRegions) { - if (CR.Kind != CounterMappingRegion::CodeRegion) + for (auto I = CD.begin(), E = CD.end(); I != E; ++I) { + if (!I->IsRegionEntry || !I->HasCount || I->IsGapRegion) continue; + ++NumCodeRegions; - if (CR.ExecutionCount != 0) + if (I->Count) ++CoveredRegions; } @@ -88,9 +89,8 @@ sumRegions(ArrayRef CodeRegions, const CoverageData &CD) { LineCoverageInfo(CoveredLines, NumLines)}; } -CoverageDataSummary::CoverageDataSummary(const CoverageData &CD, - ArrayRef CodeRegions) { - std::tie(RegionCoverage, LineCoverage) = sumRegions(CodeRegions, CD); +CoverageDataSummary::CoverageDataSummary(const CoverageData &CD) { + std::tie(RegionCoverage, LineCoverage) = sumRegions(CD); BranchCoverage = sumBranches(CD.getBranches()); MCDCCoverage = sumMCDCPairs(CD.getMCDCRecords()); } @@ -103,7 +103,7 @@ FunctionCoverageSummary::get(const CoverageMapping &CM, auto Summary = FunctionCoverageSummary(Function.Name, Function.ExecutionCount); - Summary += CoverageDataSummary(CD, Function.CountedRegions); + Summary += CoverageDataSummary(CD); // Compute the branch coverage, including branches from expansions. Summary.BranchCoverage += sumBranchExpansions(CM, CD.getExpansions()); diff --git a/llvm/tools/llvm-cov/CoverageSummaryInfo.h b/llvm/tools/llvm-cov/CoverageSummaryInfo.h index d9210676c41bf..42398ee06100e 100644 --- a/llvm/tools/llvm-cov/CoverageSummaryInfo.h +++ b/llvm/tools/llvm-cov/CoverageSummaryInfo.h @@ -230,8 +230,7 @@ struct CoverageDataSummary { MCDCCoverageInfo MCDCCoverage; CoverageDataSummary() = default; - CoverageDataSummary(const coverage::CoverageData &CD, - ArrayRef CodeRegions); + CoverageDataSummary(const coverage::CoverageData &CD); auto &operator+=(const CoverageDataSummary &RHS) { RegionCoverage += RHS.RegionCoverage; From c1678ea160892c7b0912d9521866073a6b2ff839 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 27 Dec 2024 16:11:10 +0900 Subject: [PATCH 28/35] llvm-cov: Use `getCoverageForFile()` --- .../ProfileData/Coverage/CoverageMapping.h | 4 +- .../ProfileData/Coverage/CoverageMapping.cpp | 6 ++- .../test/tools/llvm-cov/branch-templates.test | 4 +- .../tools/llvm-cov/coverage_watermark.test | 22 ++++---- llvm/test/tools/llvm-cov/zeroFunctionFile.c | 3 +- llvm/tools/llvm-cov/CoverageReport.cpp | 42 +++++++++++---- llvm/tools/llvm-cov/CoverageSummaryInfo.cpp | 26 ---------- llvm/tools/llvm-cov/CoverageSummaryInfo.h | 51 +++++-------------- .../tools/llvm-cov/SourceCoverageViewHTML.cpp | 16 ++++-- 9 files changed, 79 insertions(+), 95 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index c51733b46a189..64416fdba1b24 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -1012,7 +1012,9 @@ class CoverageMapping { /// The given filename must be the name as recorded in the coverage /// information. That is, only names returned from getUniqueSourceFiles will /// yield a result. - CoverageData getCoverageForFile(StringRef Filename) const; + CoverageData getCoverageForFile( + StringRef Filename, + const DenseSet &FilteredOutFunctions = {}) const; /// Get the coverage for a particular function. CoverageData getCoverageForFunction(const FunctionRecord &Function) const; diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index feededcd7d1eb..e7780b465186d 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -1422,7 +1422,9 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) { return R.Kind == CounterMappingRegion::ExpansionRegion && R.FileID == FileID; } -CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { +CoverageData CoverageMapping::getCoverageForFile( + StringRef Filename, + const DenseSet &FilteredOutFunctions) const { assert(SingleByteCoverage); MergeableCoverageData FileCoverage(*SingleByteCoverage, Filename); @@ -1432,6 +1434,8 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { getImpreciseRecordIndicesForFilename(Filename); for (unsigned RecordIndex : RecordIndices) { const FunctionRecord &Function = Functions[RecordIndex]; + if (FilteredOutFunctions.count(&Function)) + continue; auto MainFileID = findMainViewFileID(Filename, Function); auto FileIDs = gatherFileIDs(Filename, Function); FileCoverage.addFunctionRegions( diff --git a/llvm/test/tools/llvm-cov/branch-templates.test b/llvm/test/tools/llvm-cov/branch-templates.test index d5535022239f5..594a3ca533678 100644 --- a/llvm/test/tools/llvm-cov/branch-templates.test +++ b/llvm/test/tools/llvm-cov/branch-templates.test @@ -26,6 +26,6 @@ // REPORTFILE: Filename Regions Missed Regions Cover Functions Missed Functions Executed Lines Missed Lines Cover Branches Missed Branches Cover // REPORTFILE-NEXT: --- -// REPORTFILE-NEXT: branch-templates.cpp 12 3 75.00% 2 0 100.00% 17 4 76.47% 8 4 50.00% +// REPORTFILE-NEXT: branch-templates.cpp 12 2 83.33% 2 0 100.00% 17 3 82.35% 12 6 50.00% // REPORTFILE-NEXT: --- -// REPORTFILE-NEXT: TOTAL 12 3 75.00% 2 0 100.00% 17 4 76.47% 8 4 50.00% +// REPORTFILE-NEXT: TOTAL 12 2 83.33% 2 0 100.00% 17 3 82.35% 12 6 50.00% diff --git a/llvm/test/tools/llvm-cov/coverage_watermark.test b/llvm/test/tools/llvm-cov/coverage_watermark.test index 5c48b4f0fb4bf..818baa470bc38 100644 --- a/llvm/test/tools/llvm-cov/coverage_watermark.test +++ b/llvm/test/tools/llvm-cov/coverage_watermark.test @@ -18,15 +18,15 @@ ORIGIN: ORIGIN: 100.00% (2/2) ORIGIN: ORIGIN: 100.00% (3/3) -ORIGIN: -ORIGIN: 75.00% (9/12) -ORIGIN: -ORIGIN: 66.67% (4/6) +ORIGIN: +ORIGIN: 83.33% (10/12) +ORIGIN: +ORIGIN: 83.33% (5/6) ORIGIN: ORIGIN: - (0/0) ORIGIN:
DOWNGRADE1: 100.00% (3/3) DOWNGRADE1: -DOWNGRADE1: 75.00% (9/12) -DOWNGRADE1: -DOWNGRADE1: 66.67% (4/6) +DOWNGRADE1: 83.33% (10/12) +DOWNGRADE1: +DOWNGRADE1: 83.33% (5/6) DOWNGRADE1: DOWNGRADE1: - (0/0) DOWNGRADE1:
DOWNGRADE2: 100.00% (3/3) DOWNGRADE2: -DOWNGRADE2: 75.00% (9/12) -DOWNGRADE2: -DOWNGRADE2: 66.67% (4/6) +DOWNGRADE2: 83.33% (10/12) +DOWNGRADE2: +DOWNGRADE2: 83.33% (5/6) DOWNGRADE1: DOWNGRADE1: - (0/0) DOWNGRADE1: