From 178b57cbbcb2b21b7d13f90ffd75903417913438 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 2 Oct 2024 23:11:36 +0900 Subject: [PATCH 01/79] [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/79] [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/79] 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 618e63946923a460b2684738e636c77b1706322a Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 17 Oct 2024 01:22:54 +0900 Subject: [PATCH 04/79] Introduce CounterExpressionBuilder::replace(C, Map) This return a counter for each term in the expression replaced by ReplaceMap. At the moment, this doesn't update the Map, so Map is marked as `const`. --- .../ProfileData/Coverage/CoverageMapping.h | 6 ++++ .../ProfileData/Coverage/CoverageMapping.cpp | 32 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index fa07b3a9e8b14..d6528bd407ef3 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -213,6 +214,11 @@ class CounterExpressionBuilder { /// Return a counter that represents the expression that subtracts RHS from /// LHS. Counter subtract(Counter LHS, Counter RHS, bool Simplify = true); + + using ReplaceMap = std::map; + + /// Return a counter for each term in the expression replaced by ReplaceMap. + Counter replace(Counter C, const ReplaceMap &Map); }; using LineColPair = std::pair; diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index c713371da81e4..b50f025d261e1 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -135,6 +135,38 @@ Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS, return Simplify ? simplify(Cnt) : Cnt; } +Counter CounterExpressionBuilder::replace(Counter C, const ReplaceMap &Map) { + auto I = Map.find(C); + + // Replace C with the Map even if C is Expression. + if (I != Map.end()) + return I->second; + + // Traverse only Expression. + if (!C.isExpression()) + return C; + + auto CE = Expressions[C.getExpressionID()]; + auto NewLHS = replace(CE.LHS, Map); + auto NewRHS = replace(CE.RHS, Map); + + // Reconstruct Expression with induced subexpressions. + switch (CE.Kind) { + case CounterExpression::Add: + C = add(NewLHS, NewRHS); + break; + case CounterExpression::Subtract: + C = subtract(NewLHS, NewRHS); + break; + } + + // Reconfirm if the reconstructed expression would hit the Map. + if ((I = Map.find(C)) != Map.end()) + return I->second; + + return C; +} + void CounterMappingContext::dump(const Counter &C, raw_ostream &OS) const { switch (C.getKind()) { case Counter::Zero: From fc697f04fd6c9f3c217ce04e3f1dd082c1f1a705 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 16 Oct 2024 23:16:53 +0900 Subject: [PATCH 05/79] [Coverage] Introduce `getBranchCounterPair()`. NFC. This aggregates the generation of branch counter pair as `ExecCnt` and `SkipCnt`, to aggregate `CounterExpr::subtract`. At the moment: - This change preserves the behavior of `llvm::EnableSingleByteCoverage`. Almost of SingleByteCoverage will be cleaned up by coming commits. - `getBranchCounterPair()` is not called in `llvm::EnableSingleByteCoverage`. I will implement the new behavior of SingleByteCoverage in it. - `IsCounterEqual(Out, Par)` is introduced instead of `Counter::operator==`. Tweaks would be required for the comparison for additional counters. - Braces around `assert()` is intentional. I will add a statement there. https://discourse.llvm.org/t/rfc-integrating-singlebytecoverage-with-branch-coverage/82492 --- clang/lib/CodeGen/CoverageMappingGen.cpp | 177 +++++++++++++---------- 1 file changed, 102 insertions(+), 75 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 07015834bc84f..0bfad9cbcbe12 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -941,6 +941,19 @@ struct CounterCoverageMappingBuilder return Counter::getCounter(CounterMap[S]); } + std::pair getBranchCounterPair(const Stmt *S, + Counter ParentCnt) { + Counter ExecCnt = getRegionCounter(S); + return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; + } + + bool IsCounterEqual(Counter OutCount, Counter ParentCount) { + if (OutCount == ParentCount) + return true; + + return false; + } + /// Push a region onto the stack. /// /// Returns the index on the stack where the region was pushed. This can be @@ -1592,6 +1605,13 @@ struct CounterCoverageMappingBuilder llvm::EnableSingleByteCoverage ? getRegionCounter(S->getCond()) : addCounters(ParentCount, BackedgeCount, BC.ContinueCount); + auto [ExecCount, ExitCount] = + (llvm::EnableSingleByteCoverage + ? std::make_pair(getRegionCounter(S), Counter::getZero()) + : getBranchCounterPair(S, CondCount)); + if (!llvm::EnableSingleByteCoverage) { + assert(ExecCount.isZero() || ExecCount == BodyCount); + } propagateCounts(CondCount, S->getCond()); adjustForOutOfOrderTraversal(getEnd(S)); @@ -1600,13 +1620,11 @@ struct CounterCoverageMappingBuilder if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); - Counter OutCount = - llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BC.BreakCount, - subtractCounters(CondCount, BodyCount)); + Counter OutCount = llvm::EnableSingleByteCoverage + ? getRegionCounter(S) + : addCounters(BC.BreakCount, ExitCount); - if (OutCount != ParentCount) { + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; if (BodyHasTerminateStmt) @@ -1615,8 +1633,7 @@ struct CounterCoverageMappingBuilder // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, - subtractCounters(CondCount, BodyCount)); + createBranchRegion(S->getCond(), BodyCount, ExitCount); } void VisitDoStmt(const DoStmt *S) { @@ -1645,22 +1662,26 @@ struct CounterCoverageMappingBuilder Counter CondCount = llvm::EnableSingleByteCoverage ? getRegionCounter(S->getCond()) : addCounters(BackedgeCount, BC.ContinueCount); + auto [ExecCount, ExitCount] = + (llvm::EnableSingleByteCoverage + ? std::make_pair(getRegionCounter(S), Counter::getZero()) + : getBranchCounterPair(S, CondCount)); + if (!llvm::EnableSingleByteCoverage) { + assert(ExecCount.isZero() || ExecCount == BodyCount); + } propagateCounts(CondCount, S->getCond()); - Counter OutCount = - llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BC.BreakCount, - subtractCounters(CondCount, BodyCount)); - if (OutCount != ParentCount) { + Counter OutCount = llvm::EnableSingleByteCoverage + ? getRegionCounter(S) + : addCounters(BC.BreakCount, ExitCount); + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; } // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, - subtractCounters(CondCount, BodyCount)); + createBranchRegion(S->getCond(), BodyCount, ExitCount); if (BodyHasTerminateStmt) HasTerminateStmt = true; @@ -1709,6 +1730,13 @@ struct CounterCoverageMappingBuilder : addCounters( addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount), IncrementBC.ContinueCount); + auto [ExecCount, ExitCount] = + (llvm::EnableSingleByteCoverage + ? std::make_pair(getRegionCounter(S), Counter::getZero()) + : getBranchCounterPair(S, CondCount)); + if (!llvm::EnableSingleByteCoverage) { + assert(ExecCount.isZero() || ExecCount == BodyCount); + } if (const Expr *Cond = S->getCond()) { propagateCounts(CondCount, Cond); @@ -1723,9 +1751,8 @@ struct CounterCoverageMappingBuilder Counter OutCount = llvm::EnableSingleByteCoverage ? getRegionCounter(S) - : addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, - subtractCounters(CondCount, BodyCount)); - if (OutCount != ParentCount) { + : addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, ExitCount); + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; if (BodyHasTerminateStmt) @@ -1734,8 +1761,7 @@ struct CounterCoverageMappingBuilder // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, - subtractCounters(CondCount, BodyCount)); + createBranchRegion(S->getCond(), BodyCount, ExitCount); } void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { @@ -1764,15 +1790,21 @@ struct CounterCoverageMappingBuilder fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); Counter OutCount; + Counter ExitCount; Counter LoopCount; if (llvm::EnableSingleByteCoverage) OutCount = getRegionCounter(S); else { - LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - OutCount = - addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount)); + LoopCount = + (ParentCount.isZero() + ? ParentCount + : addCounters(ParentCount, BackedgeCount, BC.ContinueCount)); + auto [ExecCount, SkipCount] = getBranchCounterPair(S, LoopCount); + ExitCount = SkipCount; + assert(ExecCount.isZero() || ExecCount == BodyCount); + OutCount = addCounters(BC.BreakCount, ExitCount); } - if (OutCount != ParentCount) { + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; if (BodyHasTerminateStmt) @@ -1781,8 +1813,7 @@ struct CounterCoverageMappingBuilder // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, - subtractCounters(LoopCount, BodyCount)); + createBranchRegion(S->getCond(), BodyCount, ExitCount); } void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { @@ -1803,10 +1834,13 @@ struct CounterCoverageMappingBuilder fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); Counter LoopCount = - addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - Counter OutCount = - addCounters(BC.BreakCount, subtractCounters(LoopCount, BodyCount)); - if (OutCount != ParentCount) { + (ParentCount.isZero() + ? ParentCount + : addCounters(ParentCount, BackedgeCount, BC.ContinueCount)); + auto [ExecCount, ExitCount] = getBranchCounterPair(S, LoopCount); + assert(ExecCount.isZero() || ExecCount == BodyCount); + Counter OutCount = addCounters(BC.BreakCount, ExitCount); + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; } @@ -2016,9 +2050,12 @@ struct CounterCoverageMappingBuilder extendRegion(S->getCond()); Counter ParentCount = getRegion().getCounter(); - Counter ThenCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S->getThen()) - : getRegionCounter(S); + auto [ThenCount, ElseCount] = + (llvm::EnableSingleByteCoverage + ? std::make_pair(getRegionCounter(S->getThen()), + (S->getElse() ? getRegionCounter(S->getElse()) + : Counter::getZero())) + : getBranchCounterPair(S, ParentCount)); // Emitting a counter for the condition makes it easier to interpret the // counter for the body when looking at the coverage. @@ -2033,12 +2070,6 @@ struct CounterCoverageMappingBuilder extendRegion(S->getThen()); Counter OutCount = propagateCounts(ThenCount, S->getThen()); - Counter ElseCount; - if (!llvm::EnableSingleByteCoverage) - ElseCount = subtractCounters(ParentCount, ThenCount); - else if (S->getElse()) - ElseCount = getRegionCounter(S->getElse()); - if (const Stmt *Else = S->getElse()) { bool ThenHasTerminateStmt = HasTerminateStmt; HasTerminateStmt = false; @@ -2061,15 +2092,14 @@ struct CounterCoverageMappingBuilder if (llvm::EnableSingleByteCoverage) OutCount = getRegionCounter(S); - if (OutCount != ParentCount) { + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; } if (!S->isConsteval() && !llvm::EnableSingleByteCoverage) // Create Branch Region around condition. - createBranchRegion(S->getCond(), ThenCount, - subtractCounters(ParentCount, ThenCount)); + createBranchRegion(S->getCond(), ThenCount, ElseCount); } void VisitCXXTryStmt(const CXXTryStmt *S) { @@ -2095,9 +2125,11 @@ struct CounterCoverageMappingBuilder extendRegion(E); Counter ParentCount = getRegion().getCounter(); - Counter TrueCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(E->getTrueExpr()) - : getRegionCounter(E); + auto [TrueCount, FalseCount] = + (llvm::EnableSingleByteCoverage + ? std::make_pair(getRegionCounter(E->getTrueExpr()), + getRegionCounter(E->getFalseExpr())) + : getBranchCounterPair(E, ParentCount)); Counter OutCount; if (const auto *BCO = dyn_cast(E)) { @@ -2116,25 +2148,20 @@ struct CounterCoverageMappingBuilder } extendRegion(E->getFalseExpr()); - Counter FalseCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(E->getFalseExpr()) - : subtractCounters(ParentCount, TrueCount); - Counter FalseOutCount = propagateCounts(FalseCount, E->getFalseExpr()); if (llvm::EnableSingleByteCoverage) OutCount = getRegionCounter(E); else OutCount = addCounters(OutCount, FalseOutCount); - if (OutCount != ParentCount) { + if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; } // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getCond(), TrueCount, - subtractCounters(ParentCount, TrueCount)); + createBranchRegion(E->getCond(), TrueCount, FalseCount); } void createOrCancelDecision(const BinaryOperator *E, unsigned Since) { @@ -2233,27 +2260,27 @@ struct CounterCoverageMappingBuilder extendRegion(E->getRHS()); propagateCounts(getRegionCounter(E), E->getRHS()); + if (llvm::EnableSingleByteCoverage) + return; + // Track RHS True/False Decision. const auto DecisionRHS = MCDCBuilder.back(); + // Extract the Parent Region Counter. + Counter ParentCnt = getRegion().getCounter(); + // Extract the RHS's Execution Counter. - Counter RHSExecCnt = getRegionCounter(E); + auto [RHSExecCnt, LHSExitCnt] = getBranchCounterPair(E, ParentCnt); // Extract the RHS's "True" Instance Counter. - Counter RHSTrueCnt = getRegionCounter(E->getRHS()); - - // Extract the Parent Region Counter. - Counter ParentCnt = getRegion().getCounter(); + auto [RHSTrueCnt, RHSExitCnt] = + getBranchCounterPair(E->getRHS(), RHSExecCnt); // Create Branch Region around LHS condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getLHS(), RHSExecCnt, - subtractCounters(ParentCnt, RHSExecCnt), DecisionLHS); + createBranchRegion(E->getLHS(), RHSExecCnt, LHSExitCnt, DecisionLHS); // Create Branch Region around RHS condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getRHS(), RHSTrueCnt, - subtractCounters(RHSExecCnt, RHSTrueCnt), DecisionRHS); + createBranchRegion(E->getRHS(), RHSTrueCnt, RHSExitCnt, DecisionRHS); // Create MCDC Decision Region if at top-level (root). if (IsRootNode) @@ -2294,31 +2321,31 @@ struct CounterCoverageMappingBuilder extendRegion(E->getRHS()); propagateCounts(getRegionCounter(E), E->getRHS()); + if (llvm::EnableSingleByteCoverage) + return; + // Track RHS True/False Decision. const auto DecisionRHS = MCDCBuilder.back(); + // Extract the Parent Region Counter. + Counter ParentCnt = getRegion().getCounter(); + // Extract the RHS's Execution Counter. - Counter RHSExecCnt = getRegionCounter(E); + auto [RHSExecCnt, LHSExitCnt] = getBranchCounterPair(E, ParentCnt); // Extract the RHS's "False" Instance Counter. - Counter RHSFalseCnt = getRegionCounter(E->getRHS()); + auto [RHSFalseCnt, RHSExitCnt] = + getBranchCounterPair(E->getRHS(), RHSExecCnt); if (!shouldVisitRHS(E->getLHS())) { GapRegionCounter = OutCount; } - // Extract the Parent Region Counter. - Counter ParentCnt = getRegion().getCounter(); - // Create Branch Region around LHS condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getLHS(), subtractCounters(ParentCnt, RHSExecCnt), - RHSExecCnt, DecisionLHS); + createBranchRegion(E->getLHS(), LHSExitCnt, RHSExecCnt, DecisionLHS); // Create Branch Region around RHS condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getRHS(), subtractCounters(RHSExecCnt, RHSFalseCnt), - RHSFalseCnt, DecisionRHS); + createBranchRegion(E->getRHS(), RHSExitCnt, RHSFalseCnt, DecisionRHS); // Create MCDC Decision Region if at top-level (root). if (IsRootNode) From e4172ca273a6fdfcbfc4662c9e37276ef34c2df4 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 17 Oct 2024 00:32:26 +0900 Subject: [PATCH 06/79] Introduce the type `CounterPair` for RegionCounterMap `CounterPair` can hold `` instead of current `unsigned`, to hold also the counter number of SkipPath. For now, this change provides the skeleton and only `CounterPair::first` is used. Each counter number can have `None` to suppress emitting counter increment. `second` is initialized as `None` by default, since most `Stmt*` don't have a pair of counters. This change also provides stubs for the verifyer. I'll provide the impl of verifier for `+Asserts` later. `markStmtAsUsed(bool, Stmt*)` may be used to inform that other side counter may not emitted. `markStmtMaybeUsed(S)` may be used for the `Stmt` and its inner will be excluded for emission in the case of skipping by constant folding. I put it into places where I found. `verifyCounterMap()` will check the coverage map the counter map and can be used to report inconsistency. These verifier methods shall be eliminated in `-Asserts`. https://discourse.llvm.org/t/rfc-integrating-singlebytecoverage-with-branch-coverage/82492 --- clang/lib/CodeGen/CGDecl.cpp | 9 ++++++++- clang/lib/CodeGen/CGExpr.cpp | 1 + clang/lib/CodeGen/CGExprScalar.cpp | 9 +++++++-- clang/lib/CodeGen/CGStmt.cpp | 3 +++ clang/lib/CodeGen/CodeGenFunction.cpp | 3 +++ clang/lib/CodeGen/CodeGenFunction.h | 6 ++++++ clang/lib/CodeGen/CodeGenModule.h | 19 +++++++++++++++++++ clang/lib/CodeGen/CodeGenPGO.cpp | 14 ++++++++++---- clang/lib/CodeGen/CodeGenPGO.h | 17 +++++++++++++++-- clang/lib/CodeGen/CoverageMappingGen.cpp | 6 +++--- clang/lib/CodeGen/CoverageMappingGen.h | 5 +++-- 11 files changed, 78 insertions(+), 14 deletions(-) diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 563f728e29d78..ed5f41b624b62 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -362,6 +362,8 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D, return GV; } + PGO.markStmtMaybeUsed(D.getInit()); // FIXME: Too lazy + #ifndef NDEBUG CharUnits VarSize = CGM.getContext().getTypeSizeInChars(D.getType()) + D.getFlexibleArrayInitChars(getContext()); @@ -1869,7 +1871,10 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { // If we are at an unreachable point, we don't need to emit the initializer // unless it contains a label. if (!HaveInsertPoint()) { - if (!Init || !ContainsLabel(Init)) return; + if (!Init || !ContainsLabel(Init)) { + PGO.markStmtMaybeUsed(Init); + return; + } EnsureInsertPoint(); } @@ -1978,6 +1983,8 @@ void CodeGenFunction::EmitAutoVarInit(const AutoVarEmission &emission) { return EmitExprAsInit(Init, &D, lv, capturedByInit); } + PGO.markStmtMaybeUsed(Init); + if (!emission.IsConstantAggregate) { // For simple scalar/complex initialization, store the value directly. LValue lv = MakeAddrLValue(Loc, type); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 52d2f6d52abf9..2fd6b02a3395e 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -5134,6 +5134,7 @@ std::optional HandleConditionalOperatorLValueSimpleCase( // If the true case is live, we need to track its region. if (CondExprBool) CGF.incrementProfileCounter(E); + CGF.markStmtMaybeUsed(Dead); // If a throw expression we emit it and return an undefined lvalue // because it can't be used. if (auto *ThrowExpr = dyn_cast(Live->IgnoreParens())) { diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index b7f5b932c56b6..74e93f889f426 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -4982,8 +4982,10 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { } // 0 && RHS: If it is safe, just elide the RHS, and return 0/false. - if (!CGF.ContainsLabel(E->getRHS())) + if (!CGF.ContainsLabel(E->getRHS())) { + CGF.markStmtMaybeUsed(E->getRHS()); return llvm::Constant::getNullValue(ResTy); + } } // If the top of the logical operator nest, reset the MCDC temp to 0. @@ -5122,8 +5124,10 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { } // 1 || RHS: If it is safe, just elide the RHS, and return 1/true. - if (!CGF.ContainsLabel(E->getRHS())) + if (!CGF.ContainsLabel(E->getRHS())) { + CGF.markStmtMaybeUsed(E->getRHS()); return llvm::ConstantInt::get(ResTy, 1); + } } // If the top of the logical operator nest, reset the MCDC temp to 0. @@ -5247,6 +5251,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { CGF.incrementProfileCounter(E); } Value *Result = Visit(live); + CGF.markStmtMaybeUsed(dead); // If the live part is a throw expression, it acts like it has a void // type, so evaluating it returns a null Value*. However, a conditional diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 41dc91c578c80..dbc1ce9bf993c 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -76,6 +76,7 @@ void CodeGenFunction::EmitStmt(const Stmt *S, ArrayRef Attrs) { // Verify that any decl statements were handled as simple, they may be in // scope of subsequent reachable statements. assert(!isa(*S) && "Unexpected DeclStmt!"); + PGO.markStmtMaybeUsed(S); return; } @@ -845,6 +846,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { RunCleanupsScope ExecutedScope(*this); EmitStmt(Executed); } + PGO.markStmtMaybeUsed(Skipped); return; } } @@ -2170,6 +2172,7 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { for (unsigned i = 0, e = CaseStmts.size(); i != e; ++i) EmitStmt(CaseStmts[i]); incrementProfileCounter(&S); + PGO.markStmtMaybeUsed(S.getBody()); // Now we want to restore the saved switch instance so that nested // switches continue to function properly diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 24723e392c2a3..371aa494e014b 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1606,6 +1606,8 @@ void CodeGenFunction::GenerateCode(GlobalDecl GD, llvm::Function *Fn, // Emit the standard function epilogue. FinishFunction(BodyRange.getEnd()); + PGO.verifyCounterMap(); + // If we haven't marked the function nothrow through other means, do // a quick pass now to see if we can. if (!CurFn->doesNotThrow()) @@ -1728,6 +1730,7 @@ bool CodeGenFunction::ConstantFoldsToSimpleInteger(const Expr *Cond, if (!AllowLabels && CodeGenFunction::ContainsLabel(Cond)) return false; // Contains a label. + PGO.markStmtMaybeUsed(Cond); ResultInt = Int; return true; } diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 9ba0ed02a564d..89ac3b342d0a7 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1620,6 +1620,12 @@ class CodeGenFunction : public CodeGenTypeCache { uint64_t LoopCount) const; public: + std::pair getIsCounterPair(const Stmt *S) const { + return PGO.getIsCounterPair(S); + } + + void markStmtMaybeUsed(const Stmt *S) { PGO.markStmtMaybeUsed(S); } + /// Increment the profiler's counter for the given statement by \p StepV. /// If \p StepV is null, the default increment is 1. void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) { diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index c58bb88035ca8..9dc497321b42a 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -101,6 +101,25 @@ enum ForDefinition_t : bool { ForDefinition = true }; +class CounterPair : public std::pair { +private: + static constexpr uint32_t None = (1u << 31); /// None is set + +public: + static constexpr uint32_t Mask = None - 1; + +public: + CounterPair(unsigned Val = 0) { + assert(!(Val & ~Mask)); + first = Val; + second = None; + } + + std::pair getIsCounterPair() const { + return {!(first & None), !(second & None)}; + } +}; + struct OrderGlobalInitsOrStermFinalizers { unsigned int priority; unsigned int lex_order; diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 820bb521ccf85..069469e3de856 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -164,7 +164,7 @@ struct MapRegionCounters : public RecursiveASTVisitor { /// The function hash. PGOHash Hash; /// The map of statements to counters. - llvm::DenseMap &CounterMap; + llvm::DenseMap &CounterMap; /// The state of MC/DC Coverage in this function. MCDC::State &MCDCState; /// Maximum number of supported MC/DC conditions in a boolean expression. @@ -175,7 +175,7 @@ struct MapRegionCounters : public RecursiveASTVisitor { DiagnosticsEngine &Diag; MapRegionCounters(PGOHashVersion HashVersion, uint64_t ProfileVersion, - llvm::DenseMap &CounterMap, + llvm::DenseMap &CounterMap, MCDC::State &MCDCState, unsigned MCDCMaxCond, DiagnosticsEngine &Diag) : NextCounter(0), Hash(HashVersion), CounterMap(CounterMap), @@ -1084,7 +1084,7 @@ void CodeGenPGO::mapRegionCounters(const Decl *D) { (CGM.getCodeGenOpts().MCDCCoverage ? CGM.getCodeGenOpts().MCDCMaxConds : 0); - RegionCounterMap.reset(new llvm::DenseMap); + RegionCounterMap.reset(new llvm::DenseMap); RegionMCDCState.reset(new MCDC::State); MapRegionCounters Walker(HashVersion, ProfileVersion, *RegionCounterMap, *RegionMCDCState, MCDCMaxConditions, CGM.getDiags()); @@ -1186,12 +1186,18 @@ CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader, Fn->setEntryCount(FunctionCount); } +std::pair CodeGenPGO::getIsCounterPair(const Stmt *S) const { + if (!RegionCounterMap || RegionCounterMap->count(S) == 0) + return {false, false}; + return (*RegionCounterMap)[S].getIsCounterPair(); +} + void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, llvm::Value *StepV) { if (!RegionCounterMap || !Builder.GetInsertBlock()) return; - unsigned Counter = (*RegionCounterMap)[S]; + unsigned Counter = (*RegionCounterMap)[S].first; // Make sure that pointer to global is passed in with zero addrspace // This is relevant during GPU profiling diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h index 9d66ffad6f435..83f35785e5327 100644 --- a/clang/lib/CodeGen/CodeGenPGO.h +++ b/clang/lib/CodeGen/CodeGenPGO.h @@ -35,7 +35,7 @@ class CodeGenPGO { std::array NumValueSites; unsigned NumRegionCounters; uint64_t FunctionHash; - std::unique_ptr> RegionCounterMap; + std::unique_ptr> RegionCounterMap; std::unique_ptr> StmtCountMap; std::unique_ptr ProfRecord; std::unique_ptr RegionMCDCState; @@ -110,6 +110,7 @@ class CodeGenPGO { bool canEmitMCDCCoverage(const CGBuilderTy &Builder); public: + std::pair getIsCounterPair(const Stmt *S) const; void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, llvm::Value *StepV); void emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S, @@ -122,6 +123,18 @@ class CodeGenPGO { Address MCDCCondBitmapAddr, llvm::Value *Val, CodeGenFunction &CGF); + void markStmtAsUsed(bool Skipped, const Stmt *S) { + // Do nothing. + } + + void markStmtMaybeUsed(const Stmt *S) { + // Do nothing. + } + + void verifyCounterMap() { + // Do nothing. + } + /// Return the region count for the counter at the given index. uint64_t getRegionCount(const Stmt *S) { if (!RegionCounterMap) @@ -130,7 +143,7 @@ class CodeGenPGO { return 0; // With profiles from a differing version of clang we can have mismatched // decl counts. Don't crash in such a case. - auto Index = (*RegionCounterMap)[S]; + auto Index = (*RegionCounterMap)[S].first; if (Index >= RegionCounts.size()) return 0; return RegionCounts[Index]; diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 07015834bc84f..08e4ac80e0e87 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -885,7 +885,7 @@ struct CounterCoverageMappingBuilder : public CoverageMappingBuilder, public ConstStmtVisitor { /// The map of statements to count values. - llvm::DenseMap &CounterMap; + llvm::DenseMap &CounterMap; MCDC::State &MCDCState; @@ -938,7 +938,7 @@ struct CounterCoverageMappingBuilder /// /// This should only be called on statements that have a dedicated counter. Counter getRegionCounter(const Stmt *S) { - return Counter::getCounter(CounterMap[S]); + return Counter::getCounter(CounterMap[S].first); } /// Push a region onto the stack. @@ -1421,7 +1421,7 @@ struct CounterCoverageMappingBuilder CounterCoverageMappingBuilder( CoverageMappingModuleGen &CVM, - llvm::DenseMap &CounterMap, + llvm::DenseMap &CounterMap, MCDC::State &MCDCState, SourceManager &SM, const LangOptions &LangOpts) : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap), MCDCState(MCDCState), MCDCBuilder(CVM.getCodeGenModule(), MCDCState) {} diff --git a/clang/lib/CodeGen/CoverageMappingGen.h b/clang/lib/CodeGen/CoverageMappingGen.h index fe4b93f3af856..0ed50597e1dc3 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.h +++ b/clang/lib/CodeGen/CoverageMappingGen.h @@ -95,6 +95,7 @@ class CoverageSourceInfo : public PPCallbacks, namespace CodeGen { class CodeGenModule; +class CounterPair; namespace MCDC { struct State; @@ -158,7 +159,7 @@ class CoverageMappingGen { CoverageMappingModuleGen &CVM; SourceManager &SM; const LangOptions &LangOpts; - llvm::DenseMap *CounterMap; + llvm::DenseMap *CounterMap; MCDC::State *MCDCState; public: @@ -169,7 +170,7 @@ class CoverageMappingGen { CoverageMappingGen(CoverageMappingModuleGen &CVM, SourceManager &SM, const LangOptions &LangOpts, - llvm::DenseMap *CounterMap, + llvm::DenseMap *CounterMap, MCDC::State *MCDCState) : CVM(CVM), SM(SM), LangOpts(LangOpts), CounterMap(CounterMap), MCDCState(MCDCState) {} From 5e460594c8a2550c38c759b2e6f1c5dc4152f820 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 17 Oct 2024 22:15:12 +0900 Subject: [PATCH 07/79] [Coverage] Make additional counters available for BranchRegion. NFC. `getBranchCounterPair()` allocates an additional Counter to SkipPath in `SingleByteCoverage`. `IsCounterEqual()` calculates the comparison with rewinding counter replacements. `NumRegionCounters` is updated to take additional counters in account. `incrementProfileCounter()` has a few additiona arguments. - `UseSkipPath=true`, to specify setting counters for SkipPath. It assumes `UseSkipPath=false` is used together. - `UseBoth` may be specified for marking another path. It introduces the same effect as issueing `markStmtAsUsed(!SkipPath, S)`. `llvm-cov` discovers counters in `FalseCount` to allocate `MaxCounterID` for empty profile data. --- clang/lib/CodeGen/CodeGenFunction.h | 8 ++++- clang/lib/CodeGen/CodeGenPGO.cpp | 31 +++++++++++++++++-- clang/lib/CodeGen/CodeGenPGO.h | 1 + clang/lib/CodeGen/CoverageMappingGen.cpp | 31 ++++++++++++++----- .../ProfileData/Coverage/CoverageMapping.cpp | 4 +++ 5 files changed, 65 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 89ac3b342d0a7..cb1192bf6e11f 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1629,11 +1629,17 @@ class CodeGenFunction : public CodeGenTypeCache { /// Increment the profiler's counter for the given statement by \p StepV. /// If \p StepV is null, the default increment is 1. void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) { + incrementProfileCounter(false, S, false, StepV); + } + + void incrementProfileCounter(bool UseSkipPath, const Stmt *S, + bool UseBoth = false, + llvm::Value *StepV = nullptr) { if (CGM.getCodeGenOpts().hasProfileClangInstr() && !CurFn->hasFnAttribute(llvm::Attribute::NoProfile) && !CurFn->hasFnAttribute(llvm::Attribute::SkipProfile)) { auto AL = ApplyDebugLocation::CreateArtificial(*this); - PGO.emitCounterSetOrIncrement(Builder, S, StepV); + PGO.emitCounterSetOrIncrement(Builder, S, UseSkipPath, UseBoth, StepV); } PGO.setCurrentStmt(S); } diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 069469e3de856..aefd53e12088b 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -1138,6 +1138,19 @@ void CodeGenPGO::emitCounterRegionMapping(const Decl *D) { if (CoverageMapping.empty()) return; + // Scan max(FalseCnt) and update NumRegionCounters. + unsigned MaxNumCounters = NumRegionCounters; + for (const auto [_, V] : *RegionCounterMap) { + auto HasCounters = V.getIsCounterPair(); + assert((!HasCounters.first || + MaxNumCounters > (V.first & CounterPair::Mask)) && + "TrueCnt should not be reassigned"); + if (HasCounters.second) + MaxNumCounters = + std::max(MaxNumCounters, (V.second & CounterPair::Mask) + 1); + } + NumRegionCounters = MaxNumCounters; + CGM.getCoverageMapping()->addFunctionMappingRecord( FuncNameVar, FuncName, FunctionHash, CoverageMapping); } @@ -1193,11 +1206,25 @@ std::pair CodeGenPGO::getIsCounterPair(const Stmt *S) const { } void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, + bool UseSkipPath, bool UseBoth, llvm::Value *StepV) { - if (!RegionCounterMap || !Builder.GetInsertBlock()) + if (!RegionCounterMap) return; - unsigned Counter = (*RegionCounterMap)[S].first; + unsigned Counter; + auto &TheMap = (*RegionCounterMap)[S]; + auto IsCounter = TheMap.getIsCounterPair(); + if (!UseSkipPath) { + assert(IsCounter.first); + Counter = (TheMap.first & CounterPair::Mask); + } else { + if (!IsCounter.second) + return; + Counter = (TheMap.second & CounterPair::Mask); + } + + if (!Builder.GetInsertBlock()) + return; // Make sure that pointer to global is passed in with zero addrspace // This is relevant during GPU profiling diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h index 83f35785e5327..8b769dd88d7f1 100644 --- a/clang/lib/CodeGen/CodeGenPGO.h +++ b/clang/lib/CodeGen/CodeGenPGO.h @@ -112,6 +112,7 @@ class CodeGenPGO { public: std::pair getIsCounterPair(const Stmt *S) const; void emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, + bool UseFalsePath, bool UseBoth, llvm::Value *StepV); void emitMCDCTestVectorBitmapUpdate(CGBuilderTy &Builder, const Expr *S, Address MCDCCondBitmapAddr, diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index a5d83e7a743bb..0bcbd20593ae2 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -887,6 +887,9 @@ struct CounterCoverageMappingBuilder /// The map of statements to count values. llvm::DenseMap &CounterMap; + CounterExpressionBuilder::ReplaceMap MapToExpand; + unsigned NextCounterNum; + MCDC::State &MCDCState; /// A stack of currently live regions. @@ -922,15 +925,11 @@ struct CounterCoverageMappingBuilder /// Return a counter for the sum of \c LHS and \c RHS. Counter addCounters(Counter LHS, Counter RHS, bool Simplify = true) { - assert(!llvm::EnableSingleByteCoverage && - "cannot add counters when single byte coverage mode is enabled"); return Builder.add(LHS, RHS, Simplify); } Counter addCounters(Counter C1, Counter C2, Counter C3, bool Simplify = true) { - assert(!llvm::EnableSingleByteCoverage && - "cannot add counters when single byte coverage mode is enabled"); return addCounters(addCounters(C1, C2, Simplify), C3, Simplify); } @@ -943,14 +942,31 @@ struct CounterCoverageMappingBuilder std::pair getBranchCounterPair(const Stmt *S, Counter ParentCnt) { - Counter ExecCnt = getRegionCounter(S); - return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; + auto &TheMap = CounterMap[S]; + auto ExecCnt = Counter::getCounter(TheMap.first); + auto SkipExpr = Builder.subtract(ParentCnt, ExecCnt); + + if (!llvm::EnableSingleByteCoverage) + return {ExecCnt, SkipExpr}; + + // Assign second if second is not assigned yet. + if (!TheMap.getIsCounterPair().second) + TheMap.second = NextCounterNum++; + + Counter SkipCnt = Counter::getCounter(TheMap.second); + MapToExpand[SkipCnt] = SkipExpr; + return {ExecCnt, SkipCnt}; } bool IsCounterEqual(Counter OutCount, Counter ParentCount) { if (OutCount == ParentCount) return true; + // Try comaparison with pre-replaced expressions. + if (Builder.replace(Builder.subtract(OutCount, ParentCount), MapToExpand) + .isZero()) + return true; + return false; } @@ -1437,7 +1453,8 @@ struct CounterCoverageMappingBuilder llvm::DenseMap &CounterMap, MCDC::State &MCDCState, SourceManager &SM, const LangOptions &LangOpts) : CoverageMappingBuilder(CVM, SM, LangOpts), CounterMap(CounterMap), - MCDCState(MCDCState), MCDCBuilder(CVM.getCodeGenModule(), MCDCState) {} + NextCounterNum(CounterMap.size()), MCDCState(MCDCState), + MCDCBuilder(CVM.getCodeGenModule(), MCDCState) {} /// Write the mapping data to the output stream void write(llvm::raw_ostream &OS) { diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index b50f025d261e1..fc7f36c8599f5 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -640,6 +640,10 @@ static unsigned getMaxCounterID(const CounterMappingContext &Ctx, unsigned MaxCounterID = 0; for (const auto &Region : Record.MappingRegions) { MaxCounterID = std::max(MaxCounterID, Ctx.getMaxCounterID(Region.Count)); + if (Region.Kind == CounterMappingRegion::BranchRegion || + Region.Kind == CounterMappingRegion::MCDCBranchRegion) + MaxCounterID = + std::max(MaxCounterID, Ctx.getMaxCounterID(Region.FalseCount)); } return MaxCounterID; } From ad136910aad1c8e53a8c6091999ad2f90d180761 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 18 Oct 2024 09:37:18 +0900 Subject: [PATCH 08/79] Rewind changes for folding --- clang/lib/CodeGen/CoverageMappingGen.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 0bfad9cbcbe12..8bd9ab402f4e5 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1795,10 +1795,7 @@ struct CounterCoverageMappingBuilder if (llvm::EnableSingleByteCoverage) OutCount = getRegionCounter(S); else { - LoopCount = - (ParentCount.isZero() - ? ParentCount - : addCounters(ParentCount, BackedgeCount, BC.ContinueCount)); + LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount); auto [ExecCount, SkipCount] = getBranchCounterPair(S, LoopCount); ExitCount = SkipCount; assert(ExecCount.isZero() || ExecCount == BodyCount); @@ -1834,9 +1831,7 @@ struct CounterCoverageMappingBuilder fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); Counter LoopCount = - (ParentCount.isZero() - ? ParentCount - : addCounters(ParentCount, BackedgeCount, BC.ContinueCount)); + addCounters(ParentCount, BackedgeCount, BC.ContinueCount); auto [ExecCount, ExitCount] = getBranchCounterPair(S, LoopCount); assert(ExecCount.isZero() || ExecCount == BodyCount); Counter OutCount = addCounters(BC.BreakCount, ExitCount); From 209ea4cfdb4f93d3c8fc60dc9af29af39fd24758 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 20 Oct 2024 11:58:16 +0900 Subject: [PATCH 09/79] Update comments --- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index b50f025d261e1..6f44797be20e3 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -138,14 +138,14 @@ Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS, Counter CounterExpressionBuilder::replace(Counter C, const ReplaceMap &Map) { auto I = Map.find(C); - // Replace C with the Map even if C is Expression. + // Replace C with the value found in Map even if C is Expression. if (I != Map.end()) return I->second; - // Traverse only Expression. if (!C.isExpression()) return C; + // Traverse both sides of Expression. auto CE = Expressions[C.getExpressionID()]; auto NewLHS = replace(CE.LHS, Map); auto NewRHS = replace(CE.RHS, Map); From f0afd04dd86573f1e7d868cc6e1c677d1779aa5f Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 20 Oct 2024 12:00:23 +0900 Subject: [PATCH 10/79] Use initializer statements --- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 6f44797be20e3..7ff2e5ba69e19 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -136,10 +136,8 @@ Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS, } Counter CounterExpressionBuilder::replace(Counter C, const ReplaceMap &Map) { - auto I = Map.find(C); - // Replace C with the value found in Map even if C is Expression. - if (I != Map.end()) + if (auto I = Map.find(C); I != Map.end()) return I->second; if (!C.isExpression()) @@ -161,7 +159,7 @@ Counter CounterExpressionBuilder::replace(Counter C, const ReplaceMap &Map) { } // Reconfirm if the reconstructed expression would hit the Map. - if ((I = Map.find(C)) != Map.end()) + if (auto I = Map.find(C); I != Map.end()) return I->second; return C; From be516faa39e1152d637ac425229f8a88480ba41b Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 20 Oct 2024 11:57:03 +0900 Subject: [PATCH 11/79] `first` may be cancelled. Currently `first` is not None by default. --- clang/lib/CodeGen/CodeGenPGO.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index aefd53e12088b..0f2090da47a37 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -1215,7 +1215,8 @@ void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, auto &TheMap = (*RegionCounterMap)[S]; auto IsCounter = TheMap.getIsCounterPair(); if (!UseSkipPath) { - assert(IsCounter.first); + if (!IsCounter.first) + return; Counter = (TheMap.first & CounterPair::Mask); } else { if (!IsCounter.second) From 52f072e5058267660aa8c8fbb00c5d09634f22b3 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 18 Oct 2024 08:32:39 +0900 Subject: [PATCH 12/79] 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 5d19c77551c6fc585d1b15c4c2a71c3c3f99ef8a Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Fri, 18 Oct 2024 09:33:51 +0900 Subject: [PATCH 13/79] [Coverage][Single] Enable Branch coverage for loop statements --- clang/lib/CodeGen/CGStmt.cpp | 82 ++++------- clang/lib/CodeGen/CodeGenFunction.cpp | 11 +- clang/lib/CodeGen/CodeGenPGO.cpp | 79 +---------- clang/lib/CodeGen/CoverageMappingGen.cpp | 130 +++++------------- .../CoverageMapping/single-byte-counters.cpp | 53 +++---- 5 files changed, 97 insertions(+), 258 deletions(-) diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index dbc1ce9bf993c..7d778ce58a148 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -1039,15 +1039,11 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, SourceLocToDebugLoc(R.getEnd()), checkIfLoopMustProgress(S.getCond(), hasEmptyLoopBody(S))); - // When single byte coverage mode is enabled, add a counter to loop condition. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(S.getCond()); - // As long as the condition is true, go to the loop body. llvm::BasicBlock *LoopBody = createBasicBlock("while.body"); if (EmitBoolCondBranch) { llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); - if (ConditionScope.requiresCleanups()) + if (getIsCounterPair(&S).second || ConditionScope.requiresCleanups()) ExitBlock = createBasicBlock("while.exit"); llvm::MDNode *Weights = createProfileWeightsForLoop(S.getCond(), getProfileCount(S.getBody())); @@ -1058,6 +1054,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, if (ExitBlock != LoopExit.getBlock()) { EmitBlock(ExitBlock); + incrementProfileCounter(true, &S); EmitBranchThroughCleanup(LoopExit); } } else if (const Attr *A = Stmt::getLikelihoodAttr(S.getBody())) { @@ -1075,11 +1072,7 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, { RunCleanupsScope BodyScope(*this); EmitBlock(LoopBody); - // When single byte coverage mode is enabled, add a counter to the body. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(S.getBody()); - else - incrementProfileCounter(&S); + incrementProfileCounter(false, &S); EmitStmt(S.getBody()); } @@ -1099,13 +1092,10 @@ void CodeGenFunction::EmitWhileStmt(const WhileStmt &S, // The LoopHeader typically is just a branch if we skipped emitting // a branch, try to erase it. - if (!EmitBoolCondBranch) + if (!EmitBoolCondBranch) { SimplifyForwardingBlocks(LoopHeader.getBlock()); - - // When single byte coverage mode is enabled, add a counter to continuation - // block. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(&S); + PGO.markStmtAsUsed(true, &S); + } if (CGM.shouldEmitConvergenceTokens()) ConvergenceTokenStack.pop_back(); @@ -1124,10 +1114,7 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S, // Emit the body of the loop. llvm::BasicBlock *LoopBody = createBasicBlock("do.body"); - if (llvm::EnableSingleByteCoverage) - EmitBlockWithFallThrough(LoopBody, S.getBody()); - else - EmitBlockWithFallThrough(LoopBody, &S); + EmitBlockWithFallThrough(LoopBody, &S); if (CGM.shouldEmitConvergenceTokens()) ConvergenceTokenStack.push_back( @@ -1139,9 +1126,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S, } EmitBlock(LoopCond.getBlock()); - // When single byte coverage mode is enabled, add a counter to loop condition. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(S.getCond()); // C99 6.8.5.2: "The evaluation of the controlling expression takes place // after each execution of the loop body." @@ -1164,16 +1148,25 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S, SourceLocToDebugLoc(R.getEnd()), checkIfLoopMustProgress(S.getCond(), hasEmptyLoopBody(S))); + auto *LoopFalse = + (getIsCounterPair(&S).second ? createBasicBlock("do.loopfalse") + : LoopExit.getBlock()); + // As long as the condition is true, iterate the loop. if (EmitBoolCondBranch) { uint64_t BackedgeCount = getProfileCount(S.getBody()) - ParentCount; Builder.CreateCondBr( - BoolCondVal, LoopBody, LoopExit.getBlock(), + BoolCondVal, LoopBody, LoopFalse, createProfileWeightsForLoop(S.getCond(), BackedgeCount)); } LoopStack.pop(); + if (LoopFalse != LoopExit.getBlock()) { + EmitBlock(LoopFalse); + incrementProfileCounter(true, &S, true); + } + // Emit the exit block. EmitBlock(LoopExit.getBlock()); @@ -1182,11 +1175,6 @@ void CodeGenFunction::EmitDoStmt(const DoStmt &S, if (!EmitBoolCondBranch) SimplifyForwardingBlocks(LoopCond.getBlock()); - // When single byte coverage mode is enabled, add a counter to continuation - // block. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(&S); - if (CGM.shouldEmitConvergenceTokens()) ConvergenceTokenStack.pop_back(); } @@ -1247,15 +1235,10 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, BreakContinueStack.back().ContinueBlock = Continue; } - // When single byte coverage mode is enabled, add a counter to loop - // condition. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(S.getCond()); - llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); // If there are any cleanups between here and the loop-exit scope, // create a block to stage a loop exit along. - if (ForScope.requiresCleanups()) + if (getIsCounterPair(&S).second || ForScope.requiresCleanups()) ExitBlock = createBasicBlock("for.cond.cleanup"); // As long as the condition is true, iterate the loop. @@ -1274,6 +1257,7 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, if (ExitBlock != LoopExit.getBlock()) { EmitBlock(ExitBlock); + incrementProfileCounter(true, &S); EmitBranchThroughCleanup(LoopExit); } @@ -1281,13 +1265,11 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, } else { // Treat it as a non-zero constant. Don't even create a new block for the // body, just fall into it. + PGO.markStmtAsUsed(true, &S); } - // When single byte coverage mode is enabled, add a counter to the body. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(S.getBody()); - else - incrementProfileCounter(&S); + incrementProfileCounter(false, &S); + { // Create a separate cleanup scope for the body, in case it is not // a compound statement. @@ -1299,8 +1281,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, if (S.getInc()) { EmitBlock(Continue.getBlock()); EmitStmt(S.getInc()); - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(S.getInc()); } BreakContinueStack.pop_back(); @@ -1317,11 +1297,6 @@ void CodeGenFunction::EmitForStmt(const ForStmt &S, // Emit the fall-through block. EmitBlock(LoopExit.getBlock(), true); - // When single byte coverage mode is enabled, add a counter to continuation - // block. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(&S); - if (CGM.shouldEmitConvergenceTokens()) ConvergenceTokenStack.pop_back(); } @@ -1358,7 +1333,7 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S, // If there are any cleanups between here and the loop-exit scope, // create a block to stage a loop exit along. llvm::BasicBlock *ExitBlock = LoopExit.getBlock(); - if (ForScope.requiresCleanups()) + if (getIsCounterPair(&S).second || ForScope.requiresCleanups()) ExitBlock = createBasicBlock("for.cond.cleanup"); // The loop body, consisting of the specified body and the loop variable. @@ -1376,14 +1351,12 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S, if (ExitBlock != LoopExit.getBlock()) { EmitBlock(ExitBlock); + incrementProfileCounter(true, &S); EmitBranchThroughCleanup(LoopExit); } EmitBlock(ForBody); - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(S.getBody()); - else - incrementProfileCounter(&S); + incrementProfileCounter(false, &S); // Create a block for the increment. In case of a 'continue', we jump there. JumpDest Continue = getJumpDestInCurrentScope("for.inc"); @@ -1414,11 +1387,6 @@ CodeGenFunction::EmitCXXForRangeStmt(const CXXForRangeStmt &S, // Emit the fall-through block. EmitBlock(LoopExit.getBlock(), true); - // When single byte coverage mode is enabled, add a counter to continuation - // block. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(&S); - if (CGM.shouldEmitConvergenceTokens()) ConvergenceTokenStack.pop_back(); } diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index df15d09276c2f..848f8d1a69c10 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -53,10 +53,6 @@ using namespace clang; using namespace CodeGen; -namespace llvm { -extern cl::opt EnableSingleByteCoverage; -} // namespace llvm - /// shouldEmitLifetimeMarkers - Decide whether we need emit the life-time /// markers. static bool shouldEmitLifetimeMarkers(const CodeGenOptions &CGOpts, @@ -1361,10 +1357,7 @@ void CodeGenFunction::EmitFunctionBody(const Stmt *Body) { void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB, const Stmt *S) { llvm::BasicBlock *SkipCountBB = nullptr; - // Do not skip over the instrumentation when single byte coverage mode is - // enabled. - if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr() && - !llvm::EnableSingleByteCoverage) { + if (HaveInsertPoint() && CGM.getCodeGenOpts().hasProfileClangInstr()) { // When instrumenting for profiling, the fallthrough to certain // statements needs to skip over the instrumentation code so that we // get an accurate count. @@ -1373,7 +1366,7 @@ void CodeGenFunction::EmitBlockWithFallThrough(llvm::BasicBlock *BB, } EmitBlock(BB); uint64_t CurrentCount = getCurrentProfileCount(); - incrementProfileCounter(S); + incrementProfileCounter(false, S); setCurrentProfileCount(getCurrentProfileCount() + CurrentCount); if (SkipCountBB) EmitBlock(SkipCountBB); diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 0f2090da47a37..6020a611d1a57 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -394,81 +394,6 @@ struct MapRegionCounters : public RecursiveASTVisitor { return true; } - bool TraverseWhileStmt(WhileStmt *While) { - // When single byte coverage mode is enabled, add a counter to condition and - // body. - bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage; - for (Stmt *CS : While->children()) { - if (!CS || NoSingleByteCoverage) - continue; - if (CS == While->getCond()) - CounterMap[While->getCond()] = NextCounter++; - else if (CS == While->getBody()) - CounterMap[While->getBody()] = NextCounter++; - } - - Base::TraverseWhileStmt(While); - if (Hash.getHashVersion() != PGO_HASH_V1) - Hash.combine(PGOHash::EndOfScope); - return true; - } - - bool TraverseDoStmt(DoStmt *Do) { - // When single byte coverage mode is enabled, add a counter to condition and - // body. - bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage; - for (Stmt *CS : Do->children()) { - if (!CS || NoSingleByteCoverage) - continue; - if (CS == Do->getCond()) - CounterMap[Do->getCond()] = NextCounter++; - else if (CS == Do->getBody()) - CounterMap[Do->getBody()] = NextCounter++; - } - - Base::TraverseDoStmt(Do); - if (Hash.getHashVersion() != PGO_HASH_V1) - Hash.combine(PGOHash::EndOfScope); - return true; - } - - bool TraverseForStmt(ForStmt *For) { - // When single byte coverage mode is enabled, add a counter to condition, - // increment and body. - bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage; - for (Stmt *CS : For->children()) { - if (!CS || NoSingleByteCoverage) - continue; - if (CS == For->getCond()) - CounterMap[For->getCond()] = NextCounter++; - else if (CS == For->getInc()) - CounterMap[For->getInc()] = NextCounter++; - else if (CS == For->getBody()) - CounterMap[For->getBody()] = NextCounter++; - } - - Base::TraverseForStmt(For); - if (Hash.getHashVersion() != PGO_HASH_V1) - Hash.combine(PGOHash::EndOfScope); - return true; - } - - bool TraverseCXXForRangeStmt(CXXForRangeStmt *ForRange) { - // When single byte coverage mode is enabled, add a counter to body. - bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage; - for (Stmt *CS : ForRange->children()) { - if (!CS || NoSingleByteCoverage) - continue; - if (CS == ForRange->getBody()) - CounterMap[ForRange->getBody()] = NextCounter++; - } - - Base::TraverseCXXForRangeStmt(ForRange); - if (Hash.getHashVersion() != PGO_HASH_V1) - Hash.combine(PGOHash::EndOfScope); - return true; - } - // If the statement type \p N is nestable, and its nesting impacts profile // stability, define a custom traversal which tracks the end of the statement // in the hash (provided we're not using the V1 hash). @@ -480,6 +405,10 @@ struct MapRegionCounters : public RecursiveASTVisitor { return true; \ } + DEFINE_NESTABLE_TRAVERSAL(WhileStmt) + DEFINE_NESTABLE_TRAVERSAL(DoStmt) + DEFINE_NESTABLE_TRAVERSAL(ForStmt) + DEFINE_NESTABLE_TRAVERSAL(CXXForRangeStmt) DEFINE_NESTABLE_TRAVERSAL(ObjCForCollectionStmt) DEFINE_NESTABLE_TRAVERSAL(CXXTryStmt) DEFINE_NESTABLE_TRAVERSAL(CXXCatchStmt) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index a331d5bc68286..4062c531d0b79 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1570,9 +1570,8 @@ struct CounterCoverageMappingBuilder void VisitBreakStmt(const BreakStmt *S) { assert(!BreakContinueStack.empty() && "break not in a loop or switch!"); - if (!llvm::EnableSingleByteCoverage) - BreakContinueStack.back().BreakCount = addCounters( - BreakContinueStack.back().BreakCount, getRegion().getCounter()); + BreakContinueStack.back().BreakCount = addCounters( + BreakContinueStack.back().BreakCount, getRegion().getCounter()); // FIXME: a break in a switch should terminate regions for all preceding // case statements, not just the most recent one. terminateRegion(S); @@ -1580,9 +1579,8 @@ struct CounterCoverageMappingBuilder void VisitContinueStmt(const ContinueStmt *S) { assert(!BreakContinueStack.empty() && "continue stmt not in a loop!"); - if (!llvm::EnableSingleByteCoverage) - BreakContinueStack.back().ContinueCount = addCounters( - BreakContinueStack.back().ContinueCount, getRegion().getCounter()); + BreakContinueStack.back().ContinueCount = addCounters( + BreakContinueStack.back().ContinueCount, getRegion().getCounter()); terminateRegion(S); } @@ -1600,9 +1598,7 @@ struct CounterCoverageMappingBuilder extendRegion(S); Counter ParentCount = getRegion().getCounter(); - Counter BodyCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S->getBody()) - : getRegionCounter(S); + Counter BodyCount = getRegionCounter(S); // Handle the body first so that we can get the backedge count. BreakContinueStack.push_back(BreakContinue()); @@ -1615,16 +1611,10 @@ struct CounterCoverageMappingBuilder // Go back to handle the condition. Counter CondCount = - llvm::EnableSingleByteCoverage - ? getRegionCounter(S->getCond()) - : addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - auto [ExecCount, ExitCount] = - (llvm::EnableSingleByteCoverage - ? std::make_pair(getRegionCounter(S), Counter::getZero()) - : getBranchCounterPair(S, CondCount)); - if (!llvm::EnableSingleByteCoverage) { - assert(ExecCount.isZero() || ExecCount == BodyCount); - } + addCounters(ParentCount, BackedgeCount, BC.ContinueCount); + auto [ExecCount, ExitCount] = getBranchCounterPair(S, CondCount); + assert(ExecCount.isZero() || ExecCount == BodyCount); + propagateCounts(CondCount, S->getCond()); adjustForOutOfOrderTraversal(getEnd(S)); @@ -1633,10 +1623,7 @@ struct CounterCoverageMappingBuilder if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); - Counter OutCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BC.BreakCount, ExitCount); - + Counter OutCount = addCounters(BC.BreakCount, ExitCount); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; @@ -1645,56 +1632,40 @@ struct CounterCoverageMappingBuilder } // Create Branch Region around condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, ExitCount); + createBranchRegion(S->getCond(), BodyCount, ExitCount); } void VisitDoStmt(const DoStmt *S) { extendRegion(S); Counter ParentCount = getRegion().getCounter(); - Counter BodyCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S->getBody()) - : getRegionCounter(S); + Counter BodyCount = getRegionCounter(S); BreakContinueStack.push_back(BreakContinue()); extendRegion(S->getBody()); - Counter BackedgeCount; - if (llvm::EnableSingleByteCoverage) - propagateCounts(BodyCount, S->getBody()); - else - BackedgeCount = - propagateCounts(addCounters(ParentCount, BodyCount), S->getBody()); + Counter BackedgeCount = + propagateCounts(addCounters(ParentCount, BodyCount), S->getBody()); BreakContinue BC = BreakContinueStack.pop_back_val(); bool BodyHasTerminateStmt = HasTerminateStmt; HasTerminateStmt = false; - Counter CondCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S->getCond()) - : addCounters(BackedgeCount, BC.ContinueCount); - auto [ExecCount, ExitCount] = - (llvm::EnableSingleByteCoverage - ? std::make_pair(getRegionCounter(S), Counter::getZero()) - : getBranchCounterPair(S, CondCount)); - if (!llvm::EnableSingleByteCoverage) { - assert(ExecCount.isZero() || ExecCount == BodyCount); - } + Counter CondCount = addCounters(BackedgeCount, BC.ContinueCount); + auto [ExecCount, ExitCount] = getBranchCounterPair(S, CondCount); + assert(ExecCount.isZero() || ExecCount == BodyCount); + propagateCounts(CondCount, S->getCond()); - Counter OutCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BC.BreakCount, ExitCount); + Counter OutCount = addCounters(BC.BreakCount, ExitCount); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; } // Create Branch Region around condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, ExitCount); + createBranchRegion(S->getCond(), BodyCount, ExitCount); if (BodyHasTerminateStmt) HasTerminateStmt = true; @@ -1706,9 +1677,7 @@ struct CounterCoverageMappingBuilder Visit(S->getInit()); Counter ParentCount = getRegion().getCounter(); - Counter BodyCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S->getBody()) - : getRegionCounter(S); + Counter BodyCount = getRegionCounter(S); // The loop increment may contain a break or continue. if (S->getInc()) @@ -1727,29 +1696,16 @@ struct CounterCoverageMappingBuilder // the count for all the continue statements. BreakContinue IncrementBC; if (const Stmt *Inc = S->getInc()) { - Counter IncCount; - if (llvm::EnableSingleByteCoverage) - IncCount = getRegionCounter(S->getInc()); - else - IncCount = addCounters(BackedgeCount, BodyBC.ContinueCount); - propagateCounts(IncCount, Inc); + propagateCounts(addCounters(BackedgeCount, BodyBC.ContinueCount), Inc); IncrementBC = BreakContinueStack.pop_back_val(); } // Go back to handle the condition. - Counter CondCount = - llvm::EnableSingleByteCoverage - ? getRegionCounter(S->getCond()) - : addCounters( - addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount), - IncrementBC.ContinueCount); - auto [ExecCount, ExitCount] = - (llvm::EnableSingleByteCoverage - ? std::make_pair(getRegionCounter(S), Counter::getZero()) - : getBranchCounterPair(S, CondCount)); - if (!llvm::EnableSingleByteCoverage) { - assert(ExecCount.isZero() || ExecCount == BodyCount); - } + Counter CondCount = addCounters( + addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount), + IncrementBC.ContinueCount); + auto [ExecCount, ExitCount] = getBranchCounterPair(S, CondCount); + assert(ExecCount.isZero() || ExecCount == BodyCount); if (const Expr *Cond = S->getCond()) { propagateCounts(CondCount, Cond); @@ -1762,9 +1718,7 @@ struct CounterCoverageMappingBuilder fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); Counter OutCount = - llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, ExitCount); + addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, ExitCount); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; @@ -1773,8 +1727,7 @@ struct CounterCoverageMappingBuilder } // Create Branch Region around condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, ExitCount); + createBranchRegion(S->getCond(), BodyCount, ExitCount); } void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { @@ -1785,9 +1738,7 @@ struct CounterCoverageMappingBuilder Visit(S->getRangeStmt()); Counter ParentCount = getRegion().getCounter(); - Counter BodyCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S->getBody()) - : getRegionCounter(S); + Counter BodyCount = getRegionCounter(S); BreakContinueStack.push_back(BreakContinue()); extendRegion(S->getBody()); @@ -1802,18 +1753,12 @@ struct CounterCoverageMappingBuilder if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); - Counter OutCount; - Counter ExitCount; - Counter LoopCount; - if (llvm::EnableSingleByteCoverage) - OutCount = getRegionCounter(S); - else { - LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - auto [ExecCount, SkipCount] = getBranchCounterPair(S, LoopCount); - ExitCount = SkipCount; - assert(ExecCount.isZero() || ExecCount == BodyCount); - OutCount = addCounters(BC.BreakCount, ExitCount); - } + Counter LoopCount = + addCounters(ParentCount, BackedgeCount, BC.ContinueCount); + auto [ExecCount, ExitCount] = getBranchCounterPair(S, LoopCount); + assert(ExecCount.isZero() || ExecCount == BodyCount); + + Counter OutCount = addCounters(BC.BreakCount, ExitCount); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; @@ -1822,8 +1767,7 @@ struct CounterCoverageMappingBuilder } // Create Branch Region around condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, ExitCount); + createBranchRegion(S->getCond(), BodyCount, ExitCount); } void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp index d20b695bc2636..401b5d7dd8b84 100644 --- a/clang/test/CoverageMapping/single-byte-counters.cpp +++ b/clang/test/CoverageMapping/single-byte-counters.cpp @@ -54,76 +54,81 @@ int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+17]]:2 = } // CHECK-NEXT: testWhile -int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+11]]:2 = [[C40:#0]] +int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+12]]:2 = [[C40:#0]] int i = 0; int sum = 0; - 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]] + while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = ([[C40]] + [[C4T:#1]]) + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:10 -> [[@LINE-1]]:16 = [[C4T]], [[C4F:#2]] + // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:17 -> [[@LINE-2]]:18 = [[C4T]] + // CHECK-NEXT: File 0, [[@LINE-3]]:18 -> [[@LINE+3]]:4 = [[C4T]] sum += i; i++; } - return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C4E:#3]] + return sum; // #0 } // CHECK-NEXT: testContinue -int testContinue() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+15]]:2 = [[C50:#0]] +int testContinue() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+16]]:2 = [[C50:#0]] int i = 0; int sum = 0; - 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]] + while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = (([[C50]] + [[C5T:#2]]) + [[C5F:#3]]) + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:10 -> [[@LINE-1]]:16 = [[C5B:#1]], [[C5E:#4]] + // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:17 -> [[@LINE-2]]:18 = [[C5B]] + // CHECK-NEXT: File 0, [[@LINE-3]]: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]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:7 = [[C5T]] continue; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = [[C5T]] - // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:5 = [[C5F:#5]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:5 = [[C5F]] sum += i; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = [[C5F]] i++; } - // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C5E:#3]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C5E]] return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C5E]] } // CHECK-NEXT: testFor -int testFor() { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+12]]:2 = [[C60:#0]] +int testFor() { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+13]]: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]] + // CHECK-NEXT: File 0, [[@LINE+3]]:19 -> [[@LINE+3]]:25 = ([[C60]] + [[C6B:#1]]) + // CHECK-NEXT: Branch,File 0, [[@LINE+2]]:19 -> [[@LINE+2]]:25 = [[C6B]], [[C6E:#2]] + // CHECK-NEXT: File 0, [[@LINE+1]]:27 -> [[@LINE+1]]:30 = [[C6B]] for (int i = 0; i < 10; i++) { - // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:31 -> [[@LINE-1]]:32 = [[C6B:#3]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:31 -> [[@LINE-1]]:32 = [[C6B]] // CHECK-NEXT: File 0, [[@LINE-2]]:32 -> [[@LINE+2]]:4 = [[C6B]] sum += i; } - return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C6E:#4]] + return sum; // #0 } // CHECK-NEXT: testForRange -int testForRange() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+11]]:2 = [[C70:#0]] +int testForRange() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+12]]:2 = [[C70:#0]] int sum = 0; int array[] = {1, 2, 3, 4, 5}; + // CHECK-NEXT: Branch,File 0, [[@LINE+1]]:20 -> [[@LINE+1]]:21 = [[C7B:#1]], [[C7E:#2]] for (int element : array) { - // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:28 -> [[@LINE-1]]:29 = [[C7B:#1]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:28 -> [[@LINE-1]]:29 = [[C7B]] // CHECK-NEXT: File 0, [[@LINE-2]]:29 -> [[@LINE+2]]:4 = [[C7B]] sum += element; } - return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C7E:#2]] + return sum; // #0 } // CHECK-NEXT: testDo -int testDo() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+9]]:2 = [[C80:#0]] +int testDo() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+10]]:2 = [[C80:#0]] int i = 0; int sum = 0; - do { // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE+3]]:4 = [[C8B:#1]] + do { // CHECK-NEXT: File 0, [[@LINE]]:6 -> [[@LINE+3]]:4 = ([[C80]] + [[C8B:#1]]) sum += i; i++; - } while (i < 5); // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE]]:17 = [[C8C:#2]] + } while (i < 5); // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE]]:17 = ([[C80]] + [[C8B]]) + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:12 -> [[@LINE-1]]:17 = [[C8B]], [[C8E:#2]] - return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C8E:#3]] + return sum; // #0 } // CHECK-NEXT: testConditional From 744c5b634de08f9214c82d6fcfde7179bc4edfb0 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 20 Oct 2024 14:46:07 +0900 Subject: [PATCH 14/79] [Coverage][Single] Enable Branch coverage for CondOp --- clang/lib/CodeGen/CGExpr.cpp | 6 +-- clang/lib/CodeGen/CGExprAgg.cpp | 14 +------ clang/lib/CodeGen/CGExprComplex.cpp | 15 +------- clang/lib/CodeGen/CGExprScalar.cpp | 37 +++---------------- clang/lib/CodeGen/CodeGenFunction.cpp | 3 +- clang/lib/CodeGen/CodeGenPGO.cpp | 8 ---- clang/lib/CodeGen/CoverageMappingGen.cpp | 16 ++------ .../CoverageMapping/single-byte-counters.cpp | 11 +++--- 8 files changed, 25 insertions(+), 85 deletions(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index cc85f05ad9f70..67e3a1de17e67 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -5137,8 +5137,7 @@ std::optional HandleConditionalOperatorLValueSimpleCase( if (!CGF.ContainsLabel(Dead)) { // If the true case is live, we need to track its region. - if (CondExprBool) - CGF.incrementProfileCounter(E); + CGF.incrementProfileCounter(!CondExprBool, E, true); CGF.markStmtMaybeUsed(Dead); // If a throw expression we emit it and return an undefined lvalue // because it can't be used. @@ -5177,7 +5176,7 @@ ConditionalInfo EmitConditionalBlocks(CodeGenFunction &CGF, // Any temporaries created here are conditional. CGF.EmitBlock(Info.lhsBlock); - CGF.incrementProfileCounter(E); + CGF.incrementProfileCounter(false, E); eval.begin(CGF); Info.LHS = BranchGenFunc(CGF, E->getTrueExpr()); eval.end(CGF); @@ -5188,6 +5187,7 @@ ConditionalInfo EmitConditionalBlocks(CodeGenFunction &CGF, // Any temporaries created here are conditional. CGF.EmitBlock(Info.rhsBlock); + CGF.incrementProfileCounter(true, E); eval.begin(CGF); Info.RHS = BranchGenFunc(CGF, E->getFalseExpr()); eval.end(CGF); diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 2ad6587089f10..0c778ef185532 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -36,10 +36,6 @@ using namespace CodeGen; // Aggregate Expression Emitter //===----------------------------------------------------------------------===// -namespace llvm { -extern cl::opt EnableSingleByteCoverage; -} // namespace llvm - namespace { class AggExprEmitter : public StmtVisitor { CodeGenFunction &CGF; @@ -1293,10 +1289,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { eval.begin(CGF); CGF.EmitBlock(LHSBlock); - if (llvm::EnableSingleByteCoverage) - CGF.incrementProfileCounter(E->getTrueExpr()); - else - CGF.incrementProfileCounter(E); + CGF.incrementProfileCounter(false, E); Visit(E->getTrueExpr()); eval.end(CGF); @@ -1311,8 +1304,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { eval.begin(CGF); CGF.EmitBlock(RHSBlock); - if (llvm::EnableSingleByteCoverage) - CGF.incrementProfileCounter(E->getFalseExpr()); + CGF.incrementProfileCounter(true, E); Visit(E->getFalseExpr()); eval.end(CGF); @@ -1321,8 +1313,6 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { E->getType()); CGF.EmitBlock(ContBlock); - if (llvm::EnableSingleByteCoverage) - CGF.incrementProfileCounter(E); } void AggExprEmitter::VisitChooseExpr(const ChooseExpr *CE) { diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index fef26e7b4ccdb..bcece9431de76 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -28,10 +28,6 @@ using namespace CodeGen; // Complex Expression Emitter //===----------------------------------------------------------------------===// -namespace llvm { -extern cl::opt EnableSingleByteCoverage; -} // namespace llvm - typedef CodeGenFunction::ComplexPairTy ComplexPairTy; /// Return the complex type that we are meant to emit. @@ -1381,11 +1377,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { eval.begin(CGF); CGF.EmitBlock(LHSBlock); - if (llvm::EnableSingleByteCoverage) - CGF.incrementProfileCounter(E->getTrueExpr()); - else - CGF.incrementProfileCounter(E); - + CGF.incrementProfileCounter(false, E); ComplexPairTy LHS = Visit(E->getTrueExpr()); LHSBlock = Builder.GetInsertBlock(); CGF.EmitBranch(ContBlock); @@ -1393,13 +1385,10 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { eval.begin(CGF); CGF.EmitBlock(RHSBlock); - if (llvm::EnableSingleByteCoverage) - CGF.incrementProfileCounter(E->getFalseExpr()); + CGF.incrementProfileCounter(true, E); ComplexPairTy RHS = Visit(E->getFalseExpr()); RHSBlock = Builder.GetInsertBlock(); CGF.EmitBlock(ContBlock); - if (llvm::EnableSingleByteCoverage) - CGF.incrementProfileCounter(E); eval.end(CGF); // Create a PHI node for the real part. diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index ca9ab6025128f..11d4ec8a26760 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -55,10 +55,6 @@ using llvm::Value; // Scalar Expression Emitter //===----------------------------------------------------------------------===// -namespace llvm { -extern cl::opt EnableSingleByteCoverage; -} // namespace llvm - namespace { /// Determine whether the given binary operation may overflow. @@ -5247,13 +5243,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { // If the dead side doesn't have labels we need, just emit the Live part. if (!CGF.ContainsLabel(dead)) { - if (CondExprBool) { - if (llvm::EnableSingleByteCoverage) { - CGF.incrementProfileCounter(lhsExpr); - CGF.incrementProfileCounter(rhsExpr); - } - CGF.incrementProfileCounter(E); - } + CGF.incrementProfileCounter(!CondExprBool, E, true); Value *Result = Visit(live); CGF.markStmtMaybeUsed(dead); @@ -5328,17 +5318,13 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { // If this is a really simple expression (like x ? 4 : 5), emit this as a // select instead of as control flow. We can only do this if it is cheap and // safe to evaluate the LHS and RHS unconditionally. - if (isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) && + if (!CGF.getIsCounterPair(E).second && + isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) && isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) { llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr); llvm::Value *StepV = Builder.CreateZExtOrBitCast(CondV, CGF.Int64Ty); - if (llvm::EnableSingleByteCoverage) { - CGF.incrementProfileCounter(lhsExpr); - CGF.incrementProfileCounter(rhsExpr); - CGF.incrementProfileCounter(E); - } else - CGF.incrementProfileCounter(E, StepV); + CGF.incrementProfileCounter(E, StepV); llvm::Value *LHS = Visit(lhsExpr); llvm::Value *RHS = Visit(rhsExpr); @@ -5370,11 +5356,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { if (CGF.MCDCLogOpStack.empty()) CGF.maybeUpdateMCDCTestVectorBitmap(condExpr); - if (llvm::EnableSingleByteCoverage) - CGF.incrementProfileCounter(lhsExpr); - else - CGF.incrementProfileCounter(E); - + CGF.incrementProfileCounter(false, E); eval.begin(CGF); Value *LHS = Visit(lhsExpr); eval.end(CGF); @@ -5390,9 +5372,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { if (CGF.MCDCLogOpStack.empty()) CGF.maybeUpdateMCDCTestVectorBitmap(condExpr); - if (llvm::EnableSingleByteCoverage) - CGF.incrementProfileCounter(rhsExpr); - + CGF.incrementProfileCounter(true, E); eval.begin(CGF); Value *RHS = Visit(rhsExpr); eval.end(CGF); @@ -5411,11 +5391,6 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { PN->addIncoming(LHS, LHSBlock); PN->addIncoming(RHS, RHSBlock); - // When single byte coverage mode is enabled, add a counter to continuation - // block. - if (llvm::EnableSingleByteCoverage) - CGF.incrementProfileCounter(E); - return PN; } diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index df15d09276c2f..2bcba9bef2628 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -2004,7 +2004,7 @@ void CodeGenFunction::EmitBranchOnBoolExpr( cond.begin(*this); EmitBlock(LHSBlock); - incrementProfileCounter(CondOp); + incrementProfileCounter(false, CondOp); { ApplyDebugLocation DL(*this, Cond); EmitBranchOnBoolExpr(CondOp->getLHS(), TrueBlock, FalseBlock, @@ -2014,6 +2014,7 @@ void CodeGenFunction::EmitBranchOnBoolExpr( cond.begin(*this); EmitBlock(RHSBlock); + incrementProfileCounter(true, CondOp); EmitBranchOnBoolExpr(CondOp->getRHS(), TrueBlock, FalseBlock, TrueCount - LHSScaledTrueCount, LH, CondOp); cond.end(*this); diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 0f2090da47a37..69f6629097984 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -343,14 +343,6 @@ struct MapRegionCounters : public RecursiveASTVisitor { return Base::VisitBinaryOperator(S); } - bool VisitConditionalOperator(ConditionalOperator *S) { - if (llvm::EnableSingleByteCoverage && S->getTrueExpr()) - CounterMap[S->getTrueExpr()] = NextCounter++; - if (llvm::EnableSingleByteCoverage && S->getFalseExpr()) - CounterMap[S->getFalseExpr()] = NextCounter++; - return Base::VisitConditionalOperator(S); - } - /// Include \p S in the function hash. bool VisitStmt(Stmt *S) { auto Type = updateCounterMappings(S); diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index a331d5bc68286..77e7399209806 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -2125,11 +2125,7 @@ struct CounterCoverageMappingBuilder extendRegion(E); Counter ParentCount = getRegion().getCounter(); - auto [TrueCount, FalseCount] = - (llvm::EnableSingleByteCoverage - ? std::make_pair(getRegionCounter(E->getTrueExpr()), - getRegionCounter(E->getFalseExpr())) - : getBranchCounterPair(E, ParentCount)); + auto [TrueCount, FalseCount] = getBranchCounterPair(E, ParentCount); Counter OutCount; if (const auto *BCO = dyn_cast(E)) { @@ -2148,11 +2144,8 @@ struct CounterCoverageMappingBuilder } extendRegion(E->getFalseExpr()); - Counter FalseOutCount = propagateCounts(FalseCount, E->getFalseExpr()); - if (llvm::EnableSingleByteCoverage) - OutCount = getRegionCounter(E); - else - OutCount = addCounters(OutCount, FalseOutCount); + OutCount = + addCounters(OutCount, propagateCounts(FalseCount, E->getFalseExpr())); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); @@ -2160,8 +2153,7 @@ struct CounterCoverageMappingBuilder } // Create Branch Region around condition. - if (!llvm::EnableSingleByteCoverage) - createBranchRegion(E->getCond(), TrueCount, FalseCount); + createBranchRegion(E->getCond(), TrueCount, FalseCount); } void createOrCancelDecision(const BinaryOperator *E, unsigned Since) { diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp index d20b695bc2636..be0454df002bd 100644 --- a/clang/test/CoverageMapping/single-byte-counters.cpp +++ b/clang/test/CoverageMapping/single-byte-counters.cpp @@ -127,10 +127,11 @@ int testDo() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+9]]:2 = [ } // CHECK-NEXT: testConditional -int testConditional(int x) { // CHECK-NEXT: File 0, [[@LINE]]:28 -> [[@LINE+6]]:2 = [[C90:#0]] +int testConditional(int x) { // CHECK-NEXT: File 0, [[@LINE]]:28 -> [[@LINE+7]]: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]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:15 -> [[@LINE-1]]:22 = [[C9T:#1]], [[C9F:#2]] + // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:24 -> [[@LINE-2]]:25 = [[C9T]] + // CHECK-NEXT: File 0, [[@LINE-3]]:25 -> [[@LINE-3]]:26 = [[C9T]] + // CHECK-NEXT: File 0, [[@LINE-4]]:29 -> [[@LINE-4]]:31 = [[C9F]] + return result; // #0 } From 3ea6383e2142889550f37389dfaaee81e5ae7d9c Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 20 Oct 2024 15:15:03 +0900 Subject: [PATCH 15/79] [Coverage][Single] Enable Branch coverage for IfStmt --- clang/lib/CodeGen/CGStmt.cpp | 31 +++++++--------- clang/lib/CodeGen/CodeGenPGO.cpp | 12 ------- clang/lib/CodeGen/CoverageMappingGen.cpp | 21 +++-------- .../CoverageMapping/single-byte-counters.cpp | 36 ++++++++++--------- 4 files changed, 38 insertions(+), 62 deletions(-) diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index dbc1ce9bf993c..c511e5f4f4213 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -840,8 +840,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { // If the skipped block has no labels in it, just emit the executed block. // This avoids emitting dead code and simplifies the CFG substantially. if (S.isConstexpr() || !ContainsLabel(Skipped)) { - if (CondConstant) - incrementProfileCounter(&S); + incrementProfileCounter(!CondConstant, &S, true); if (Executed) { RunCleanupsScope ExecutedScope(*this); EmitStmt(Executed); @@ -851,14 +850,14 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { } } + auto HasSkip = getIsCounterPair(&S); + // Otherwise, the condition did not fold, or we couldn't elide it. Just emit // the conditional branch. llvm::BasicBlock *ThenBlock = createBasicBlock("if.then"); llvm::BasicBlock *ContBlock = createBasicBlock("if.end"); - llvm::BasicBlock *ElseBlock = ContBlock; - if (Else) - ElseBlock = createBasicBlock("if.else"); - + llvm::BasicBlock *ElseBlock = + (Else || HasSkip.second ? createBasicBlock("if.else") : ContBlock); // Prefer the PGO based weights over the likelihood attribute. // When the build isn't optimized the metadata isn't used, so don't generate // it. @@ -891,10 +890,7 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { // Emit the 'then' code. EmitBlock(ThenBlock); - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(S.getThen()); - else - incrementProfileCounter(&S); + incrementProfileCounter(false, &S); { RunCleanupsScope ThenScope(*this); EmitStmt(S.getThen()); @@ -908,9 +904,9 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { auto NL = ApplyDebugLocation::CreateEmpty(*this); EmitBlock(ElseBlock); } - // When single byte coverage mode is enabled, add a counter to else block. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(Else); + // Add a counter to else block unless it has CounterExpr. + if (HasSkip.second) + incrementProfileCounter(true, &S); { RunCleanupsScope ElseScope(*this); EmitStmt(Else); @@ -920,15 +916,14 @@ void CodeGenFunction::EmitIfStmt(const IfStmt &S) { auto NL = ApplyDebugLocation::CreateEmpty(*this); EmitBranch(ContBlock); } + } else if (HasSkip.second) { + EmitBlock(ElseBlock); + incrementProfileCounter(true, &S); + EmitBranch(ContBlock); } // Emit the continuation block for code after the if. EmitBlock(ContBlock, true); - - // When single byte coverage mode is enabled, add a counter to continuation - // block. - if (llvm::EnableSingleByteCoverage) - incrementProfileCounter(&S); } bool CodeGenFunction::checkIfLoopMustProgress(const Expr *ControllingExpression, diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 0f2090da47a37..f6b9b5c82952c 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -366,18 +366,6 @@ struct MapRegionCounters : public RecursiveASTVisitor { if (Hash.getHashVersion() == PGO_HASH_V1) return Base::TraverseIfStmt(If); - // When single byte coverage mode is enabled, add a counter to then and - // else. - bool NoSingleByteCoverage = !llvm::EnableSingleByteCoverage; - for (Stmt *CS : If->children()) { - if (!CS || NoSingleByteCoverage) - continue; - if (CS == If->getThen()) - CounterMap[If->getThen()] = NextCounter++; - else if (CS == If->getElse()) - CounterMap[If->getElse()] = NextCounter++; - } - // Otherwise, keep track of which branch we're in while traversing. VisitStmt(If); diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index a331d5bc68286..6c6aecb9994c6 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -2050,12 +2050,7 @@ struct CounterCoverageMappingBuilder extendRegion(S->getCond()); Counter ParentCount = getRegion().getCounter(); - auto [ThenCount, ElseCount] = - (llvm::EnableSingleByteCoverage - ? std::make_pair(getRegionCounter(S->getThen()), - (S->getElse() ? getRegionCounter(S->getElse()) - : Counter::getZero())) - : getBranchCounterPair(S, ParentCount)); + auto [ThenCount, ElseCount] = getBranchCounterPair(S, ParentCount); // Emitting a counter for the condition makes it easier to interpret the // counter for the body when looking at the coverage. @@ -2080,26 +2075,20 @@ struct CounterCoverageMappingBuilder fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), ElseCount); extendRegion(Else); - Counter ElseOutCount = propagateCounts(ElseCount, Else); - if (!llvm::EnableSingleByteCoverage) - OutCount = addCounters(OutCount, ElseOutCount); + OutCount = addCounters(OutCount, propagateCounts(ElseCount, Else)); if (ThenHasTerminateStmt) HasTerminateStmt = true; - } else if (!llvm::EnableSingleByteCoverage) + } else OutCount = addCounters(OutCount, ElseCount); - if (llvm::EnableSingleByteCoverage) - OutCount = getRegionCounter(S); - if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; } - if (!llvm::EnableSingleByteCoverage) - // Create Branch Region around condition. - createBranchRegion(S->getCond(), ThenCount, ElseCount); + // Create Branch Region around condition. + createBranchRegion(S->getCond(), ThenCount, ElseCount); } void VisitCXXTryStmt(const CXXTryStmt *S) { diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp index d20b695bc2636..533f791eee19e 100644 --- a/clang/test/CoverageMapping/single-byte-counters.cpp +++ b/clang/test/CoverageMapping/single-byte-counters.cpp @@ -1,36 +1,39 @@ // 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+7]]:2 = [[C00:#0]] +int testIf(int x) { // CHECK-NEXT: File 0, [[@LINE]]:19 -> [[@LINE+8]]:2 = [[C00:#0]] int result = 0; 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]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:7 -> [[@LINE-1]]:13 = [[C0T:#1]], [[C0F:#2]] + // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:14 -> [[@LINE+1]]:5 = [[C0T]] result = -1; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:16 = [[C0T]] - return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C0E:#2]] + return result; // #0 } // CHECK-NEXT: testIfElse -int testIfElse(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+8]]:2 = [[C10:#0]] +int testIfElse(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+9]]:2 = [[C10:#0]] int result = 0; 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]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:7 -> [[@LINE-1]]:12 = [[C1T:#1]], [[C1F:#2]] + // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:13 -> [[@LINE+1]]:5 = [[C1T]] 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]] + else // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:5 = [[C1F]] result = x * x; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:19 = [[C1F]] - return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C1E:#3]] + return result; // #0 } // CHECK-NEXT: testIfElseReturn -int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+9]]:2 = [[C20:#0]] +int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+10]]:2 = [[C20:#0]] int result = 0; 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]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:7 -> [[@LINE-1]]:12 = [[C2T:#1]], [[C2F:#2]] + // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:13 -> [[@LINE+1]]:5 = [[C2T]] 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]] + else // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:20 -> [[@LINE+1]]:5 = [[C2F]] 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: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:3 = [[C2T]] + return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C2T]] } // CHECK-NEXT: testSwitch @@ -68,16 +71,17 @@ int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+11]]:2 = } // CHECK-NEXT: testContinue -int testContinue() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+15]]:2 = [[C50:#0]] +int testContinue() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+16]]:2 = [[C50:#0]] int i = 0; int sum = 0; 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]] + // CHECK-NEXT: File 0, [[@LINE-2]]:18 -> [[@LINE+8]]: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]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:15 = [[C5T:#4]], [[C5F:#5]] + // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:16 -> [[@LINE+1]]:7 = [[C5T]] continue; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = [[C5T]] - // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:5 = [[C5F:#5]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:5 = [[C5F]] sum += i; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = [[C5F]] i++; } From ec05cc37e1177f06c9a44a1e39dadc9306cc5c68 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 21 Oct 2024 08:09:31 +0900 Subject: [PATCH 16/79] [Coverage][Single] Enable Branch coverage for SwitchStmt --- clang/lib/CodeGen/CGStmt.cpp | 12 ++++++++++ clang/lib/CodeGen/CoverageMappingGen.cpp | 22 ++++++++++--------- .../CoverageMapping/single-byte-counters.cpp | 13 ++++++----- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index dbc1ce9bf993c..80fe5cf183de1 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -2259,6 +2259,18 @@ void CodeGenFunction::EmitSwitchStmt(const SwitchStmt &S) { ConditionScope.ForceCleanup(); + // Close the last case (or DefaultBlock). + EmitBranch(SwitchExit.getBlock()); + + // Insert a False Counter if SwitchStmt doesn't have DefaultStmt. + if (getIsCounterPair(S.getCond()).second) { + auto *ImplicitDefaultBlock = createBasicBlock("sw.false"); + EmitBlock(ImplicitDefaultBlock); + incrementProfileCounter(true, S.getCond()); + Builder.CreateBr(SwitchInsn->getDefaultDest()); + SwitchInsn->setDefaultDest(ImplicitDefaultBlock); + } + // Emit continuation. EmitBlock(SwitchExit.getBlock(), true); incrementProfileCounter(&S); diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index a331d5bc68286..c5fdf23299e4e 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -958,6 +958,14 @@ struct CounterCoverageMappingBuilder return {ExecCnt, SkipCnt}; } + Counter getSwitchImplicitDefaultCounter(const Stmt *Cond, Counter ParentCount, + Counter CaseCountSum) { + return ( + llvm::EnableSingleByteCoverage + ? Counter::getCounter(CounterMap[Cond].second = NextCounterNum++) + : subtractCounters(ParentCount, CaseCountSum)); + } + bool IsCounterEqual(Counter OutCount, Counter ParentCount) { if (OutCount == ParentCount) return true; @@ -1885,7 +1893,7 @@ struct CounterCoverageMappingBuilder propagateCounts(Counter::getZero(), Body); BreakContinue BC = BreakContinueStack.pop_back_val(); - if (!BreakContinueStack.empty() && !llvm::EnableSingleByteCoverage) + if (!BreakContinueStack.empty()) BreakContinueStack.back().ContinueCount = addCounters( BreakContinueStack.back().ContinueCount, BC.ContinueCount); @@ -1900,11 +1908,6 @@ struct CounterCoverageMappingBuilder MostRecentLocation = getStart(S); handleFileExit(ExitLoc); - // When single byte coverage mode is enabled, do not create branch region by - // early returning. - if (llvm::EnableSingleByteCoverage) - return; - // Create a Branch Region around each Case. Subtract the case's // counter from the Parent counter to track the "False" branch count. Counter CaseCountSum; @@ -1920,7 +1923,8 @@ struct CounterCoverageMappingBuilder // the hidden branch, which will be added later by the CodeGen. This region // will be associated with the switch statement's condition. if (!HasDefaultCase) { - Counter DefaultCount = subtractCounters(ParentCount, CaseCountSum); + Counter DefaultCount = getSwitchImplicitDefaultCounter( + S->getCond(), ParentCount, CaseCountSum); createBranchRegion(S->getCond(), Counter::getZero(), DefaultCount); } } @@ -1929,9 +1933,7 @@ struct CounterCoverageMappingBuilder extendRegion(S); SourceMappingRegion &Parent = getRegion(); - Counter Count = llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(Parent.getCounter(), getRegionCounter(S)); + Counter Count = addCounters(Parent.getCounter(), getRegionCounter(S)); // Reuse the existing region if it starts at our label. This is typical of // the first case in a switch. diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp index d20b695bc2636..464fa370d86f0 100644 --- a/clang/test/CoverageMapping/single-byte-counters.cpp +++ b/clang/test/CoverageMapping/single-byte-counters.cpp @@ -34,19 +34,22 @@ int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+9]] } // CHECK-NEXT: testSwitch -int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+17]]:2 = [[C30:#0]] +int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+20]]:2 = [[C30:#0]] int result; switch (x) { - // 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]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+13]]:15 = 0 + case 1: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = [[C31:#2]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = [[C31]], 0 result = 1; break; // 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]] + case 2: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+3]]:10 = [[C32:#3]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:9 = [[C32]], 0 result = 2; break; // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:11 -> [[@LINE+1]]:3 = 0 - default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+1]]:15 = [[C3D:#4]] + default: // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE+2]]:15 = [[C3D:#4]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:3 -> [[@LINE-1]]:10 = [[C3D]], 0 result = 0; } // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C3E:#1]] From 16e2bb8b73bcde1c2618bb358a905a9f463c1217 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 20 Oct 2024 16:24:26 +0900 Subject: [PATCH 17/79] [Coverage][Single] Enable Branch coverage for `BinLAnd` and `BinLOr` --- clang/lib/CodeGen/CGExprScalar.cpp | 83 +++++++++++++++++++----- clang/lib/CodeGen/CGStmt.cpp | 4 -- clang/lib/CodeGen/CodeGenFunction.cpp | 43 ++++++++++-- clang/lib/CodeGen/CoverageMappingGen.cpp | 6 -- 4 files changed, 104 insertions(+), 32 deletions(-) diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 11d4ec8a26760..83962ba96aa48 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -4918,6 +4918,9 @@ Value *ScalarExprEmitter::VisitBinAssign(const BinaryOperator *E) { } Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { + auto HasLHSSkip = CGF.getIsCounterPair(E); + auto HasRHSSkip = CGF.getIsCounterPair(E->getRHS()); + // Perform vector logical and on comparisons with zero vectors. if (E->getType()->isVectorType()) { CGF.incrementProfileCounter(E); @@ -4964,11 +4967,17 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { CodeGenFunction::isInstrumentedCondition(E->getRHS())) { CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond); llvm::BasicBlock *FBlock = CGF.createBasicBlock("land.end"); + llvm::BasicBlock *RHSSkip = + (HasRHSSkip.second ? CGF.createBasicBlock("land.rhsskip") : FBlock); llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt"); - Builder.CreateCondBr(RHSCond, RHSBlockCnt, FBlock); + Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSSkip); CGF.EmitBlock(RHSBlockCnt); - CGF.incrementProfileCounter(E->getRHS()); + CGF.incrementProfileCounter(false, E->getRHS()); CGF.EmitBranch(FBlock); + if (HasRHSSkip.second) { + CGF.EmitBlock(RHSSkip); + CGF.incrementProfileCounter(true, E->getRHS()); + } CGF.EmitBlock(FBlock); } @@ -4997,12 +5006,21 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { llvm::BasicBlock *ContBlock = CGF.createBasicBlock("land.end"); llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("land.rhs"); + llvm::BasicBlock *LHSFalseBlock = + (HasLHSSkip.second ? CGF.createBasicBlock("land.lhsskip") : ContBlock); + CodeGenFunction::ConditionalEvaluation eval(CGF); // Branch on the LHS first. If it is false, go to the failure (cont) block. - CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, ContBlock, + CGF.EmitBranchOnBoolExpr(E->getLHS(), RHSBlock, LHSFalseBlock, CGF.getProfileCount(E->getRHS())); + if (HasLHSSkip.second) { + CGF.EmitBlock(LHSFalseBlock); + CGF.incrementProfileCounter(true, E); + CGF.EmitBranch(ContBlock); + } + // Any edges into the ContBlock are now from an (indeterminate number of) // edges from this first condition. All of these values will be false. Start // setting up the PHI node in the Cont Block for this. @@ -5014,7 +5032,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { eval.begin(CGF); CGF.EmitBlock(RHSBlock); - CGF.incrementProfileCounter(E); + CGF.incrementProfileCounter(false, E); Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); eval.end(CGF); @@ -5024,15 +5042,24 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { // If we're generating for profiling or coverage, generate a branch on the // RHS to a block that increments the RHS true counter needed to track branch // condition coverage. + llvm::BasicBlock *ContIncoming = RHSBlock; if (InstrumentRegions && CodeGenFunction::isInstrumentedCondition(E->getRHS())) { CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond); llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("land.rhscnt"); - Builder.CreateCondBr(RHSCond, RHSBlockCnt, ContBlock); + llvm::BasicBlock *RHSBlockSkip = + (HasRHSSkip.second ? CGF.createBasicBlock("land.rhsskip") : ContBlock); + Builder.CreateCondBr(RHSCond, RHSBlockCnt, RHSBlockSkip); CGF.EmitBlock(RHSBlockCnt); - CGF.incrementProfileCounter(E->getRHS()); + CGF.incrementProfileCounter(false, E->getRHS()); CGF.EmitBranch(ContBlock); PN->addIncoming(RHSCond, RHSBlockCnt); + if (HasRHSSkip.second) { + CGF.EmitBlock(RHSBlockSkip); + CGF.incrementProfileCounter(true, E->getRHS()); + CGF.EmitBranch(ContBlock); + ContIncoming = RHSBlockSkip; + } } // Emit an unconditional branch from this block to ContBlock. @@ -5042,7 +5069,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { CGF.EmitBlock(ContBlock); } // Insert an entry into the phi node for the edge with the value of RHSCond. - PN->addIncoming(RHSCond, RHSBlock); + PN->addIncoming(RHSCond, ContIncoming); CGF.MCDCLogOpStack.pop_back(); // If the top of the logical operator nest, update the MCDC bitmap. @@ -5060,6 +5087,9 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { } Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { + auto HasLHSSkip = CGF.getIsCounterPair(E); + auto HasRHSSkip = CGF.getIsCounterPair(E->getRHS()); + // Perform vector logical or on comparisons with zero vectors. if (E->getType()->isVectorType()) { CGF.incrementProfileCounter(E); @@ -5088,7 +5118,7 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { bool LHSCondVal; if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) { if (!LHSCondVal) { // If we have 0 || X, just emit X. - CGF.incrementProfileCounter(E); + CGF.incrementProfileCounter(false, E); // If the top of the logical operator nest, reset the MCDC temp to 0. if (CGF.MCDCLogOpStack.empty()) @@ -5106,11 +5136,17 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { CodeGenFunction::isInstrumentedCondition(E->getRHS())) { CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond); llvm::BasicBlock *FBlock = CGF.createBasicBlock("lor.end"); + llvm::BasicBlock *RHSSkip = + (HasRHSSkip.second ? CGF.createBasicBlock("lor.rhsskip") : FBlock); llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("lor.rhscnt"); - Builder.CreateCondBr(RHSCond, FBlock, RHSBlockCnt); + Builder.CreateCondBr(RHSCond, RHSSkip, RHSBlockCnt); CGF.EmitBlock(RHSBlockCnt); - CGF.incrementProfileCounter(E->getRHS()); + CGF.incrementProfileCounter(false, E->getRHS()); CGF.EmitBranch(FBlock); + if (HasRHSSkip.second) { + CGF.EmitBlock(RHSSkip); + CGF.incrementProfileCounter(true, E->getRHS()); + } CGF.EmitBlock(FBlock); } @@ -5138,14 +5174,22 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { llvm::BasicBlock *ContBlock = CGF.createBasicBlock("lor.end"); llvm::BasicBlock *RHSBlock = CGF.createBasicBlock("lor.rhs"); + llvm::BasicBlock *LHSTrueBlock = + (HasLHSSkip.second ? CGF.createBasicBlock("lor.lhsskip") : ContBlock); CodeGenFunction::ConditionalEvaluation eval(CGF); // Branch on the LHS first. If it is true, go to the success (cont) block. - CGF.EmitBranchOnBoolExpr(E->getLHS(), ContBlock, RHSBlock, + CGF.EmitBranchOnBoolExpr(E->getLHS(), LHSTrueBlock, RHSBlock, CGF.getCurrentProfileCount() - CGF.getProfileCount(E->getRHS())); + if (HasLHSSkip.second) { + CGF.EmitBlock(LHSTrueBlock); + CGF.incrementProfileCounter(true, E); + CGF.EmitBranch(ContBlock); + } + // Any edges into the ContBlock are now from an (indeterminate number of) // edges from this first condition. All of these values will be true. Start // setting up the PHI node in the Cont Block for this. @@ -5159,7 +5203,7 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { // Emit the RHS condition as a bool value. CGF.EmitBlock(RHSBlock); - CGF.incrementProfileCounter(E); + CGF.incrementProfileCounter(false, E); Value *RHSCond = CGF.EvaluateExprAsBool(E->getRHS()); eval.end(CGF); @@ -5170,21 +5214,30 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { // If we're generating for profiling or coverage, generate a branch on the // RHS to a block that increments the RHS true counter needed to track branch // condition coverage. + llvm::BasicBlock *ContIncoming = RHSBlock; if (InstrumentRegions && CodeGenFunction::isInstrumentedCondition(E->getRHS())) { CGF.maybeUpdateMCDCCondBitmap(E->getRHS(), RHSCond); llvm::BasicBlock *RHSBlockCnt = CGF.createBasicBlock("lor.rhscnt"); - Builder.CreateCondBr(RHSCond, ContBlock, RHSBlockCnt); + llvm::BasicBlock *RHSTrueBlock = + (HasRHSSkip.second ? CGF.createBasicBlock("lor.rhsskip") : ContBlock); + Builder.CreateCondBr(RHSCond, RHSTrueBlock, RHSBlockCnt); CGF.EmitBlock(RHSBlockCnt); - CGF.incrementProfileCounter(E->getRHS()); + CGF.incrementProfileCounter(false, E->getRHS()); CGF.EmitBranch(ContBlock); PN->addIncoming(RHSCond, RHSBlockCnt); + if (HasRHSSkip.second) { + CGF.EmitBlock(RHSTrueBlock); + CGF.incrementProfileCounter(true, E->getRHS()); + CGF.EmitBranch(ContBlock); + ContIncoming = RHSTrueBlock; + } } // Emit an unconditional branch from this block to ContBlock. Insert an entry // into the phi node for the edge with the value of RHSCond. CGF.EmitBlock(ContBlock); - PN->addIncoming(RHSCond, RHSBlock); + PN->addIncoming(RHSCond, ContIncoming); CGF.MCDCLogOpStack.pop_back(); // If the top of the logical operator nest, update the MCDC bitmap. diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index e28048d0ec4d9..ee42560b8870d 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -43,10 +43,6 @@ using namespace CodeGen; // Statement Emission //===----------------------------------------------------------------------===// -namespace llvm { -extern cl::opt EnableSingleByteCoverage; -} // namespace llvm - void CodeGenFunction::EmitStopPoint(const Stmt *S) { if (CGDebugInfo *DI = getDebugInfo()) { SourceLocation Loc; diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index fcd225b0dc7f4..7f3f4bdbdbbc1 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -1762,6 +1762,7 @@ void CodeGenFunction::EmitBranchToCounterBlock( return EmitBranchOnBoolExpr(Cond, TrueBlock, FalseBlock, TrueCount, LH); const Stmt *CntrStmt = (CntrIdx ? CntrIdx : Cond); + auto HasSkip = getIsCounterPair(CntrStmt); llvm::BasicBlock *ThenBlock = nullptr; llvm::BasicBlock *ElseBlock = nullptr; @@ -1770,6 +1771,10 @@ void CodeGenFunction::EmitBranchToCounterBlock( // Create the block we'll use to increment the appropriate counter. llvm::BasicBlock *CounterIncrBlock = createBasicBlock("lop.rhscnt"); + llvm::BasicBlock *SkipIncrBlock = + (HasSkip.second ? createBasicBlock("lop.rhsskip") : nullptr); + llvm::BasicBlock *SkipNextBlock = nullptr; + // Set block pointers according to Logical-AND (BO_LAnd) semantics. This // means we need to evaluate the condition and increment the counter on TRUE: // @@ -1783,8 +1788,9 @@ void CodeGenFunction::EmitBranchToCounterBlock( // goto TrueBlock; if (LOp == BO_LAnd) { + SkipNextBlock = FalseBlock; ThenBlock = CounterIncrBlock; - ElseBlock = FalseBlock; + ElseBlock = (SkipIncrBlock ? SkipIncrBlock : SkipNextBlock); NextBlock = TrueBlock; } @@ -1801,7 +1807,8 @@ void CodeGenFunction::EmitBranchToCounterBlock( // goto FalseBlock; else if (LOp == BO_LOr) { - ThenBlock = TrueBlock; + SkipNextBlock = TrueBlock; + ThenBlock = (SkipIncrBlock ? SkipIncrBlock : SkipNextBlock); ElseBlock = CounterIncrBlock; NextBlock = FalseBlock; } else { @@ -1811,11 +1818,17 @@ void CodeGenFunction::EmitBranchToCounterBlock( // Emit Branch based on condition. EmitBranchOnBoolExpr(Cond, ThenBlock, ElseBlock, TrueCount, LH); + if (SkipIncrBlock) { + EmitBlock(SkipIncrBlock); + incrementProfileCounter(true, CntrStmt); + EmitBranch(SkipNextBlock); + } + // Emit the block containing the counter increment(s). EmitBlock(CounterIncrBlock); // Increment corresponding counter; if index not provided, use Cond as index. - incrementProfileCounter(CntrStmt); + incrementProfileCounter(false, CntrStmt); // Go to the next block. EmitBranch(NextBlock); @@ -1834,6 +1847,8 @@ void CodeGenFunction::EmitBranchOnBoolExpr( Cond = Cond->IgnoreParens(); if (const BinaryOperator *CondBOp = dyn_cast(Cond)) { + auto HasSkip = getIsCounterPair(CondBOp); + // Handle X && Y in a condition. if (CondBOp->getOpcode() == BO_LAnd) { MCDCLogOpStack.push_back(CondBOp); @@ -1865,6 +1880,8 @@ void CodeGenFunction::EmitBranchOnBoolExpr( // Emit the LHS as a conditional. If the LHS conditional is false, we // want to jump to the FalseBlock. llvm::BasicBlock *LHSTrue = createBasicBlock("land.lhs.true"); + llvm::BasicBlock *LHSFalse = + (HasSkip.second ? createBasicBlock("land.lhsskip") : FalseBlock); // The counter tells us how often we evaluate RHS, and all of TrueCount // can be propagated to that branch. uint64_t RHSCount = getProfileCount(CondBOp->getRHS()); @@ -1875,12 +1892,17 @@ void CodeGenFunction::EmitBranchOnBoolExpr( // Propagate the likelihood attribute like __builtin_expect // __builtin_expect(X && Y, 1) -> X and Y are likely // __builtin_expect(X && Y, 0) -> only Y is unlikely - EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, FalseBlock, RHSCount, + EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, LHSFalse, RHSCount, LH == Stmt::LH_Unlikely ? Stmt::LH_None : LH); + if (HasSkip.second) { + EmitBlock(LHSFalse); + incrementProfileCounter(true, CondBOp); + EmitBranch(FalseBlock); + } EmitBlock(LHSTrue); } - incrementProfileCounter(CondBOp); + incrementProfileCounter(false, CondBOp); setCurrentProfileCount(getProfileCount(CondBOp->getRHS())); // Any temporaries created here are conditional. @@ -1920,6 +1942,8 @@ void CodeGenFunction::EmitBranchOnBoolExpr( } // Emit the LHS as a conditional. If the LHS conditional is true, we // want to jump to the TrueBlock. + llvm::BasicBlock *LHSTrue = + (HasSkip.second ? createBasicBlock("lor.lhsskip") : TrueBlock); llvm::BasicBlock *LHSFalse = createBasicBlock("lor.lhs.false"); // We have the count for entry to the RHS and for the whole expression // being true, so we can divy up True count between the short circuit and @@ -1934,12 +1958,17 @@ void CodeGenFunction::EmitBranchOnBoolExpr( // __builtin_expect(X || Y, 1) -> only Y is likely // __builtin_expect(X || Y, 0) -> both X and Y are unlikely ApplyDebugLocation DL(*this, Cond); - EmitBranchOnBoolExpr(CondBOp->getLHS(), TrueBlock, LHSFalse, LHSCount, + EmitBranchOnBoolExpr(CondBOp->getLHS(), LHSTrue, LHSFalse, LHSCount, LH == Stmt::LH_Likely ? Stmt::LH_None : LH); + if (HasSkip.second) { + EmitBlock(LHSTrue); + incrementProfileCounter(true, CondBOp); + EmitBranch(TrueBlock); + } EmitBlock(LHSFalse); } - incrementProfileCounter(CondBOp); + incrementProfileCounter(false, CondBOp); setCurrentProfileCount(getProfileCount(CondBOp->getRHS())); // Any temporaries created here are conditional. diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 6abf0b333b246..9179410c70621 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -2185,9 +2185,6 @@ struct CounterCoverageMappingBuilder extendRegion(E->getRHS()); propagateCounts(getRegionCounter(E), E->getRHS()); - if (llvm::EnableSingleByteCoverage) - return; - // Track RHS True/False Decision. const auto DecisionRHS = MCDCBuilder.back(); @@ -2246,9 +2243,6 @@ struct CounterCoverageMappingBuilder extendRegion(E->getRHS()); propagateCounts(getRegionCounter(E), E->getRHS()); - if (llvm::EnableSingleByteCoverage) - return; - // Track RHS True/False Decision. const auto DecisionRHS = MCDCBuilder.back(); From 03cfce188cb45adbe78f7e77c2fdd244650f5a3c Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 23 Oct 2024 14:39:35 +0000 Subject: [PATCH 18/79] CGF::markStmtAsUsed --- clang/lib/CodeGen/CodeGenFunction.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 89ac3b342d0a7..fcad1cbcae5e3 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1624,6 +1624,9 @@ class CodeGenFunction : public CodeGenTypeCache { return PGO.getIsCounterPair(S); } + void markStmtAsUsed(bool Skipped, const Stmt *S) { + PGO.markStmtAsUsed(Skipped, S); + } void markStmtMaybeUsed(const Stmt *S) { PGO.markStmtMaybeUsed(S); } /// Increment the profiler's counter for the given statement by \p StepV. From afc8481f7cf20da7de4e95a60bf3ccdb04bd08f3 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 23 Oct 2024 14:39:35 +0000 Subject: [PATCH 19/79] CGF.markStmtMaybeUsed for binop --- clang/lib/CodeGen/CGExprScalar.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 74e93f889f426..9e8533ca90a5c 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -4970,7 +4970,8 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { CGF.incrementProfileCounter(E->getRHS()); CGF.EmitBranch(FBlock); CGF.EmitBlock(FBlock); - } + } else + CGF.markStmtMaybeUsed(E->getRHS()); CGF.MCDCLogOpStack.pop_back(); // If the top of the logical operator nest, update the MCDC bitmap. @@ -5112,7 +5113,8 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { CGF.incrementProfileCounter(E->getRHS()); CGF.EmitBranch(FBlock); CGF.EmitBlock(FBlock); - } + } else + CGF.markStmtMaybeUsed(E->getRHS()); CGF.MCDCLogOpStack.pop_back(); // If the top of the logical operator nest, update the MCDC bitmap. From ad997c2f539ab2622e61c106bb3d646930777712 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 23 Oct 2024 14:39:35 +0000 Subject: [PATCH 20/79] Fix cases when LHS is skipped --- clang/lib/CodeGen/CGExprScalar.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index de85d4ad63833..fd67622fe8154 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -4949,7 +4949,7 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { bool LHSCondVal; if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) { if (LHSCondVal) { // If we have 1 && X, just emit X. - CGF.incrementProfileCounter(E); + CGF.incrementProfileCounter(false, E, true); // If the top of the logical operator nest, reset the MCDC temp to 0. if (CGF.MCDCLogOpStack.empty()) @@ -4993,7 +4993,12 @@ Value *ScalarExprEmitter::VisitBinLAnd(const BinaryOperator *E) { // 0 && RHS: If it is safe, just elide the RHS, and return 0/false. if (!CGF.ContainsLabel(E->getRHS())) { + CGF.markStmtAsUsed(false, E); + if (HasLHSSkip.second) + CGF.incrementProfileCounter(true, E); + CGF.markStmtMaybeUsed(E->getRHS()); + return llvm::Constant::getNullValue(ResTy); } } @@ -5119,7 +5124,7 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { bool LHSCondVal; if (CGF.ConstantFoldsToSimpleInteger(E->getLHS(), LHSCondVal)) { if (!LHSCondVal) { // If we have 0 || X, just emit X. - CGF.incrementProfileCounter(false, E); + CGF.incrementProfileCounter(false, E, true); // If the top of the logical operator nest, reset the MCDC temp to 0. if (CGF.MCDCLogOpStack.empty()) @@ -5163,7 +5168,12 @@ Value *ScalarExprEmitter::VisitBinLOr(const BinaryOperator *E) { // 1 || RHS: If it is safe, just elide the RHS, and return 1/true. if (!CGF.ContainsLabel(E->getRHS())) { + CGF.markStmtAsUsed(false, E); + if (HasLHSSkip.second) + CGF.incrementProfileCounter(true, E); + CGF.markStmtMaybeUsed(E->getRHS()); + return llvm::ConstantInt::get(ResTy, 1); } } From ab84f17fc181cb4b38693dc6ea80ac44f44bf990 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 27 Oct 2024 20:28:26 +0900 Subject: [PATCH 21/79] Introduce skeleton getSwitchImplicitDefaultCounter() --- clang/lib/CodeGen/CoverageMappingGen.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 1782434bdb9aa..532f6e8ba1820 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -947,6 +947,11 @@ struct CounterCoverageMappingBuilder return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; } + Counter getSwitchImplicitDefaultCounter(const Stmt *Cond, Counter ParentCount, + Counter CaseCountSum) { + return Builder.subtract(ParentCount, CaseCountSum); + } + bool IsCounterEqual(Counter OutCount, Counter ParentCount) { if (OutCount == ParentCount) return true; @@ -1903,7 +1908,8 @@ struct CounterCoverageMappingBuilder // the hidden branch, which will be added later by the CodeGen. This region // will be associated with the switch statement's condition. if (!HasDefaultCase) { - Counter DefaultCount = subtractCounters(ParentCount, CaseCountSum); + Counter DefaultCount = getSwitchImplicitDefaultCounter( + S->getCond(), ParentCount, CaseCountSum); createBranchRegion(S->getCond(), Counter::getZero(), DefaultCount); } } From a4608854e1b727817db3cc01234f97e78285f8c7 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 27 Oct 2024 20:40:44 +0900 Subject: [PATCH 22/79] Update getSwitchImplicitDefaultCounter --- clang/lib/CodeGen/CoverageMappingGen.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index d4a1b2613eab9..cb861e61d3272 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -960,7 +960,10 @@ struct CounterCoverageMappingBuilder Counter getSwitchImplicitDefaultCounter(const Stmt *Cond, Counter ParentCount, Counter CaseCountSum) { - return Builder.subtract(ParentCount, CaseCountSum); + return ( + llvm::EnableSingleByteCoverage + ? Counter::getCounter(CounterMap[Cond].second = NextCounterNum++) + : Builder.subtract(ParentCount, CaseCountSum)); } bool IsCounterEqual(Counter OutCount, Counter ParentCount) { From 02853943407a5c550554e4920586b8724dd63a76 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 28 Oct 2024 00:55:49 +0900 Subject: [PATCH 23/79] Don't allocate second if SkipExpr isn't Expr. --- clang/lib/CodeGen/CoverageMappingGen.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index cb861e61d3272..8584f58548eae 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -946,8 +946,12 @@ struct CounterCoverageMappingBuilder auto ExecCnt = Counter::getCounter(TheMap.first); auto SkipExpr = Builder.subtract(ParentCnt, ExecCnt); - if (!llvm::EnableSingleByteCoverage) + if (!llvm::EnableSingleByteCoverage || !SkipExpr.isExpression()) { + assert( + !TheMap.getIsCounterPair().second && + "SkipCnt shouldn't be allocated but refer to an existing counter."); return {ExecCnt, SkipExpr}; + } // Assign second if second is not assigned yet. if (!TheMap.getIsCounterPair().second) From 2842382fd41b6175502b72ae651829bbeaefa5b2 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 28 Oct 2024 02:26:36 +0900 Subject: [PATCH 24/79] update --- clang/test/CoverageMapping/single-byte-counters.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp index 401b5d7dd8b84..74aab4fc31f3d 100644 --- a/clang/test/CoverageMapping/single-byte-counters.cpp +++ b/clang/test/CoverageMapping/single-byte-counters.cpp @@ -58,7 +58,7 @@ int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+12]]:2 = int i = 0; int sum = 0; while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = ([[C40]] + [[C4T:#1]]) - // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:10 -> [[@LINE-1]]:16 = [[C4T]], [[C4F:#2]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:10 -> [[@LINE-1]]:16 = [[C4T]], [[C4F:#0]] // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:17 -> [[@LINE-2]]:18 = [[C4T]] // CHECK-NEXT: File 0, [[@LINE-3]]:18 -> [[@LINE+3]]:4 = [[C4T]] sum += i; @@ -92,7 +92,7 @@ int testFor() { // CHECK-NEXT: File 0, [[@LINE]]:15 -> [[@LINE+13]]:2 = [[C60:#0 int i; int sum = 0; // CHECK-NEXT: File 0, [[@LINE+3]]:19 -> [[@LINE+3]]:25 = ([[C60]] + [[C6B:#1]]) - // CHECK-NEXT: Branch,File 0, [[@LINE+2]]:19 -> [[@LINE+2]]:25 = [[C6B]], [[C6E:#2]] + // CHECK-NEXT: Branch,File 0, [[@LINE+2]]:19 -> [[@LINE+2]]:25 = [[C6B]], [[C6E:#0]] // CHECK-NEXT: File 0, [[@LINE+1]]:27 -> [[@LINE+1]]:30 = [[C6B]] for (int i = 0; i < 10; i++) { // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:31 -> [[@LINE-1]]:32 = [[C6B]] @@ -108,7 +108,7 @@ int testForRange() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+12]]:2 = int sum = 0; int array[] = {1, 2, 3, 4, 5}; - // CHECK-NEXT: Branch,File 0, [[@LINE+1]]:20 -> [[@LINE+1]]:21 = [[C7B:#1]], [[C7E:#2]] + // CHECK-NEXT: Branch,File 0, [[@LINE+1]]:20 -> [[@LINE+1]]:21 = [[C7B:#1]], [[C7E:#0]] for (int element : array) { // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:28 -> [[@LINE-1]]:29 = [[C7B]] // CHECK-NEXT: File 0, [[@LINE-2]]:29 -> [[@LINE+2]]:4 = [[C7B]] @@ -126,7 +126,7 @@ int testDo() { // CHECK-NEXT: File 0, [[@LINE]]:14 -> [[@LINE+10]]:2 = sum += i; i++; } while (i < 5); // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE]]:17 = ([[C80]] + [[C8B]]) - // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:12 -> [[@LINE-1]]:17 = [[C8B]], [[C8E:#2]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:12 -> [[@LINE-1]]:17 = [[C8B]], [[C8E:#0]] return sum; // #0 } From 49e139ec5ac2b79baf27ac756bf0bf24bf053ae7 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 28 Oct 2024 07:24:19 +0900 Subject: [PATCH 25/79] Suppress StepV in EnableSingleByteCoverage --- clang/lib/CodeGen/CGExprScalar.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 11d4ec8a26760..7d858e1d404c8 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -55,6 +55,10 @@ using llvm::Value; // Scalar Expression Emitter //===----------------------------------------------------------------------===// +namespace llvm { +extern cl::opt EnableSingleByteCoverage; +} // namespace llvm + namespace { /// Determine whether the given binary operation may overflow. @@ -5318,7 +5322,7 @@ VisitAbstractConditionalOperator(const AbstractConditionalOperator *E) { // If this is a really simple expression (like x ? 4 : 5), emit this as a // select instead of as control flow. We can only do this if it is cheap and // safe to evaluate the LHS and RHS unconditionally. - if (!CGF.getIsCounterPair(E).second && + if (!llvm::EnableSingleByteCoverage && isCheapEnoughToEvaluateUnconditionally(lhsExpr, CGF) && isCheapEnoughToEvaluateUnconditionally(rhsExpr, CGF)) { llvm::Value *CondV = CGF.EvaluateExprAsBool(condExpr); From 1f35324eb57614da5420943b96b5b63f11637294 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 28 Oct 2024 07:44:46 +0900 Subject: [PATCH 26/79] assert(!StepV) --- clang/lib/CodeGen/CodeGenPGO.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 69f6629097984..b4edc72ce75aa 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -1229,10 +1229,11 @@ void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, NormalizedFuncNameVarPtr, Builder.getInt64(FunctionHash), Builder.getInt32(NumRegionCounters), Builder.getInt32(Counter), StepV}; - if (llvm::EnableSingleByteCoverage) + if (llvm::EnableSingleByteCoverage) { + assert(!StepV && "StepV is impossible in SingleByte"); Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_cover), ArrayRef(Args, 4)); - else if (!StepV) + } else if (!StepV) Builder.CreateCall(CGM.getIntrinsic(llvm::Intrinsic::instrprof_increment), ArrayRef(Args, 4)); else From 97a4a8f40afb53250639c29e193edd814cb82f58 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 20 Nov 2024 23:33:51 +0900 Subject: [PATCH 27/79] 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 28/79] 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 29/79] 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 30/79] 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 8a3ef7cedec7726feca2ea922a3f1faa86d496c5 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 20 Nov 2024 23:59:37 +0900 Subject: [PATCH 31/79] Update single tests --- .../Inputs/branch-c-general-single.proftext | 71 ++++--------------- .../Inputs/branch-c-general-single.yaml | 40 +++++------ .../tools/llvm-cov/Inputs/branch-c-general.c | 30 ++++---- .../showLineExecutionCounts-single.proftext | 5 +- .../showLineExecutionCounts-single.yaml | 4 +- 5 files changed, 53 insertions(+), 97 deletions(-) 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 index ea8c6f9bc634e..580a691c46b4e 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext @@ -4,15 +4,12 @@ big_switch # Func Hash: 13144136522122330070 # Num Counters: -27 +25 # Counter Values: 1 1 1 1 -1 -1 -1 0 1 1 @@ -33,12 +30,13 @@ big_switch 1 1 1 +1 boolean_operators # Func Hash: 1245693242827665 # Num Counters: -17 +14 # Counter Values: 1 1 @@ -54,35 +52,22 @@ boolean_operators 1 1 1 -1 -1 -1 boolop_loops # Func Hash: 12402604614320574815 # Num Counters: -23 +13 # Counter Values: 1 -0 -1 -1 -1 -1 -0 -1 1 1 1 -0 1 1 1 1 1 -0 -1 1 1 1 @@ -92,13 +77,10 @@ branch-c-general.c:static_func # Func Hash: 18129 # Num Counters: -5 +2 # Counter Values: 1 1 -1 -1 -1 conditional_operator # Func Hash: @@ -116,14 +98,11 @@ conditionals # Func Hash: 4904767535850050386 # Num Counters: -25 +22 # Counter Values: 1 1 1 -1 -1 -1 0 1 1 @@ -148,7 +127,7 @@ do_fallthrough # Func Hash: 8714614136504380050 # Num Counters: -10 +7 # Counter Values: 1 1 @@ -157,15 +136,12 @@ do_fallthrough 1 1 1 -1 -1 -1 early_exits # Func Hash: 2880354649761471549 # Num Counters: -20 +18 # Counter Values: 1 0 @@ -182,9 +158,7 @@ early_exits 1 1 0 -1 -1 -1 +0 0 0 @@ -192,22 +166,17 @@ jumps # Func Hash: 15051420506203462683 # Num Counters: -38 +32 # Counter Values: 1 1 0 -1 -0 -0 0 1 0 1 -1 0 1 -1 0 1 1 @@ -215,20 +184,19 @@ jumps 1 1 1 -1 0 1 -1 0 1 1 1 1 +0 +0 1 1 1 0 -0 1 1 1 @@ -245,25 +213,18 @@ simple_loops # Func Hash: 1245818015463121 # Num Counters: -11 +4 # Counter Values: 1 1 1 1 -1 -1 -1 -1 -1 -1 -1 switches # Func Hash: 43242458792028222 # Num Counters: -29 +27 # Counter Values: 1 1 @@ -274,9 +235,6 @@ switches 0 1 1 -0 -1 -1 1 1 1 @@ -294,4 +252,5 @@ switches 1 0 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 index 9d23dcb67ad2a..e1803ca67fa45 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml @@ -11,42 +11,42 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: D7878914FBE99B074D000000D136449C106D04004C551E9517F40F4F0101000D010715080205020F0016090018001B0D001C009D808080080D001D0104110203040215000A000F19001001858080800819010500081D01030202210006000825001000181001010001 + Content: D7878914FBE99B0760000000D136449C106D04004C551E9517F40F4F01010401050109010D010D0E010715080203020F0016200501000F0016050018001B05001C009D8080800805001D010407020A000F200901000A000F09001001858080800809010500080F010600080F00100018200D01001000181001010001 - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 83AD05A5F1438E68EA00000052D33558163C11444C551E9517F40F4F010100260111150E02050113001A09001C001F0D002000A1808080080D00210B040D0109000E15000F009080808008150010020615010B000C21000D008E8080800821000E0010310106008C8080800831000C04063100100015290016009780808008290017020629010B000C35000D008E8080800835000E00102D0106008C808080082D000C02062D010B000C3D000D008E808080083D000E0010100201005B1D010502041D0009000A1D0009000F4D000E000F45001000918080800845001100134901050104490009000A490009000F5D000E000F55001000918080800855001100131002010001 + Content: 83AD05A5F1438E68F300000052D33558163C11444C551E9517F40F4F010101014D270111150E02030113001A2005550013001A4D001C001F05002000A1808080080500210B04050109000E09000F009080808008090010020609010B000C15000D008E8080800815000E0010250106008C8080800825000C040625001000151D00160097808080081D001702061D010B000C29000D008E8080800829000E0010210106008C8080800821000C020621010B000C31000D008E8080800831000E0010100201005B1101050204110009000A110009000F41000E000F39001000918080800839001100133D010501043D0009000A3D0009000F51000E000F49001000918080800849001100131002010001 - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 0449C70428C57369F80000003D5C2D0E4B13F9274C551E9517F40F4F01010028012114180210020100010101070008050009008A8080800805000A000C100101000109010313020D000A00111100120093808080081100130604110209000F190010018780808008190107000C1D000D0185808080081D010502041D0009000E21000F018780808008210107000F15010402838080800810010100011501030B021500070008290009008A8080800829000A000C10010100012D010309023100060504310109000F3D00100187808080083D0107000D41000E028780808008410207000A35010C0013390015028380808008100101000139010302023900070008490009008A8080800849000A000C1001010001 + Content: 0449C70428C57369140100003D5C2D0E4B13F9274C551E9517F40F4F010107071D0919114111411141252925292A012114180210020100010101070008050009008A8080800805000A000C1001010001090103130203000A0011200D41000A00110D00120093808080080D001306040D0209000F110010018780808008110107000C15000D0185808080081501050204150009000E19000F018780808008190107000F13010402838080800810010100011301030B021300070008210009008A8080800821000A000C100101000125010309021B000605041B0109000F2D00100187808080082D0107000D31000E028780808008310207000A35010C0013202945000C0013450015028380808008100101000145010302024500070008390009008A8080800839000A000C1001010001 - Name: '__llvm_covfun (3)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 55947829059F255EB80100001B9C495D3463E1D04C551E9517F40F4F01010046013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A15000B008C8080800815000C000E11010402818080800810010100011D010126021D01070008210009008A8080800821000A000C1001010001250103000D25000E0283808080081001010001000103210229000A000B2D000C008D808080082D000D03043501030204350109000A39000B008C8080800839000C000E1002010001310103000D31000E0181808080084101011B024501011A024901011902490207000C4D000D0185808080084D0105000F5100100283808080081001010001510103140255000A000F5900100091808080085900110A04610103090400011006918080800869010501110001120185808080086D0105011200011301858080800871010501115D030402838080800810010100015D0103080275000F0015790017001A7D001B009C808080087D001C0604000115028580808008100101003F0001050304000009000A8501000B008C808080088501000C000E8D01010302048D010109000A9101000B008C808080089101000C000E1002010001 + Content: 55947829059F255ED40100001B9C495D3463E1D04C551E9517F40F4F010103010D3D496D794A013B0E2F02100201000103010F0014200571000F00140D0016001905001A009B8080800805001B040400011402858080800810010100230001050104000009000A09000B008C8080800809000C000E710104028180808008100101000111010126021101070008150009008A8080800815000A000C1001010001190103000D19000E0283808080081001010001000103210229000A000B201D75000A000B1D000C008D808080081D000D03042101030204210109000A25000B008C8080800825000C000E1002010001750103000D75000E0181808080082D01011B023101011A023501011902350207000C39000D018580808008390105000F3D001002838080800810010100013D0103140207000A000F204179000A000F4100100091808080084100110A0445010309040001100691808080084D0105011100011201858080800851010501120001130185808080085501050111790304028380808008100101000179010308020B000F001520597D000F00156D0017001A59001B009C8080800859001C0604000115028580808008100101003F0001050304000009000A5D000B008C808080085D000C000E6501030204650109000A69000B008C8080800869000C000E1002010001 - Name: '__llvm_covfun (4)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 7129CA3C268292BF4D0100003E688383C9A099004C551E9517F40F4F01010035016C112502100201011C000217028A80808008090103010A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F21010B000C25000D008E8080800825000E001010010100152D0105100F2D010B000C31000D008E8080800831000E0010350107000C35000D0185808080083901050D0F39010B000C3D000D008E808080083D000E0010410107000F4100100185808080084501050A0F45010B000C49000D008E8080800849000E00104D0107080F000012039180808008550107021155010D000E59000F00908080800859001000125D010900115101080285808080081001010001610105020F61010B0017650018018980808008650109000F1902040383808080081001010121190203020219000700116D00120093808080086D001300151001010001 + Content: 7129CA3C268292BF560100003E688383C9A099004C551E9517F40F4F010101051136016C112502100201011C000217028A80808008090103010A05020402838080800810010100620501031C0203003F0046200D69003F0046110048004B0D004C00CD808080080D004D1704000119148F80808008150105130F15010B000C19000D008E8080800819000E00101001010015210105100F21010B000C25000D008E8080800825000E0010290107000C29000D0185808080082D01050D0F2D010B000C31000D008E8080800831000E0010350107000F3500100185808080083901050A0F39010B000C3D000D008E808080083D000E0010410107080F000012039180808008490107021149010D000E4D000F0090808080084D0010001251010900114501080285808080081001010001550105020F55010B0017590018018980808008590109000F69020403838080800810010101216902030202690007001161001200938080800861001300151001010001 - Name: '__llvm_covfun (5)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 3F4D1C6E6087417B32010000D6FF56B8865A69B64C551E9517F40F4F01010031019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C19010B000C1D000D008E808080081D000E00101001010015250105150C25010B000C29000D008E8080800829000E00102D0107000C2D000D018580808008310105120C31010B000C35000D008E8080800835000E0010390107000C39000D03858080800810010101013D02050D0C3D010B000C41000D008E8080800841000E0010450107000C45000D0185808080084901050A0C49010B000C4D000D008E808080084D000E0010510107000C51000D0385808080081001010101550205050C55010B000C59000D008E8080800859000E00105D0107000C5D000D018580808008610105020C61010B000C65000D008E8080800865000E0010690107000C1003010001 + Content: 3F4D1C6E6087417B3B010000D6FF56B8865A69B64C551E9517F40F4F010101010932019301131F0203011300192005610013001909001B001E05001F00A0808080080500201C04000115198C808080080D0105180C0D010B000C11000D008E8080800811000E00101001010015190105150C19010B000C1D000D008E808080081D000E0010210107000C21000D018580808008250105120C25010B000C29000D008E8080800829000E00102D0107000C2D000D03858080800810010101013102050D0C31010B000C35000D008E8080800835000E0010390107000C39000D0185808080083D01050A0C3D010B000C41000D008E8080800841000E0010450107000C45000D0385808080081001010101490205050C49010B000C4D000D008E808080084D000E0010510107000C51000D018580808008550105020C55010B000C59000D008E8080800859000E00105D0107000C1003010001 - Name: '__llvm_covfun (6)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 59A48AA8899AA3587200000091E33C8FF36C04004C551E9517F40F4F0101001501B4011A0C02050213001A09001C001F0D002000A1808080080D002108040D0109000E1500120013100101005D0D0109000E1D00120013100101005D0D0109000E0D000900172D0012001725001B001C10010100630D0109000E0D000900173D0012001735001B001C1002010063 + Content: 59A48AA8899AA3587B00000091E33C8FF36C04004C551E9517F40F4F01010101051601B4011A0C02030213001A2005010013001A05001C001F05002000A1808080080500210804050109000E0900120013100101005D050109000E1100120013100101005D050109000E0500090017210012001719001B001C1001010063050109000E0500090017310012001729001B001C1002010063 - Name: '__llvm_covfun (7)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: F5953D044B505D139E0000005FD132562FE71EAC4C551E9517F40F4F0101001D01C201150D02100201000111010A000B11000A001511000F0015090016018580808008090105000810010100010D0103070225000A001125000A001C250015001C1D001D0185808080081D01050008100101000121010304023D001100123D0011001C3D0016001C31001E002135002200231001010061390103020255000A001155000A001C550015001C49001E00214D002200231001010061 + Content: F5953D044B505D139D0000005FD132562FE71EAC4C551E9517F40F4F010107010501110111011D011D012901291A01C201150D02100201000103010A000B03000A001509000F0015050016018580808008050105000810010100010B010A00110B000A001C150015001C11001D018580808008110105000810010100011301110012130011001C210016001C1D001E00211D0022002310010100611B010A00111B000A001C2D0015001C29001E002129002200231001010061 - Name: '__llvm_covfun (8)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -56,7 +56,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 7DE8E7C47096EB425200000092EAF0986287F0784C551E9517F40F4F0101000D01DA01170B02050113001909001B001E0D001F00A0808080080D002009041502080606100101024D15030B00102100110092808080082100120017250018018780808008250107010619010E0013 + Content: 7DE8E7C47096EB426A00000092EAF0986287F0784C551E9517F40F4F0101050715010D0D15050905090F01DA01170B020301130019200519001300190B001B001E05001F00A08080800805002009041302080606100101024D13030B00100D00110092808080080D00120017110018018780808008110107010611010E0013200915000E0013 - Name: '__llvm_covfun (10)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -66,7 +66,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 4CB4F49D6737EBF922000000D1460000000000004C551E9517F40F4F0101000501E7011B0302050113001909001B001E0D001F00A0808080080D00200104 + Content: 4CB4F49D6737EBF92B000000D1460000000000004C551E9517F40F4F01010101050601E7011B030203011300192005010013001905001B001E05001F00A0808080080500200104 - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -106,49 +106,49 @@ Symbols: Type: STT_OBJECT Section: __llvm_covfun Binding: STB_WEAK - Size: 0x69 + Size: 0x7C Other: [ STV_HIDDEN ] - Name: __covrec_688E43F1A505AD83u Type: STT_OBJECT Section: '__llvm_covfun (1)' Binding: STB_WEAK - Size: 0x106 + Size: 0x10F Other: [ STV_HIDDEN ] - Name: __covrec_6973C52804C74904u Type: STT_OBJECT Section: '__llvm_covfun (2)' Binding: STB_WEAK - Size: 0x114 + Size: 0x130 Other: [ STV_HIDDEN ] - Name: __covrec_5E259F0529789455u Type: STT_OBJECT Section: '__llvm_covfun (3)' Binding: STB_WEAK - Size: 0x1D4 + Size: 0x1F0 Other: [ STV_HIDDEN ] - Name: __covrec_BF9282263CCA2971u Type: STT_OBJECT Section: '__llvm_covfun (4)' Binding: STB_WEAK - Size: 0x169 + Size: 0x172 Other: [ STV_HIDDEN ] - Name: __covrec_7B4187606E1C4D3Fu Type: STT_OBJECT Section: '__llvm_covfun (5)' Binding: STB_WEAK - Size: 0x14E + Size: 0x157 Other: [ STV_HIDDEN ] - Name: __covrec_58A39A89A88AA459u Type: STT_OBJECT Section: '__llvm_covfun (6)' Binding: STB_WEAK - Size: 0x8E + Size: 0x97 Other: [ STV_HIDDEN ] - Name: __covrec_135D504B043D95F5u Type: STT_OBJECT Section: '__llvm_covfun (7)' Binding: STB_WEAK - Size: 0xBA + Size: 0xB9 Other: [ STV_HIDDEN ] - Name: __covrec_795CF1BD69C3E520u Type: STT_OBJECT @@ -160,7 +160,7 @@ Symbols: Type: STT_OBJECT Section: '__llvm_covfun (9)' Binding: STB_WEAK - Size: 0x6E + Size: 0x86 Other: [ STV_HIDDEN ] - Name: __covrec_DB956436E78DD5FAu Type: STT_OBJECT @@ -172,6 +172,6 @@ Symbols: Type: STT_OBJECT Section: '__llvm_covfun (11)' Binding: STB_WEAK - Size: 0x3E + Size: 0x47 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 5ea9ecb42b0ed..21c48d48e50da 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c @@ -6,16 +6,16 @@ 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) { // CHECK: Branch ([[@LINE]]:15): [True: [[C100:100|1]], False: 1] } - while (i > 0) // BRCOV: Branch ([[@LINE]]:10): [True: [[C100]], False: 1] + while (i > 0) // CHECK: Branch ([[@LINE]]:10): [True: [[C100]], False: 1] i--; - do {} while (i++ < 75); // BRCOV: Branch ([[@LINE]]:16): [True: [[C75:75|1]], False: 1] + do {} while (i++ < 75); // CHECK: Branch ([[@LINE]]:16): [True: [[C75:75|1]], False: 1] } void conditionals() { // CHECK: @LINE|{{.*}}conditionals() - for (int i = 0; i < 100; ++i) {//BRCOV: Branch ([[@LINE]]:19): [True: [[C100]], False: 1] + for (int i = 0; i < 100; ++i) {//CHECK: 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]]] @@ -35,7 +35,7 @@ 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) { // CHECK: Branch ([[@LINE]]:10): [True: [[C51:51|1]], False: 0] i++; if (i > 50) // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[C50]]] break; @@ -50,7 +50,7 @@ void early_exits() { // CHECK: @LINE|{{.*}}early_exits() return; else i++; - } while (i < 100); // BRCOV: Branch ([[@LINE]]:12): [True: [[C25]], False: 0] + } while (i < 100); // CHECK: Branch ([[@LINE]]:12): [True: [[C25:25|1]], False: 0] if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 0] @@ -59,7 +59,7 @@ void early_exits() { // CHECK: @LINE|{{.*}}early_exits() void jumps() { // CHECK: @LINE|{{.*}}jumps() int i; - for (i = 0; i < 2; ++i) { // BRCOV: Branch ([[@LINE]]:15): [True: 1, False: 0] + for (i = 0; i < 2; ++i) { // CHECK: Branch ([[@LINE]]:15): [True: 1, False: 0] goto outofloop; // Never reached -> no weights if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 0] @@ -70,7 +70,7 @@ void jumps() { // CHECK: @LINE|{{.*}}jumps() goto loop1; - while (i) { // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1] + while (i) { // CHECK: Branch ([[@LINE]]:10): [True: 0, False: 1] loop1: if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 1] } @@ -83,7 +83,7 @@ void jumps() { // CHECK: @LINE|{{.*}}jumps() if (i < 3) // BRCOV: Branch ([[@LINE]]:7): [True: [[C2:2|1]], False: 1] goto loop2; - while (i < 3) { // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1] + while (i < 3) { // CHECK: Branch ([[@LINE]]:10): [True: 0, False: 1] loop2: switch (i) { case 0: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] @@ -95,7 +95,7 @@ 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) { // CHECK: Branch ([[@LINE]]:15): [True: [[C10:10|1]], False: 1] goto withinloop; // never reached -> no weights if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 0] @@ -113,7 +113,7 @@ 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] + // CHECK: 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: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] @@ -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) {// CHECK: Branch ([[@LINE]]:19): [True: [[C32:32|1]], 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] @@ -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) {// CHECK: 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() { // 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); // CHECK: Branch ([[@LINE]]:14): [True: [[C2:2|1]], False: [[C2]]] } } 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) {// CHECK: Branch ([[@LINE]]:19): [True: [[C10]], False: 1] } } diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext index 1b7b949de4962..6cb6185b8a45e 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext @@ -4,7 +4,7 @@ main # Func Hash: 15239891155360101223 # Num Counters: -14 +11 # Counter Values: 161 0 @@ -13,9 +13,6 @@ main 161 161 161 -161 -161 -161 0 161 0 diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml index 84b184023f082..927f7289ba132 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml @@ -11,7 +11,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: FAD58DE7366495DB9A0000006733DBEA42F87ED3C60E0B951FF3509D0101001A01060C130210020100010101070008050009008A8080800805000A0204090204008A8080800809000A020410030100010D01030A02110013001A15001C001F19002000A180808008190021020410030100011D010306021D0007000D25000F0090808080082500100015290018001D2101030502210007000D31000F018980808008310109000E350109000E10010100012D0103000B + Content: FAD58DE7366495DB9E0000006733DBEA42F87ED3C60E0B951FF3509D0101010D111A01060C130210020100010101070008050009008A8080800805000A0204090204008A8080800809000A020410030100010D01030A02030013001A20110D0013001A11001C001F11002000A180808008110021020410030100010D0107000D19000F00908080800819001000151D0018001D1501030502150007000D25000F018980808008250109000E290109000E1001010001210103000B - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -40,6 +40,6 @@ Symbols: Type: STT_OBJECT Section: __llvm_covfun Binding: STB_WEAK - Size: 0xB6 + Size: 0xBA Other: [ STV_HIDDEN ] ... From 273646016fcb5e06ec13068eded8a25740795013 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 21 Nov 2024 00:05:54 +0900 Subject: [PATCH 32/79] Update single tests --- .../tools/llvm-cov/Inputs/branch-c-general-single.proftext | 2 +- llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml | 4 ++-- llvm/test/tools/llvm-cov/Inputs/branch-c-general.c | 4 ++-- .../test/tools/llvm-cov/Inputs/branch-macros-single.proftext | 5 ++--- llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml | 2 +- .../llvm-cov/Inputs/showLineExecutionCounts-single.proftext | 4 +--- .../llvm-cov/Inputs/showLineExecutionCounts-single.yaml | 4 ++-- 7 files changed, 11 insertions(+), 14 deletions(-) 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 index ea8c6f9bc634e..d7e78369c4504 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext @@ -107,10 +107,10 @@ conditional_operator 5 # Counter Values: 1 -1 0 1 1 +0 conditionals # Func Hash: 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 index 9d23dcb67ad2a..60de270939725 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml @@ -51,7 +51,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 20E5C369BDF15C7940000000D0D60000000000004C551E9517F40F4F0101000B01D1011D0702100201000101010B001109001300948080800809001400150D001800191001010001050103020205000B000C01001000111001010001 + Content: 20E5C369BDF15C7949000000D0D60000000000004C551E9517F40F4F0101000C01D1011D0702100201000101010B001120050D000B001105001300948080800805001400150D00180019100101000101010B000C200911000B000C11001000111001010001 - Name: '__llvm_covfun (9)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -154,7 +154,7 @@ Symbols: Type: STT_OBJECT Section: '__llvm_covfun (8)' Binding: STB_WEAK - Size: 0x5C + Size: 0x65 Other: [ STV_HIDDEN ] - Name: __covrec_42EB9670C4E7E87Du Type: STT_OBJECT 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..1d4560b5e1026 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c @@ -209,9 +209,9 @@ void boolop_loops() { // CHECK: @LINE|{{.*}}boolop_loops() void conditional_operator() { // CHECK: @LINE|{{.*}}conditional_operator() int i = 100; - int j = i < 50 ? i : 1; // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1] + int j = i < 50 ? i : 1; // CHECK: Branch ([[@LINE]]:11): [True: 0, False: 1] - int k = i ?: 0; // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 0] + int k = i ?: 0; // CHECK: Branch ([[@LINE]]:11): [True: 1, False: 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 index afb4b1038d3f8..29dc4ef3bf5c2 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.proftext @@ -30,18 +30,17 @@ _Z5func2ii # Func Hash: 14151920320560143107 # Num Counters: -10 +9 # Counter Values: 3 3 2 1 0 -3 0 -3 1 0 +3 main # Func Hash: diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml index 5c5f62b11863b..7545e311af7ab 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml @@ -16,7 +16,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: B01D983FC67363959E000000039B9E2C8DB865C493E696313ECE8F5D0D01010101010101010101010101000401241A07020C010E0014140018001D1001010365011C0B1000160405080F002624001000152C0018001D3400200025013C0A1000160305070F001F44001000154C0019001E0119060F0017011D050F00170154091000150205050F001705000F00170121060F00170401070F001F01000F001F5C00100015640019001E0201050F001701000F0017010D060F0017 + Content: B01D983FC67363959E000000039B9E2C8DB865C493E696313ECE8F5D0D01010101010101010101010101000401241A07020C010E0014140018001D1001010365011C0B1000160405080F002624001000152C0018001D3400200025013C0A1000160305070F001F44001000154C0019001E0115060F00170121050F00170154091000150205050F001705000F00170119060F00170401070F001F01000F001F5C00100015640019001E0201050F001701000F0017010D060F0017 - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext index 1b7b949de4962..d8af6ef7fc615 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext @@ -4,7 +4,7 @@ main # Func Hash: 15239891155360101223 # Num Counters: -14 +12 # Counter Values: 161 0 @@ -15,9 +15,7 @@ main 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 index 84b184023f082..a836189245273 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml @@ -11,7 +11,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: FAD58DE7366495DB9A0000006733DBEA42F87ED3C60E0B951FF3509D0101001A01060C130210020100010101070008050009008A8080800805000A0204090204008A8080800809000A020410030100010D01030A02110013001A15001C001F19002000A180808008190021020410030100011D010306021D0007000D25000F0090808080082500100015290018001D2101030502210007000D31000F018980808008310109000E350109000E10010100012D0103000B + Content: FAD58DE7366495DB9E0000006733DBEA42F87ED3C60E0B951FF3509D0101001A01060C130210020100010101070008050009008A8080800805000A0204090204008A8080800809000A020410030100010D01030A02110013001A15001C001F19002000A180808008190021020410030100011D0103050B1D0007000D2021290007000D21000F0090808080082100100015290018001D1D0107000D20252D0007000D25000F018980808008250109000E2D0109000E1001010001 - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -40,6 +40,6 @@ Symbols: Type: STT_OBJECT Section: __llvm_covfun Binding: STB_WEAK - Size: 0xB6 + Size: 0xBA Other: [ STV_HIDDEN ] ... From b2f7fdf6e1e80c191fde07f40de50fe26c4c6eff Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 21 Nov 2024 00:08:44 +0900 Subject: [PATCH 33/79] Update single tests --- .../Inputs/branch-c-general-single.proftext | 41 ++++++------ .../Inputs/branch-c-general-single.yaml | 24 +++---- .../tools/llvm-cov/Inputs/branch-c-general.c | 62 +++++++++---------- .../branch-logical-mixed-single.proftext | 8 +-- .../Inputs/branch-logical-mixed-single.yaml | 4 +- .../llvm-cov/Inputs/branch-logical-mixed.cpp | 8 +-- .../Inputs/branch-templates-single.proftext | 13 ++-- .../Inputs/branch-templates-single.yaml | 16 ++--- .../llvm-cov/Inputs/branch-templates.cpp | 18 +++--- .../showLineExecutionCounts-single.proftext | 5 +- .../showLineExecutionCounts-single.yaml | 4 +- .../test/tools/llvm-cov/branch-templates.test | 2 + 12 files changed, 98 insertions(+), 107 deletions(-) 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 index ea8c6f9bc634e..eae18299e95d7 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext @@ -28,11 +28,11 @@ big_switch 1 1 1 -1 -1 -1 -1 -1 +0 +0 +0 +0 +0 boolean_operators # Func Hash: @@ -116,7 +116,7 @@ conditionals # Func Hash: 4904767535850050386 # Num Counters: -25 +23 # Counter Values: 1 1 @@ -124,10 +124,6 @@ conditionals 1 1 1 -0 -1 -1 -1 1 1 1 @@ -139,7 +135,9 @@ conditionals 1 1 1 +0 1 +0 1 1 1 @@ -165,7 +163,7 @@ early_exits # Func Hash: 2880354649761471549 # Num Counters: -20 +19 # Counter Values: 1 0 @@ -177,15 +175,14 @@ early_exits 1 1 1 -1 -1 -1 +0 1 0 1 1 1 0 +1 0 jumps @@ -200,11 +197,9 @@ jumps 1 0 0 -0 1 0 1 -1 0 1 1 @@ -214,8 +209,6 @@ jumps 1 1 1 -1 -1 0 1 1 @@ -228,10 +221,14 @@ jumps 1 1 0 +1 +1 0 1 1 1 +0 +1 main # Func Hash: @@ -281,17 +278,17 @@ switches 1 1 1 -1 -1 -1 -1 0 1 1 1 1 +0 1 1 0 0 +0 +1 +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 index 9d23dcb67ad2a..fd1fa6302f6fb 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml @@ -16,27 +16,27 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 83AD05A5F1438E68EA00000052D33558163C11444C551E9517F40F4F010100260111150E02050113001A09001C001F0D002000A1808080080D00210B040D0109000E15000F009080808008150010020615010B000C21000D008E8080800821000E0010310106008C8080800831000C04063100100015290016009780808008290017020629010B000C35000D008E8080800835000E00102D0106008C808080082D000C02062D010B000C3D000D008E808080083D000E0010100201005B1D010502041D0009000A1D0009000F4D000E000F45001000918080800845001100134901050104490009000A490009000F5D000E000F55001000918080800855001100131002010001 + Content: 83AD05A5F1438E680301000052D33558163C11444C551E9517F40F4F010100290111150E02050113001A09001C001F0D002000A1808080080D00210B040D0109000E2015410009000E15000F009080808008150010020615010B000C201945000B000C19000D008E8080800819000E0010410106008C8080800841000C04064100100015201D49001000151D00160097808080081D001702061D010B000C20214D000B000C21000D008E8080800821000E0010490106008C8080800849000C020649010B000C202551000B000C25000D008E8080800825000E0010100201005B0D0109000A0D0009000F2D000E000F29001000918080800829001100130D0109000A0D0009000F39000E000F35001000918080800835001100131002010001 - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 0449C70428C57369F80000003D5C2D0E4B13F9274C551E9517F40F4F01010028012114180210020100010101070008050009008A8080800805000A000C100101000109010313020D000A00111100120093808080081100130604110209000F190010018780808008190107000C1D000D0185808080081D010502041D0009000E21000F018780808008210107000F15010402838080800810010100011501030B021500070008290009008A8080800829000A000C10010100012D010309023100060504310109000F3D00100187808080083D0107000D41000E028780808008410207000A35010C0013390015028380808008100101000139010302023900070008490009008A8080800849000A000C1001010001 + Content: 0449C70428C57369180100003D5C2D0E4B13F9274C551E9517F40F4F0101002C01211418021002010001010107000820053500070008050009008A8080800805000A000C100101000109010A00110D00120093808080080D001306040D0209000F2015390009000F150010018780808008150107000C39000D0185808080083901050204390009000E20193D0009000E19000F018780808008190107000F11010402838080800810010100011101030B021100070008201D41000700081D0009008A808080081D000A000C10010100012101060504210109000F202D450009000F2D00100187808080082D0107000D45000E028780808008450207000A25010C001329001502838080800810010100012901030202290007000820314900070008310009008A8080800831000A000C1001010001 - Name: '__llvm_covfun (3)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 55947829059F255EB80100001B9C495D3463E1D04C551E9517F40F4F01010046013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A15000B008C8080800815000C000E11010402818080800810010100011D010126021D01070008210009008A8080800821000A000C1001010001250103000D25000E0283808080081001010001000103210229000A000B2D000C008D808080082D000D03043501030204350109000A39000B008C8080800839000C000E1002010001310103000D31000E0181808080084101011B024501011A024901011902490207000C4D000D0185808080084D0105000F5100100283808080081001010001510103140255000A000F5900100091808080085900110A04610103090400011006918080800869010501110001120185808080086D0105011200011301858080800871010501115D030402838080800810010100015D0103080275000F0015790017001A7D001B009C808080087D001C0604000115028580808008100101003F0001050304000009000A8501000B008C808080088501000C000E8D01010302048D010109000A9101000B008C808080089101000C000E1002010001 + Content: 55947829059F255EDF0100001B9C495D3463E1D04C551E9517F40F4F0101004B013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A201581010009000A15000B008C8080800815000C000E1101040281808080081001010001190101030D1901070008201D8501000700081D0009008A808080081D000A000C100101000100010E0283808080081001010001000103210221000A000B25000C008D8080800825000D03042D010302042D0109000A203189010009000A31000B008C8080800831000C000E1002010001290103000D29000E0181808080083501011B023901011A023D010119023D0207000C20418D010007000C41000D018580808008410105000F8D01001002838080800810010100018D010103140245000A000F4900100091808080084900110A04510103090400011006918080800859010501110001120185808080085D0105011200011301858080800861010501114D030402838080800810010100014D0103080265000F0015690017001A6D001B009C808080086D001C0604000115028580808008100101003F0001050304000009000A207591010009000A75000B008C8080800875000C000E7901030204790109000A207D95010009000A7D000B008C808080087D000C000E1002010001 - Name: '__llvm_covfun (4)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 7129CA3C268292BF4D0100003E688383C9A099004C551E9517F40F4F01010035016C112502100201011C000217028A80808008090103010A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F21010B000C25000D008E8080800825000E001010010100152D0105100F2D010B000C31000D008E8080800831000E0010350107000C35000D0185808080083901050D0F39010B000C3D000D008E808080083D000E0010410107000F4100100185808080084501050A0F45010B000C49000D008E8080800849000E00104D0107080F000012039180808008550107021155010D000E59000F00908080800859001000125D010900115101080285808080081001010001610105020F61010B0017650018018980808008650109000F1902040383808080081001010121190203020219000700116D00120093808080086D001300151001010001 + Content: 7129CA3C268292BF6A0100003E688383C9A099004C551E9517F40F4F01010038016C112502100201011C000217028A80808008090103010A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F21010B000C202559000B000C25000D008E8080800825000E00101001010015290105020C29010B000C202D5D000B000C2D000D008E808080082D000E001000010D018580808008310105020F31010B000C203561000B000C35000D008E8080800835000E00100001100185808080083901050A0F39010B000C203D65000B000C3D000D008E808080083D000E0010000112039180808008450107021145010D000E204969000D000E49000F009080808008490010001241020802858080800810010100014D0105020F4D010B001720516D000B0017510018018980808008510109000F1902040383808080081001010121190203020219000700112055710007001155001200938080800855001300151001010001 - Name: '__llvm_covfun (5)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 3F4D1C6E6087417B32010000D6FF56B8865A69B64C551E9517F40F4F01010031019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C19010B000C1D000D008E808080081D000E00101001010015250105150C25010B000C29000D008E8080800829000E00102D0107000C2D000D018580808008310105120C31010B000C35000D008E8080800835000E0010390107000C39000D03858080800810010101013D02050D0C3D010B000C41000D008E8080800841000E0010450107000C45000D0185808080084901050A0C49010B000C4D000D008E808080084D000E0010510107000C51000D0385808080081001010101550205050C55010B000C59000D008E8080800859000E00105D0107000C5D000D018580808008610105020C61010B000C65000D008E8080800865000E0010690107000C1003010001 + Content: 3F4D1C6E6087417B45010000D6FF56B8865A69B64C551E9517F40F4F01010032019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C19010B000C201D51000B000C1D000D008E808080081D000E00101001010015210105020C21010B000C202555000B000C25000D008E8080800825000E001000010D018580808008290105020C29010B000C202D59000B000C2D000D008E808080082D000E001000010D0385808080081001010101310205020C31010B000C20355D000B000C35000D008E8080800835000E001000010D018580808008390105020C39010B000C203D61000B000C3D000D008E808080083D000E001000010D0385808080081001010101410205020C41010B000C204565000B000C45000D008E8080800845000E001000010D018580808008490105020C49010B000C204D69000B000C4D000D008E808080084D000E00101004010001 - Name: '__llvm_covfun (6)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -56,7 +56,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 7DE8E7C47096EB425200000092EAF0986287F0784C551E9517F40F4F0101000D01DA01170B02050113001909001B001E0D001F00A0808080080D002009041502080606100101024D15030B00102100110092808080082100120017250018018780808008250107010619010E0013 + Content: 7DE8E7C47096EB425900000092EAF0986287F0784C551E9517F40F4F0101000E01DA01170B02050113001909001B001E0D001F00A0808080080D002009041502080606100101024D15030B0010202125000B00102100110092808080082100120017250018018780808008250107010619010E0013 - Name: '__llvm_covfun (10)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -112,31 +112,31 @@ Symbols: Type: STT_OBJECT Section: '__llvm_covfun (1)' Binding: STB_WEAK - Size: 0x106 + Size: 0x11F Other: [ STV_HIDDEN ] - Name: __covrec_6973C52804C74904u Type: STT_OBJECT Section: '__llvm_covfun (2)' Binding: STB_WEAK - Size: 0x114 + Size: 0x134 Other: [ STV_HIDDEN ] - Name: __covrec_5E259F0529789455u Type: STT_OBJECT Section: '__llvm_covfun (3)' Binding: STB_WEAK - Size: 0x1D4 + Size: 0x1FB Other: [ STV_HIDDEN ] - Name: __covrec_BF9282263CCA2971u Type: STT_OBJECT Section: '__llvm_covfun (4)' Binding: STB_WEAK - Size: 0x169 + Size: 0x186 Other: [ STV_HIDDEN ] - Name: __covrec_7B4187606E1C4D3Fu Type: STT_OBJECT Section: '__llvm_covfun (5)' Binding: STB_WEAK - Size: 0x14E + Size: 0x161 Other: [ STV_HIDDEN ] - Name: __covrec_58A39A89A88AA459u Type: STT_OBJECT @@ -160,7 +160,7 @@ Symbols: Type: STT_OBJECT Section: '__llvm_covfun (9)' Binding: STB_WEAK - Size: 0x6E + Size: 0x75 Other: [ STV_HIDDEN ] - Name: __covrec_DB956436E78DD5FAu Type: STT_OBJECT 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..d8d4dad5b0ed1 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c @@ -16,12 +16,12 @@ void simple_loops() { // CHECK: @LINE|{{.*}}simple_loops() 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] + if (i % 2) { // CHECK: Branch ([[@LINE]]:9): [True: [[C50:50|1]], False: [[C50]]] + if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: [[C50]], False: 0] + } else if (i % 3) { // CHECK: Branch ([[@LINE]]:16): [True: [[C33:33|1]], False: [[C17:17|1]]] + if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: [[C33]], False: 0] } else { - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C16:16|1]], False: 1] + if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: [[C16:16|1]], False: 1] } // BRCOV: Branch ([[@LINE+1]]:9): [True: [[C100]], Folded] if (1 && i) {} // BRCOV: Branch ([[@LINE]]:14): [True: [[C99:99|1]], False: 1] @@ -33,26 +33,26 @@ void conditionals() { // CHECK: @LINE|{{.*}}conditionals() void early_exits() { // CHECK: @LINE|{{.*}}early_exits() int i = 0; - if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 1] + if (i) {} // CHECK: Branch ([[@LINE]]:7): [True: 0, False: 1] while (i < 100) { // BRCOV: Branch ([[@LINE]]:10): [True: [[C51:51|1]], False: 0] i++; - if (i > 50) // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[C50]]] + if (i > 50) // CHECK: Branch ([[@LINE]]:9): [True: 1, False: [[C50]]] break; - if (i % 2) // BRCOV: Branch ([[@LINE]]:9): [True: [[C25:25|1]], False: [[C25]]] + if (i % 2) // CHECK: Branch ([[@LINE]]:9): [True: [[C25:25|1]], False: [[C25]]] continue; } - if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 1, False: 0] + if (i) {} // CHECK: Branch ([[@LINE]]:7): [True: 1, False: 0] do { - if (i > 75) // BRCOV: Branch ([[@LINE]]:9): [True: 1, False: [[C25]]] + if (i > 75) // CHECK: Branch ([[@LINE]]:9): [True: 1, False: [[C25]]] return; else i++; } while (i < 100); // BRCOV: Branch ([[@LINE]]:12): [True: [[C25]], False: 0] - if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 0] + if (i) {} // CHECK: Branch ([[@LINE]]:7): [True: 0, False: 0] } @@ -62,17 +62,17 @@ void jumps() { // CHECK: @LINE|{{.*}}jumps() for (i = 0; i < 2; ++i) { // BRCOV: Branch ([[@LINE]]:15): [True: 1, False: 0] goto outofloop; // Never reached -> no weights - if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 0] + if (i) {} // CHECK: Branch ([[@LINE]]:9): [True: 0, False: 0] } outofloop: - if (i) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 1] + if (i) {} // CHECK: Branch ([[@LINE]]:7): [True: 0, False: 1] goto loop1; while (i) { // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1] loop1: - if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 1] + if (i) {} // CHECK: Branch ([[@LINE]]:9): [True: 0, False: 1] } goto loop2; @@ -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) // CHECK: Branch ([[@LINE]]:7): [True: [[C2:2|1]], False: 1] goto loop2; while (i < 3) { // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1] @@ -98,9 +98,9 @@ void jumps() { // CHECK: @LINE|{{.*}}jumps() for (i = 0; i < 10; ++i) { // BRCOV: Branch ([[@LINE]]:15): [True: [[C10:10|1]], False: 1] goto withinloop; // never reached -> no weights - if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: 0, False: 0] + if (i) {} // CHECK: Branch ([[@LINE]]:9): [True: 0, False: 0] withinloop: - if (i) {} // BRCOV: Branch ([[@LINE]]:9): [True: [[C9:9|1]], False: 1] + if (i) {} // CHECK: Branch ([[@LINE]]:9): [True: [[C9:9|1]], False: 1] } } @@ -117,30 +117,30 @@ void switches() { // CHECK: @LINE|{{.*}}switches() 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] + if (i) {} // CHECK: 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] + if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: [[C2]], False: 1] break; case 3: // BRCOV: Branch ([[@LINE]]:5): [True: [[C3:3|1]], Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C3]], False: 0] + if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: [[C3:3|1]], False: 0] continue; case 4: // BRCOV: Branch ([[@LINE]]:5): [True: [[C4:4|1]], Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C4]], False: 0] + if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: [[C4:4|1]], False: 0] switch (i) { case 6 ... 9: // BRCOV: Branch ([[@LINE]]:7): [True: [[C4]], Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:13): [True: [[C4]], False: 0] + if (i) {} // CHECK: Branch ([[@LINE]]:13): [True: [[C4]], 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]]] + if (i == len - 1) // CHECK: Branch ([[@LINE]]:11): [True: 1, False: [[C4]]] return; } } // Never reached -> no weights - if (weights[0]) {} // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: 0] + if (weights[0]) {} // CHECK: Branch ([[@LINE]]:7): [True: 0, False: 0] } @@ -148,29 +148,29 @@ 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): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1] + if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: 0, False: 1] // fallthrough case (1 << 1): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] - if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: 1] + if (i) {} // CHECK: 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] + if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: [[C11:11|1]], 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] + if (i) {} // CHECK: 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] + if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: [[C15:15|1]], 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] + if (i) {} // CHECK: 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] + if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: [[C2]], False: 0] break; } } 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 index f9662438de0e6..798e150d80a1a 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.proftext @@ -4,7 +4,7 @@ _Z4funcii # Func Hash: 8468630735863722633 # Num Counters: -67 +63 # Counter Values: 4 0 @@ -63,16 +63,12 @@ _Z4funcii 0 0 4 -4 -4 -0 -4 1 3 4 +0 3 1 -4 main # Func Hash: 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 index 56f3d4955f4d9..0c36f48789a51 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml @@ -11,7 +11,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: F0A0ED2C305C0BB32D02000089B21C19C99E86758F2950E06FBD46E8010100600108194302100701000101010C000E01000C010E01000C020E01000C030E01000C040E25010C000E1D010C000E15010C000E0D010C000E05010C000E100101000101010C000E01000C010E01000C020E01000C030E01000C040E4D010C000E45010C000E3D010C000E35010C000E2D010C000E100101000101010C011001000C031001000C051001000C071001000C091001000D000F69010D000F65010C011065000D000F71010D000F61010C011061000D000F79010D000F5D010C01105D000D000F8101010D000F59010C011059000D000F8901010D000F55010C011055000D000F9101010D000F100101000101010C011001000C031001000C051001000C071001000C091001000D000FAD01010D000FA901010C0110A901000D000FB501010D000FA501010C0110A501000D000FBD01010D000FA101010C0110A101000D000FC501010D000F9D01010C01109D01000D000FCD01010D000F9901010C01109901000D000FD501010D000F10010100010101070008DD010009018580808008DD0101050016E1010017028580808008E101020500161001010001E50101030E02E50100070008E9010009018580808008E90101050016ED010017028580808008ED01020500161001010001F10101030902F10100070008F5010009018580808008F50101050016F9010017028580808008F901020500161001010001FD0101030402FD01000700088102000901858080800881020105001685020017028580808008850202050016 + Content: F0A0ED2C305C0BB33C02000089B21C19C99E86758F2950E06FBD46E8010100610108194302100701000101010C000E01000C010E01000C020E01000C030E01000C040E25010C000E1D010C000E15010C000E0D010C000E05010C000E100101000101010C000E01000C010E01000C020E01000C030E01000C040E4D010C000E45010C000E3D010C000E35010C000E2D010C000E100101000101010C011001000C031001000C051001000C071001000C091001000D000F69010D000F65010C011065000D000F71010D000F61010C011061000D000F79010D000F5D010C01105D000D000F8101010D000F59010C011059000D000F8901010D000F55010C011055000D000F9101010D000F100101000101010C011001000C031001000C051001000C071001000C091001000D000FAD01010D000FA901010C0110A901000D000FB501010D000FA501010C0110A501000D000FBD01010D000FA101010C0110A101000D000FC501010D000F9D01010C01109D01000D000FCD01010D000F9901010C01109901000D000FD501010D000F1001010001010107000820DD01ED0100070008DD010009018580808008DD0101050016ED010017028580808008ED01020500161001010001010107000820E101F10100070008E1010009018580808008E10101050016F1010017028580808008F101020500161001010001010107000820E501F50100070008E5010009018580808008E50101050016F5010017028580808008F501020500161001010001010107000820E901F90100070008E9010009018580808008E90101050016F9010017028580808008F90102050016 - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -46,7 +46,7 @@ Symbols: Type: STT_OBJECT Section: __llvm_covfun Binding: STB_WEAK - Size: 0x249 + Size: 0x258 Other: [ STV_HIDDEN ] - Name: __covrec_DB956436E78DD5FAu Type: STT_OBJECT 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..7665a88466ac8 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp @@ -53,22 +53,22 @@ void func(int a, int b) { (b5 || // BRCOV: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] b0); // BRCOV: Branch ([[@LINE]]:13): [True: [[C2]], False: 0] - if (c) // BRCOV: Branch ([[@LINE]]:7): [True: 0, False: [[C4]]] + if (c) // CHECK: Branch ([[@LINE]]:7): [True: 0, False: [[C4]]] printf("case0\n"); else printf("case1\n"); - if (d) // BRCOV: Branch ([[@LINE]]:7): [True: [[C4]], False: 0] + if (d) // CHECK: Branch ([[@LINE]]:7): [True: [[C4]], False: 0] printf("case2\n"); else printf("case3\n"); - if (e) // BRCOV: Branch ([[@LINE]]:7): [True: 1, False: [[C3]]] + if (e) // CHECK: Branch ([[@LINE]]:7): [True: 1, False: [[C3:3|1]]] printf("case4\n"); else printf("case5\n"); - if (f) // BRCOV: Branch ([[@LINE]]:7): [True: [[C3]], False: 1] + if (f) // CHECK: Branch ([[@LINE]]:7): [True: [[C3]], False: 1] printf("case6\n"); else printf("case7\n"); diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.proftext b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.proftext index 829431334478f..42cb368bd186e 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.proftext @@ -4,34 +4,31 @@ _Z4funcIbEiT_ # Func Hash: 11045778961 # Num Counters: -4 +3 # Counter Values: 1 1 0 -0 _Z4funcIfEiT_ # Func Hash: 11045778961 # Num Counters: -4 +3 # Counter Values: 1 0 1 -0 _Z4funcIiEiT_ # Func Hash: 11045778961 # Num Counters: -4 +3 # Counter Values: 1 0 1 -0 main # Func Hash: @@ -41,9 +38,9 @@ main # Counter Values: 1 1 -1 0 1 +0 1 -1 +0 diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml index d4ede6db448e6..de145925c6bab 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates-single.yaml @@ -11,22 +11,22 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: FAD58DE7366495DB5100000058242991A444920226ED9A40DAABBC6B0101000D011D0C090201010700130500140185808080080501050016090103060209000700170D00180185808080080D01050016110103040211000700171500180185808080081501050016190103010B + Content: FAD58DE7366495DB5700000058242991A444920226ED9A40DAABBC6B0101000D011D0C0902010107001320051100070013050014018580808008050105001601010700172009150007001709001801858080800809010500160101070017200D19000700170D00180185808080080D01050016 - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 5427717259E0E43E38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 + Content: 5427717259E0E43E3F000000113661920200000026ED9A40DAABBC6B01010009010D0F0602010106000720050900060007050008018580808008050105000D09000E028580808008090205000D00000E0183808080080001030102 - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 4B7E22082F0551AA38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 + Content: 4B7E22082F0551AA3F000000113661920200000026ED9A40DAABBC6B01010009010D0F0602010106000720050900060007050008018580808008050105000D09000E028580808008090205000D00000E0183808080080001030102 - Name: '__llvm_covfun (3)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: AC1440BC3DA3E41A38000000113661920200000026ED9A40DAABBC6B01010008010D0F06020101060007050008018580808008050105000D09000E028580808008090205000D0D000E0183808080080D01030102 + Content: AC1440BC3DA3E41A3F000000113661920200000026ED9A40DAABBC6B01010009010D0F0602010106000720050900060007050008018580808008050105000D09000E028580808008090205000D00000E0183808080080001030102 - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -58,24 +58,24 @@ Symbols: Type: STT_OBJECT Section: __llvm_covfun Binding: STB_WEAK - Size: 0x6D + Size: 0x73 Other: [ STV_HIDDEN ] - Name: __covrec_3EE4E05972712754u Type: STT_OBJECT Section: '__llvm_covfun (1)' Binding: STB_WEAK - Size: 0x54 + Size: 0x5B Other: [ STV_HIDDEN ] - Name: __covrec_AA51052F08227E4Bu Type: STT_OBJECT Section: '__llvm_covfun (2)' Binding: STB_WEAK - Size: 0x54 + Size: 0x5B Other: [ STV_HIDDEN ] - Name: __covrec_1AE4A33DBC4014ACu Type: STT_OBJECT Section: '__llvm_covfun (3)' Binding: STB_WEAK - Size: 0x54 + Size: 0x5B 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 4d932eaf5944a..597e596ae84d5 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-templates.cpp @@ -11,27 +11,27 @@ 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) // 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_: - // BRCOV: | | Branch ([[@LINE-8]]:6): [True: 0, False: 1] + // CHECK: | | Branch ([[@LINE-8]]:6): [True: 0, False: 1] // CHECK-LABEL: _Z4funcIbEiT_: - // BRCOV: | | Branch ([[@LINE-10]]:6): [True: 1, False: 0] + // CHECK: | | Branch ([[@LINE-10]]:6): [True: 1, False: 0] // CHECK-LABEL: _Z4funcIfEiT_: - // BRCOV: | | Branch ([[@LINE-12]]:6): [True: 0, False: 1] + // CHECK: | | Branch ([[@LINE-12]]:6): [True: 0, False: 1] int main() { - if (func(0)) // BRCOV: | Branch ([[@LINE]]:7): [True: 1, False: 0] + if (func(0)) // CHECK: | Branch ([[@LINE]]:7): [True: 1, False: 0] printf("case1\n"); - if (func(true)) // BRCOV: | Branch ([[@LINE]]:7): [True: 0, False: 1] + if (func(true)) // CHECK: | Branch ([[@LINE]]:7): [True: 0, False: 1] printf("case2\n"); - if (func(0.0)) // BRCOV: | Branch ([[@LINE]]:7): [True: 1, False: 0] + if (func(0.0)) // CHECK: | Branch ([[@LINE]]:7): [True: 1, False: 0] printf("case3\n"); (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 index 1b7b949de4962..cfaaf8c3fc631 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.proftext @@ -4,7 +4,7 @@ main # Func Hash: 15239891155360101223 # Num Counters: -14 +13 # Counter Values: 161 0 @@ -14,10 +14,9 @@ main 161 161 161 -161 -161 0 161 0 161 +161 diff --git a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml index 84b184023f082..f1cca420c1d10 100644 --- a/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/showLineExecutionCounts-single.yaml @@ -11,7 +11,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: FAD58DE7366495DB9A0000006733DBEA42F87ED3C60E0B951FF3509D0101001A01060C130210020100010101070008050009008A8080800805000A0204090204008A8080800809000A020410030100010D01030A02110013001A15001C001F19002000A180808008190021020410030100011D010306021D0007000D25000F0090808080082500100015290018001D2101030502210007000D31000F018980808008310109000E350109000E10010100012D0103000B + Content: FAD58DE7366495DB9C0000006733DBEA42F87ED3C60E0B951FF3509D0101001A01060C13021002010001010107000820053100070008050009008A8080800805000A0204310204008A8080800831000A02041003010001090113001A0D001C001F11002000A180808008110021020410030100011501030602150007000D1D000F0090808080081D00100015210018001D1901030502190007000D29000F018980808008290109000E2D0109000E1001010001250103000B - Name: __llvm_covmap Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -40,6 +40,6 @@ Symbols: Type: STT_OBJECT Section: __llvm_covfun Binding: STB_WEAK - Size: 0xB6 + Size: 0xB8 Other: [ STV_HIDDEN ] ... diff --git a/llvm/test/tools/llvm-cov/branch-templates.test b/llvm/test/tools/llvm-cov/branch-templates.test index d5535022239f5..6454c4ad8dd35 100644 --- a/llvm/test/tools/llvm-cov/branch-templates.test +++ b/llvm/test/tools/llvm-cov/branch-templates.test @@ -6,6 +6,8 @@ // 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 +// RUN: llvm-cov report --show-branch-summary %t.o -instr-profile %t.profdata -show-functions -path-equivalence=.,%S/Inputs %S/Inputs/branch-templates.cpp | FileCheck %s -check-prefix=REPORT +// RUN: llvm-cov report --show-branch-summary %t.o -instr-profile %t.profdata -path-equivalence=.,%S/Inputs | FileCheck %s -check-prefix=REPORTFILE // REPORT: Name Regions Miss Cover Lines Miss Cover Branches Miss Cover // REPORT-NEXT: --- From cce771fa5512089c69ddfad30f2267124f3f46b5 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 21 Nov 2024 00:18:39 +0900 Subject: [PATCH 34/79] Update test --- .../Inputs/branch-c-general-single.proftext | 6 ++-- .../Inputs/branch-c-general-single.yaml | 12 +++---- .../tools/llvm-cov/Inputs/branch-c-general.c | 32 +++++++++---------- 3 files changed, 26 insertions(+), 24 deletions(-) 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 index ea8c6f9bc634e..b92df1d6a38a3 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext @@ -192,7 +192,7 @@ jumps # Func Hash: 15051420506203462683 # Num Counters: -38 +39 # Counter Values: 1 1 @@ -232,6 +232,7 @@ jumps 1 1 1 +0 main # Func Hash: @@ -263,7 +264,7 @@ switches # Func Hash: 43242458792028222 # Num Counters: -29 +30 # Counter Values: 1 1 @@ -294,4 +295,5 @@ switches 1 0 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 index 9d23dcb67ad2a..6bbf80e14941d 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml @@ -26,17 +26,17 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 55947829059F255EB80100001B9C495D3463E1D04C551E9517F40F4F01010046013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A15000B008C8080800815000C000E11010402818080800810010100011D010126021D01070008210009008A8080800821000A000C1001010001250103000D25000E0283808080081001010001000103210229000A000B2D000C008D808080082D000D03043501030204350109000A39000B008C8080800839000C000E1002010001310103000D31000E0181808080084101011B024501011A024901011902490207000C4D000D0185808080084D0105000F5100100283808080081001010001510103140255000A000F5900100091808080085900110A04610103090400011006918080800869010501110001120185808080086D0105011200011301858080800871010501115D030402838080800810010100015D0103080275000F0015790017001A7D001B009C808080087D001C0604000115028580808008100101003F0001050304000009000A8501000B008C808080088501000C000E8D01010302048D010109000A9101000B008C808080089101000C000E1002010001 + Content: 55947829059F255ED50100001B9C495D3463E1D04C551E9517F40F4F0101004A013B0E2F02100201000105010F001409001600190D001A009B808080080D001B040400011402858080800810010100230001050104000009000A15000B008C8080800815000C000E11010402818080800810010100011D010126021D01070008210009008A8080800821000A000C1001010001250103000D25000E0283808080081001010001000103210229000A000B2D000C008D808080082D000D03043501030204350109000A39000B008C8080800839000C000E1002010001310103000D31000E0181808080084101011B024501011A024901011902490207000C4D000D0185808080084D0105000F5100100283808080081001010001510103140255000A000F5900100091808080085900110A04610103090420009901010D000E00001006918080800869010501112069000005000B0001120185808080086D01050112206D000005000B00011301858080800871010501112071000005000B5D030402838080800810010100015D0103080275000F0015790017001A7D001B009C808080087D001C0604000115028580808008100101003F0001050304000009000A8501000B008C808080088501000C000E8D01010302048D010109000A9101000B008C808080089101000C000E1002010001 - Name: '__llvm_covfun (4)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 7129CA3C268292BF4D0100003E688383C9A099004C551E9517F40F4F01010035016C112502100201011C000217028A80808008090103010A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F21010B000C25000D008E8080800825000E001010010100152D0105100F2D010B000C31000D008E8080800831000E0010350107000C35000D0185808080083901050D0F39010B000C3D000D008E808080083D000E0010410107000F4100100185808080084501050A0F45010B000C49000D008E8080800849000E00104D0107080F000012039180808008550107021155010D000E59000F00908080800859001000125D010900115101080285808080081001010001610105020F61010B0017650018018980808008650109000F1902040383808080081001010121190203020219000700116D00120093808080086D001300151001010001 + Content: 7129CA3C268292BF8B0100003E688383C9A099004C551E9517F40F4F010103292D516151613D016C112502100201011C000217028A80808008090103010A2009000003000A05020402838080800810010100620501031C020D003F0046110048004B15004C00CD8080800815004D1704000119148F80808008210105130F2021000005000B21010B000C25000D008E8080800825000E00101001010015030105100F202D000005000B03010B000C31000D008E8080800831000E0010350107000C35000D0185808080083901050D0F2039000005000B39010B000C3D000D008E808080083D000E0010410107000F4100100185808080084501050A0F2045000005000B45010B000C49000D008E8080800849000E00104D0107080F200075000F001000001203918080800855010702112055000007001355010D000E59000F00908080800859001000125D0109001151010802858080800810010100010B0105020F2061000005000C0B010B0017650018018980808008650109000F1902040383808080081001010121190203020219000700116D00120093808080086D001300151001010001 - Name: '__llvm_covfun (5)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 3F4D1C6E6087417B32010000D6FF56B8865A69B64C551E9517F40F4F01010031019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C19010B000C1D000D008E808080081D000E00101001010015250105150C25010B000C29000D008E8080800829000E00102D0107000C2D000D018580808008310105120C31010B000C35000D008E8080800835000E0010390107000C39000D03858080800810010101013D02050D0C3D010B000C41000D008E8080800841000E0010450107000C45000D0185808080084901050A0C49010B000C4D000D008E808080084D000E0010510107000C51000D0385808080081001010101550205050C55010B000C59000D008E8080800859000E00105D0107000C5D000D018580808008610105020C61010B000C65000D008E8080800865000E0010690107000C1003010001 + Content: 3F4D1C6E6087417B65010000D6FF56B8865A69B64C551E9517F40F4F010101212538019301131F02050113001909001B001E0D001F00A0808080080D00201C04000115198C80808008190105180C2019000005001219010B000C1D000D008E808080081D000E00101001010015030105150C2025000005001203010B000C29000D008E8080800829000E00102D0107000C2D000D018580808008310105120C2031000005002031010B000C35000D008E8080800835000E0010390107000C39000D03858080800810010101013D02050D0C203D00000500133D010B000C41000D008E8080800841000E0010450107000C45000D0185808080084901050A0C2049000005002149010B000C4D000D008E808080084D000E0010510107000C51000D0385808080081001010101550205050C2055000005002755010B000C59000D008E8080800859000E00105D0107000C5D000D018580808008610105020C2061000005000C61010B000C65000D008E8080800865000E0010690107000C1003010001 - Name: '__llvm_covfun (6)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -124,19 +124,19 @@ Symbols: Type: STT_OBJECT Section: '__llvm_covfun (3)' Binding: STB_WEAK - Size: 0x1D4 + Size: 0x1F1 Other: [ STV_HIDDEN ] - Name: __covrec_BF9282263CCA2971u Type: STT_OBJECT Section: '__llvm_covfun (4)' Binding: STB_WEAK - Size: 0x169 + Size: 0x1A7 Other: [ STV_HIDDEN ] - Name: __covrec_7B4187606E1C4D3Fu Type: STT_OBJECT Section: '__llvm_covfun (5)' Binding: STB_WEAK - Size: 0x14E + Size: 0x181 Other: [ STV_HIDDEN ] - Name: __covrec_58A39A89A88AA459u Type: STT_OBJECT 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..5fb4ad3c364dc 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c @@ -86,11 +86,11 @@ void jumps() { // CHECK: @LINE|{{.*}}jumps() while (i < 3) { // BRCOV: Branch ([[@LINE]]:10): [True: 0, False: 1] loop2: switch (i) { - case 0: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + case 0: // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded] goto first; - case 1: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + case 1: // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded] goto second; - case 2: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + case 2: // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded] goto third; } } @@ -110,30 +110,30 @@ void switches() { // CHECK: @LINE|{{.*}}switches() // No cases -> no weights switch (weights[0]) { - default: // BRCOV: Branch ([[@LINE]]:3): [True: 1, Folded] + default: // CHECK: 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: // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + case 1: // CHECK: 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] + case 2: // CHECK: Branch ([[@LINE]]:5): [True: [[C2:2|1]], Folded] if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C2]], False: 1] break; - case 3: // BRCOV: Branch ([[@LINE]]:5): [True: [[C3:3|1]], Folded] + case 3: // CHECK: Branch ([[@LINE]]:5): [True: [[C3:3|1]], Folded] if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C3]], False: 0] continue; - case 4: // BRCOV: Branch ([[@LINE]]:5): [True: [[C4:4|1]], Folded] + case 4: // CHECK: Branch ([[@LINE]]:5): [True: [[C4:4|1]], Folded] if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C4]], False: 0] switch (i) { - case 6 ... 9: // BRCOV: Branch ([[@LINE]]:7): [True: [[C4]], Folded] + case 6 ... 9: // CHECK: Branch ([[@LINE]]:7): [True: [[C4]], Folded] if (i) {} // BRCOV: Branch ([[@LINE]]:13): [True: [[C4]], False: 0] continue; } - default: // BRCOV: Branch ([[@LINE]]:5): [True: [[C5:5|1]], Folded] + default: // CHECK: Branch ([[@LINE]]:5): [True: [[C5:5|1]], Folded] if (i == len - 1) // BRCOV: Branch ([[@LINE]]:11): [True: 1, False: [[C4]]] return; } @@ -147,21 +147,21 @@ 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] switch (1 << i) { - case (1 << 0): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + case (1 << 0): // CHECK: Branch ([[@LINE]]:5): [True: 1, Folded] if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: 0, False: 1] // fallthrough - case (1 << 1): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + case (1 << 1): // CHECK: 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] + case (1 << 2) ... (1 << 12):// CHECK: 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): // BRCOV: Branch ([[@LINE]]:5): [True: 1, Folded] + case (1 << 13): // CHECK: 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] + case (1 << 14) ... (1 << 28)://CHECK: Branch ([[@LINE]]:5): [True: [[C15:15|1]], 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. @@ -169,7 +169,7 @@ void big_switch() { // CHECK: @LINE|{{.*}}big_switch() 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] + default: // CHECK: Branch ([[@LINE]]:5): [True: [[C2:2|1]], Folded] if (i) {} // BRCOV: Branch ([[@LINE]]:11): [True: [[C2]], False: 0] break; } From 4b58cb135371efccd573617f4e4e37055e477b0e Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 21 Nov 2024 00:23:18 +0900 Subject: [PATCH 35/79] Update single tests --- .../Inputs/branch-c-general-single.proftext | 30 +++++++- .../Inputs/branch-c-general-single.yaml | 12 +-- .../tools/llvm-cov/Inputs/branch-c-general.c | 44 +++++------ .../branch-logical-mixed-single.proftext | 66 ++++++++++++++++- .../Inputs/branch-logical-mixed-single.yaml | 4 +- .../llvm-cov/Inputs/branch-logical-mixed.cpp | 74 +++++++++---------- .../Inputs/branch-macros-single.proftext | 28 ++++++- .../llvm-cov/Inputs/branch-macros-single.yaml | 8 +- .../tools/llvm-cov/Inputs/branch-macros.cpp | 40 +++++----- .../tools/llvm-cov/branch-logical-mixed.test | 2 +- llvm/test/tools/llvm-cov/branch-macros.test | 2 +- 11 files changed, 211 insertions(+), 99 deletions(-) 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 index 1606f292c1786..0f89783360241 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.proftext @@ -36,7 +36,7 @@ boolean_operators # Func Hash: 1245693242827665 # Num Counters: -14 +26 # Counter Values: 1 1 @@ -52,12 +52,24 @@ boolean_operators 1 1 1 +1 +1 +1 +0 +1 +1 +1 +1 +1 +1 +1 +0 boolop_loops # Func Hash: 12402604614320574815 # Num Counters: -13 +21 # Counter Values: 1 1 @@ -72,6 +84,14 @@ boolop_loops 1 1 1 +0 +1 +1 +1 +0 +1 +1 +1 branch-c-general.c:static_func # Func Hash: @@ -98,7 +118,7 @@ conditionals # Func Hash: 4904767535850050386 # Num Counters: -20 +24 # Counter Values: 1 1 @@ -119,6 +139,10 @@ conditionals 0 1 1 +0 +1 +1 +0 1 do_fallthrough 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 index 2d6324fad688c..ec5ab0a105ced 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general-single.yaml @@ -16,7 +16,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 83AD05A5F1438E680C01000052D33558163C11444C551E9517F40F4F01010101052A0111150E02030113001A2005010013001A05001C001F05002000A1808080080500210B04050109000E2009350009000E09000F009080808008090010020609010B000C200D39000B000C0D000D008E808080080D000E0010350106008C8080800835000C0406350010001520113D00100015110016009780808008110017020611010B000C201541000B000C15000D008E8080800815000E00103D0106008C808080083D000C02063D010B000C201945000B000C19000D008E8080800819000E0010100201005B050109000A050009000F21000E000F1D00100091808080081D00110013050109000A050009000F2D000E000F29001000918080800829001100131002010001 + Content: 83AD05A5F1438E682801000052D33558163C11444C551E9517F40F4F01010101052E0111150E02030113001A2005010013001A05001C001F05002000A1808080080500210B04050109000E2009350009000E09000F009080808008090010020609010B000C200D39000B000C0D000D008E808080080D000E0010350106008C8080800835000C0406350010001520113D00100015110016009780808008110017020611010B000C201541000B000C15000D008E8080800815000E00103D0106008C808080083D000C02063D010B000C201945000B000C19000D008E8080800819000E0010100201005B050109000A050009000F2021000009000A21000E000F202551000E000F1D00100091808080081D00110013050109000A050009000F20002D0009000A2D000E000F205D31000E000F29001000918080800829001100131002010001 - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -41,12 +41,12 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: 59A48AA8899AA3587B00000091E33C8FF36C04004C551E9517F40F4F01010101051601B4011A0C02030213001A2005010013001A05001C001F05002000A1808080080500210804050109000E0900120013100101005D050109000E1100120013100101005D050109000E0500090017210012001719001B001C1001010063050109000E0500090017310012001729001B001C1002010063 + Content: 59A48AA8899AA358C100000091E33C8FF36C04004C551E9517F40F4F01010101052001B4011A0C02030213001A2005010013001A05001C001F05002000A1808080080500210804050109000E2039090009000E0900120013203D0D00120013100101005D050109000E2011410009000E110012001320154500120013100101005D050109000E05000900172049210009000E2100120017204D250012001719001B001C20551D001B001C1001010063050109000E05000900172031590009000E310012001720355D0012001729001B001C202D65001B001C1002010063 - Name: '__llvm_covfun (7)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: F5953D044B505D139D0000005FD132562FE71EAC4C551E9517F40F4F010107010501110111011D011D012901291A01C201150D02100201000103010A000B03000A001509000F0015050016018580808008050105000810010100010B010A00110B000A001C150015001C11001D018580808008110105000810010100011301110012130011001C210016001C1D001E00211D0022002310010100611B010A00111B000A001C2D0015001C29001E002129002200231001010061 + Content: F5953D044B505D13D50000005FD132562FE71EAC4C551E9517F40F4F010107010501110111011D011D012901292201C201150D02100201000103010A000B03000A0015200935000A000B09000F0015200D39000F0015050016018580808008050105000810010100010B010A00110B000A001C203D15000A0011150015001C2041190015001C11001D018580808008110105000810010100011301110012130011001C20214500110012210016001C2025490016001C1D001E00211D0022002310010100611B010A00111B000A001C204D2D000A00112D0015001C2051310015001C29001E002129002200231001010061 - Name: '__llvm_covfun (8)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -112,7 +112,7 @@ Symbols: Type: STT_OBJECT Section: '__llvm_covfun (1)' Binding: STB_WEAK - Size: 0x128 + Size: 0x144 Other: [ STV_HIDDEN ] - Name: __covrec_6973C52804C74904u Type: STT_OBJECT @@ -142,13 +142,13 @@ Symbols: Type: STT_OBJECT Section: '__llvm_covfun (6)' Binding: STB_WEAK - Size: 0x97 + Size: 0xDD Other: [ STV_HIDDEN ] - Name: __covrec_135D504B043D95F5u Type: STT_OBJECT Section: '__llvm_covfun (7)' Binding: STB_WEAK - Size: 0xB9 + Size: 0xF1 Other: [ STV_HIDDEN ] - Name: __covrec_795CF1BD69C3E520u Type: STT_OBJECT 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 6b7f2c96ec800..6c62e33d02bac 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c +++ b/llvm/test/tools/llvm-cov/Inputs/branch-c-general.c @@ -23,10 +23,10 @@ void conditionals() { // CHECK: @LINE|{{.*}}conditionals() } else { if (i) {} // CHECK: Branch ([[@LINE]]:11): [True: [[C16:16|1]], 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] + // CHECK: Branch ([[@LINE+1]]:9): [True: [[C100]], Folded] + if (1 && i) {} // CHECK: Branch ([[@LINE]]:14): [True: [[C99:99|1]], False: 1] + if (0 || i) {} // CHECK: Branch ([[@LINE]]:9): [Folded, False: [[C100]]] + } // CHECK: Branch ([[@LINE-1]]:14): [True: [[C99]], False: 1] } @@ -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; // CHECK: Branch ([[@LINE]]:9): [True: [[C66:66|1]], False: [[C34:34|1]]] + // CHECK: Branch ([[@LINE-1]]:18): [True: [[C33]], False: 1] + v = i % 3 && i; // CHECK: Branch ([[@LINE]]:9): [True: [[C66]], False: [[C34]]] + // CHECK: Branch ([[@LINE-1]]:18): [True: [[C66]], False: 0] + v = i % 3 || i % 2 || i; // CHECK: Branch ([[@LINE]]:9): [True: [[C66]], False: [[C34]]] + // CHECK: Branch ([[@LINE-1]]:18): [True: [[C17]], False: [[C17]]] + v = i % 2 && i % 3 && i; // CHECK: Branch ([[@LINE-2]]:27): [True: [[C16]], False: 1] + } // CHECK: Branch ([[@LINE-1]]:9): [True: [[C50]], False: [[C50]]] + // CHECK: Branch ([[@LINE-2]]:18): [True: [[C33]], False: [[C17]]] +} // CHECK: Branch ([[@LINE-3]]:27): [True: [[C33]], 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) // CHECK: Branch ([[@LINE]]:10): [True: [[C51]], False: 0] + i--; // CHECK: Branch ([[@LINE-1]]:15): [True: [[C50]], 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)) // CHECK: Branch ([[@LINE]]:10): [True: [[C25]], False: [[C26:26|1]]] + i--; // CHECK: 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] + for (i = 100; i && i > 50; --i); // CHECK: Branch ([[@LINE]]:17): [True: [[C51]], False: 0] + // CHECK: Branch ([[@LINE-1]]:22): [True: [[C50]], False: 1] + for (; (i % 2) || (i > 0); --i); // CHECK: Branch ([[@LINE]]:10): [True: [[C25]], False: [[C26]]] + // CHECK: Branch ([[@LINE-1]]:21): [True: [[C25]], False: 1] } void conditional_operator() { // CHECK: @LINE|{{.*}}conditional_operator() 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 index 798e150d80a1a..7ebf85a88e869 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.proftext @@ -4,7 +4,7 @@ _Z4funcii # Func Hash: 8468630735863722633 # Num Counters: -63 +127 # Counter Values: 4 0 @@ -65,6 +65,70 @@ _Z4funcii 4 1 3 +1 +1 +2 +0 +2 +2 +4 +0 +4 +0 +3 +0 +3 +1 +4 +0 +4 +0 +4 +0 +1 +2 +1 +2 +1 +0 +0 +3 +1 +0 +3 +0 +1 +0 +2 +1 +1 +0 +2 +1 +1 +0 +3 +1 +2 +1 +0 +0 +3 +0 +1 +0 +0 +3 +1 +0 +1 +2 +1 +0 +1 +2 +1 +0 4 0 3 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 index 0c36f48789a51..0fc3196210b09 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed-single.yaml @@ -11,7 +11,7 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: F0A0ED2C305C0BB33C02000089B21C19C99E86758F2950E06FBD46E8010100610108194302100701000101010C000E01000C010E01000C020E01000C030E01000C040E25010C000E1D010C000E15010C000E0D010C000E05010C000E100101000101010C000E01000C010E01000C020E01000C030E01000C040E4D010C000E45010C000E3D010C000E35010C000E2D010C000E100101000101010C011001000C031001000C051001000C071001000C091001000D000F69010D000F65010C011065000D000F71010D000F61010C011061000D000F79010D000F5D010C01105D000D000F8101010D000F59010C011059000D000F8901010D000F55010C011055000D000F9101010D000F100101000101010C011001000C031001000C051001000C071001000C091001000D000FAD01010D000FA901010C0110A901000D000FB501010D000FA501010C0110A501000D000FBD01010D000FA101010C0110A101000D000FC501010D000F9D01010C01109D01000D000FCD01010D000F9901010C01109901000D000FD501010D000F1001010001010107000820DD01ED0100070008DD010009018580808008DD0101050016ED010017028580808008ED01020500161001010001010107000820E101F10100070008E1010009018580808008E10101050016F1010017028580808008F101020500161001010001010107000820E501F50100070008E5010009018580808008E50101050016F5010017028580808008F501020500161001010001010107000820E901F90100070008E9010009018580808008E90101050016F9010017028580808008F90102050016 + Content: F0A0ED2C305C0BB36F03000089B21C19C99E86758F2950E06FBD46E801010085010108194302100701000101010C000E01000C010E01000C020E01000C030E01000C040E2025ED01000C000E25010C000E2029F101000C000E1D010C000E2021F901000C000E15010C000E20198102000C000E0D010C000E20118902000C000E05010C000E20099102000C000E100101000101010C000E01000C010E01000C020E01000C030E01000C040E2095024D000C000E4D010C000E20990251000C000E45010C000E20A10249000C000E3D010C000E20A90241000C000E35010C000E20B10239000C000E2D010C000E20B90231000C000E100101000101010C011001000C031001000C051001000C071001000C091001000D000F2069BD02000D000F69010D000F206DC102000D000F65010C011065000D000F2071C502000D000F71010D000F2075C902000D000F61010C011061000D000F2079D502000D000F79010D000F207DD902000D000F5D010C01105D000D000F208101E502000D000F8101010D000F208501E902000D000F59010C011059000D000F208901F502000D000F8901010D000F208D01F902000D000F55010C011055000D000F2091018503000D000F9101010D000F2095018903000D000F100101000101010C011001000C031001000C051001000C071001000C091001000D000F209503AD01000D000FAD01010D000F209903B101000D000FA901010C0110A901000D000F209D03B501000D000FB501010D000F20A103B901000D000FA501010C0110A501000D000F20AD03BD01000D000FBD01010D000F20B103C101000D000FA101010C0110A101000D000F20BD03C501000D000FC501010D000F20C103C901000D000F9D01010C01109D01000D000F20CD03CD01000D000FCD01010D000F20D103D101000D000F9901010C01109901000D000F20DD03D501000D000FD501010D000F20E103D901000D000F1001010001010107000820DD01ED0300070008DD010009018580808008DD0101050016ED030017028580808008ED03020500161001010001010107000820E101F10300070008E1010009018580808008E10101050016F1030017028580808008F103020500161001010001010107000820E501F50300070008E5010009018580808008E50101050016F5030017028580808008F503020500161001010001010107000820E901F90300070008E9010009018580808008E90101050016F9030017028580808008F90302050016 - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -46,7 +46,7 @@ Symbols: Type: STT_OBJECT Section: __llvm_covfun Binding: STB_WEAK - Size: 0x258 + Size: 0x38B Other: [ STV_HIDDEN ] - Name: __covrec_DB956436E78DD5FAu Type: STT_OBJECT 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 7665a88466ac8..1ed55c7475e5a 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-logical-mixed.cpp @@ -13,45 +13,45 @@ 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]]] - b4 && // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] - b5; // BRCOV: Branch ([[@LINE]]:12): [True: 0, False: 0] + bool c = b0 && // CHECK: Branch ([[@LINE]]:12): [True: [[C3:3|1]], False: 1] + b1 && // CHECK: Branch ([[@LINE]]:12): [True: [[C2:2|1]], False: 1] + b2 && // CHECK: Branch ([[@LINE]]:12): [True: [[C2]], False: 0] + b3 && // CHECK: Branch ([[@LINE]]:12): [True: 0, False: [[C2]]] + 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 d = b0 || // CHECK: Branch ([[@LINE]]:12): [True: [[C3]], 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 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 e = (b0 && // CHECK: Branch ([[@LINE]]:13): [True: [[C3]], False: 1] + b5) || // CHECK: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + (b1 && // CHECK: Branch ([[@LINE]]:13): [True: [[C2]], False: 1] + b4) || // CHECK: Branch ([[@LINE]]:13): [True: 0, False: [[C2]]] + (b2 && // CHECK: Branch ([[@LINE]]:13): [True: [[C3]], False: 0] + b3) || // CHECK: Branch ([[@LINE]]:13): [True: 0, False: [[C3]]] + (b3 && // CHECK: Branch ([[@LINE]]:13): [True: 0, False: [[C3]]] + b2) || // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 0] + (b4 && // CHECK: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + b1) || // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 1] + (b5 && // CHECK: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + b0); // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 1] - 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] + bool f = (b0 || // CHECK: Branch ([[@LINE]]:13): [True: [[C3]], False: 1] + b5) && // CHECK: Branch ([[@LINE]]:13): [True: 1, False: 0] + (b1 || // CHECK: Branch ([[@LINE]]:13): [True: [[C2]], False: [[C2]]] + b4) && // CHECK: Branch ([[@LINE]]:13): [True: 1, False: 1] + (b2 || // CHECK: Branch ([[@LINE]]:13): [True: [[C3]], False: 0] + b3) && // CHECK: Branch ([[@LINE]]:13): [True: 0, False: 0] + (b3 || // CHECK: Branch ([[@LINE]]:13): [True: 0, False: [[C3]]] + b2) && // CHECK: Branch ([[@LINE]]:13): [True: [[C3]], False: 0] + (b4 || // CHECK: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + b1) && // CHECK: Branch ([[@LINE]]:13): [True: [[C2]], False: 0] + (b5 || // CHECK: Branch ([[@LINE]]:13): [True: 1, False: [[C2]]] + b0); // CHECK: Branch ([[@LINE]]:13): [True: [[C2]], False: 0] if (c) // CHECK: Branch ([[@LINE]]:7): [True: 0, False: [[C4]]] printf("case0\n"); @@ -63,7 +63,7 @@ void func(int a, int b) { else printf("case3\n"); - if (e) // CHECK: Branch ([[@LINE]]:7): [True: 1, False: [[C3:3|1]]] + if (e) // CHECK: Branch ([[@LINE]]:7): [True: 1, False: [[C3]]] printf("case4\n"); else printf("case5\n"); diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.proftext b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.proftext index 29dc4ef3bf5c2..1643936583df4 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.proftext +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.proftext @@ -4,7 +4,7 @@ _Z4funcii # Func Hash: 456046650042366162 # Num Counters: -19 +37 # Counter Values: 3 1 @@ -25,12 +25,30 @@ _Z4funcii 0 0 0 +2 +1 +2 +1 +2 +1 +2 +1 +2 +1 +3 +0 +3 +0 +3 +0 +3 +0 _Z5func2ii # Func Hash: 14151920320560143107 # Num Counters: -9 +15 # Counter Values: 3 3 @@ -40,7 +58,13 @@ _Z5func2ii 0 1 0 +2 +1 3 +2 +1 +0 +1 main # Func Hash: diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml index 7545e311af7ab..2951ae89d2b8d 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros-single.yaml @@ -11,12 +11,12 @@ Sections: Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: F0A0ED2C305C0BB33F010000D238C8100334540693E696313ECE8F5D15010101010101010101010101010101010101010101001501101911020C010C0011140015001A100101005C1C010C0011100101006224010C001210010100682C010C0012100101006E34010C0012100101007401010A000B01000A001001000A001501000A001A45000F00103D00140015350019001A2D001E001F10010104550201050F001701000F00170105060F00170301070F001F3C00100015440019001E014C0910001501540A100016015C0B1000160201050F001701000F0017010D060F00170301070F001F64001000156C0019001E017409100015017C0A1000160201050F001701000F00170115060F00170301070F001F8401001000158C010019001E019401091000150201050F001701000F0017011D060F00170301070F001F9C0100100015A4010019001E0201050F001701000F00170125060F0017 + Content: F0A0ED2C305C0BB3AB010000D238C8100334540693E696313ECE8F5D15010101010101010101010101010101010101010101001A01101911020C010C0011140015001A100101005C1C010C0011100101006224010C001210010100682C010C0012100101006E34010C0012100101007401010A000B01000A001001000A001501000A001A204575000A000B45000F0010204979000F00103D001400152041810100140015350019001A203989010019001A2D001E001F20319101001E001F10010104550301050F001701000F001720054D000F00170205060F0017200951000F00170301070F001F3C00100015440019001E014C0910001501540A100016015C0B1000160301050F001701000F0017200D55000F0017020D060F0017201159000F00170301070F001F64001000156C0019001E017409100015017C0A1000160301050F001701000F001720155D000F00170215060F0017201961000F00170301070F001F8401001000158C010019001E019401091000150301050F001701000F0017201D65000F0017021D060F0017202169000F00170301070F001F9C0100100015A4010019001E0301050F001701000F001720256D000F00170225060F0017202971000F0017 - Name: '__llvm_covfun (1)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] AddressAlign: 0x8 - Content: B01D983FC67363959E000000039B9E2C8DB865C493E696313ECE8F5D0D01010101010101010101010101000401241A07020C010E0014140018001D1001010365011C0B1000160405080F002624001000152C0018001D3400200025013C0A1000160305070F001F44001000154C0019001E0115060F00170121050F00170154091000150205050F001705000F00170119060F00170401070F001F01000F001F5C00100015640019001E0201050F001701000F0017010D060F0017 + Content: B01D983FC6736395C1000000039B9E2C8DB865C493E696313ECE8F5D0D01010101010101010101010101000401241A07020C010E0014140018001D1001010365011C0B1000160505080F0026203909000F002624001000152C0018001D3400200025013C0A1000160305070F001F44001000154C0019001E0115060F00170129050F00170154091000150305050F001705000F001720192D000F00170219060F0017201D31000F00170401070F001F01000F001F5C00100015640019001E0301050F001701000F0017200D21000F0017020D060F0017201125000F0017 - Name: '__llvm_covfun (2)' Type: SHT_PROGBITS Flags: [ SHF_GNU_RETAIN ] @@ -52,13 +52,13 @@ Symbols: Type: STT_OBJECT Section: __llvm_covfun Binding: STB_WEAK - Size: 0x15B + Size: 0x1C7 Other: [ STV_HIDDEN ] - Name: __covrec_956373C63F981DB0u Type: STT_OBJECT Section: '__llvm_covfun (1)' Binding: STB_WEAK - Size: 0xBA + Size: 0xDD Other: [ STV_HIDDEN ] - Name: __covrec_DB956436E78DD5FAu Type: STT_OBJECT diff --git a/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp b/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp index e2abe748d86dc..47ed2b610fb99 100644 --- a/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp +++ b/llvm/test/tools/llvm-cov/Inputs/branch-macros.cpp @@ -14,31 +14,31 @@ // CHECK: |{{ +}}[[C3:3|1]]|bool func( bool func(int a, int b) { - 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] + bool c = COND1 && COND2; // CHECK: | | | Branch ([[@LINE-12]]:15): [True: 1, False: [[C2:2|1]]] + // CHECK: | | | Branch ([[@LINE-12]]:15): [True: 0, False: 1] + bool d = COND3; // CHECK: | | | | | Branch ([[@LINE-14]]:15): [True: 1, False: [[C2]]] + // CHECK: | | | | | Branch ([[@LINE-14]]:15): [True: 0, False: 1] + bool e = MACRO1; // CHECK: | | | | | | | Branch ([[@LINE-16]]:15): [True: 1, False: [[C2]]] + // CHECK: | | | | | | | Branch ([[@LINE-16]]:15): [True: 0, False: 1] + bool f = MACRO2; // CHECK: | | | | | | | | | Branch ([[@LINE-18]]:15): [True: 1, False: [[C2]]] + // CHECK: | | | | | | | | | Branch ([[@LINE-18]]:15): [True: 0, False: 1] + bool g = MACRO3; // CHECK: | | | | | | | | | | | Branch ([[@LINE-20]]:15): [True: 1, False: [[C2]]] + // CHECK: | | | | | | | | | | | 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-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] + // CHECK: | Branch ([[@LINE-1]]:10): [True: 0, False: [[C3]]] + // 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; // 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]]] + bool h = MACRO3 || COND4; // CHECK: | | | | | | | | | | | Branch ([[@LINE-32]]:15): [True: 1, False: [[C2]]] + // CHECK: | | | | | | | | | | | Branch ([[@LINE-32]]:15): [True: 0, False: 1] + // CHECK: | | | | | | | Branch ([[@LINE-34]]:15): [True: 1, False: [[C2]]] + // CHECK: | | | | | | | Branch ([[@LINE-34]]:15): [True: 0, False: 1] + // CHECK: | | | Branch ([[@LINE-33]]:15): [True: 1, False: [[C2]]] return h; } diff --git a/llvm/test/tools/llvm-cov/branch-logical-mixed.test b/llvm/test/tools/llvm-cov/branch-logical-mixed.test index b03cabeb01855..2e3a78ef4559d 100644 --- a/llvm/test/tools/llvm-cov/branch-logical-mixed.test +++ b/llvm/test/tools/llvm-cov/branch-logical-mixed.test @@ -1,5 +1,5 @@ // 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 // 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 diff --git a/llvm/test/tools/llvm-cov/branch-macros.test b/llvm/test/tools/llvm-cov/branch-macros.test index a4790afc53422..57666a96646d8 100644 --- a/llvm/test/tools/llvm-cov/branch-macros.test +++ b/llvm/test/tools/llvm-cov/branch-macros.test @@ -1,5 +1,5 @@ // 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 // 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 From eb7fff9a3b8356851770d1b5c6a4f0a69a79af05 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 21 Nov 2024 07:57:37 +0900 Subject: [PATCH 36/79] 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 37/79] 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 38/79] 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 39/79] 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 40/79] 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 ed700c2cb5b7ceac1bcf5ac0414a11d3148b9990 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 21 Dec 2024 17:49:06 +0900 Subject: [PATCH 41/79] s/replace/subst/ --- llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h | 6 +++--- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index a55ca997d47fd..dad5f1276f27c 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -215,10 +215,10 @@ class CounterExpressionBuilder { /// LHS. Counter subtract(Counter LHS, Counter RHS, bool Simplify = true); - using ReplaceMap = std::map; + using SubstMap = std::map; - /// Return a counter for each term in the expression replaced by ReplaceMap. - Counter replace(Counter C, const ReplaceMap &Map); + /// Return a counter for each term in the expression replaced by SubstMap. + Counter subst(Counter C, const SubstMap &Map); }; using LineColPair = std::pair; diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 6d6f03c360639..3f89414bdbbb9 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -135,7 +135,7 @@ Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS, return Simplify ? simplify(Cnt) : Cnt; } -Counter CounterExpressionBuilder::replace(Counter C, const ReplaceMap &Map) { +Counter CounterExpressionBuilder::subst(Counter C, const SubstMap &Map) { // Replace C with the value found in Map even if C is Expression. if (auto I = Map.find(C); I != Map.end()) return I->second; @@ -143,10 +143,9 @@ Counter CounterExpressionBuilder::replace(Counter C, const ReplaceMap &Map) { if (!C.isExpression()) return C; - // Traverse both sides of Expression. auto CE = Expressions[C.getExpressionID()]; - auto NewLHS = replace(CE.LHS, Map); - auto NewRHS = replace(CE.RHS, Map); + auto NewLHS = subst(CE.LHS, Map); + auto NewRHS = subst(CE.RHS, Map); // Reconstruct Expression with induced subexpressions. switch (CE.Kind) { From dbcf896f38c4c950abd23bf5fe8b9dff75476fef Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 21 Dec 2024 18:06:25 +0900 Subject: [PATCH 42/79] getSwitchImplicitDefaultCounterPair --- clang/lib/CodeGen/CoverageMappingGen.cpp | 27 ++++++++++++------------ 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index e63c38fcd4ba2..dff804fbeee92 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -944,12 +944,18 @@ struct CounterCoverageMappingBuilder return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; } - Counter getSwitchImplicitDefaultCounter(const Stmt *Cond, Counter ParentCount, - Counter CaseCountSum) { - if (llvm::EnableSingleByteCoverage) - CaseCountSum = Counter::getZero(); + /// Returns {TrueCnt,FalseCnt} for "implicit default". + /// FalseCnt is considered as the False count on SwitchStmt. + std::pair + getSwitchImplicitDefaultCounterPair(const Stmt *Cond, Counter ParentCount, + Counter CaseCountSum) { + // Simplify is skipped while building the counters above: it can get + // really slow on top of switches with thousands of cases. Instead, + // trigger simplification by adding zero to the last counter. + CaseCountSum = + addCounters(CaseCountSum, Counter::getZero(), /*Simplify=*/true); - return Builder.subtract(ParentCount, CaseCountSum); + return {CaseCountSum, Builder.subtract(ParentCount, CaseCountSum)}; } bool IsCounterEqual(Counter OutCount, Counter ParentCount) { @@ -1910,16 +1916,9 @@ struct CounterCoverageMappingBuilder // the hidden branch, which will be added later by the CodeGen. This region // will be associated with the switch statement's condition. if (!HasDefaultCase) { - // Simplify is skipped while building the counters above: it can get - // really slow on top of switches with thousands of cases. Instead, - // trigger simplification by adding zero to the last counter. - CaseCountSum = - addCounters(CaseCountSum, Counter::getZero(), /*Simplify=*/true); - - // This is considered as the False count on SwitchStmt. - Counter SwitchFalse = getSwitchImplicitDefaultCounter( + auto Counters = getSwitchImplicitDefaultCounterPair( S->getCond(), ParentCount, CaseCountSum); - createBranchRegion(S->getCond(), CaseCountSum, SwitchFalse); + createBranchRegion(S->getCond(), Counters.first, Counters.second); } } From c0785e91103db81b53e000834ce748d8d448e5ef Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sat, 21 Dec 2024 21:31:20 +0900 Subject: [PATCH 43/79] Fold either in switchcase --- clang/lib/CodeGen/CoverageMappingGen.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 238235f72d731..c66280c98e80d 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -964,6 +964,10 @@ struct CounterCoverageMappingBuilder std::pair getSwitchImplicitDefaultCounterPair(const Stmt *Cond, Counter ParentCount, Counter CaseCountSum) { + if (llvm::EnableSingleByteCoverage) + return {Counter::getZero(), // Folded + Counter::getCounter(CounterMap[Cond].second = NextCounterNum++)}; + // Simplify is skipped while building the counters above: it can get // really slow on top of switches with thousands of cases. Instead, // trigger simplification by adding zero to the last counter. @@ -1195,12 +1199,14 @@ struct CounterCoverageMappingBuilder /// and add it to the function's SourceRegions. /// Returns Counter that corresponds to SC. Counter createSwitchCaseRegion(const SwitchCase *SC, Counter ParentCount) { + Counter TrueCnt = getRegionCounter(SC); + Counter FalseCnt = (llvm::EnableSingleByteCoverage + ? Counter::getZero() // Folded + : subtractCounters(ParentCount, TrueCnt)); // Push region onto RegionStack but immediately pop it (which adds it to // the function's SourceRegions) because it doesn't apply to any other // source other than the SwitchCase. - Counter TrueCnt = getRegionCounter(SC); - popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(), - subtractCounters(ParentCount, TrueCnt))); + popRegions(pushRegion(TrueCnt, getStart(SC), SC->getColonLoc(), FalseCnt)); return TrueCnt; } From 24457a7236f5dc76e49c78817b5a0de6ce4f7f93 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Sun, 22 Dec 2024 00:42:02 +0900 Subject: [PATCH 44/79] 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 45/79] 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 46/79] 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 42c0c2616ebd115b8df40548ef252db57979a54d Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 23 Dec 2024 12:24:24 +0900 Subject: [PATCH 47/79] clang/test: Add tests that we missed while I was updating. --- .../CoverageMapping/single-byte-counters.cpp | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp index d20b695bc2636..4c0987eea4b98 100644 --- a/clang/test/CoverageMapping/single-byte-counters.cpp +++ b/clang/test/CoverageMapping/single-byte-counters.cpp @@ -33,6 +33,18 @@ int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+9]] return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C2E:#3]] } +// CHECK-NEXT: testIfBothReturn +int testIfBothReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+9]]:2 = [[C20:#0]] + int result = 0; + 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]] + return 42; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:14 = [[C2T]] + else // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:15 -> [[@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 = #3 + return -1; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:12 = #3 +} + // CHECK-NEXT: testSwitch int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+17]]:2 = [[C30:#0]] int result; @@ -67,18 +79,23 @@ int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+11]]:2 = return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C4E:#3]] } -// CHECK-NEXT: testContinue -int testContinue() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+15]]:2 = [[C50:#0]] +// CHECK-NEXT: testContinueBreak +int testContinueBreak() { // CHECK-NEXT: File 0, [[@LINE]]:25 -> [[@LINE+20]]:2 = #0 int i = 0; int sum = 0; - while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = [[C5C:#1]] + while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = #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]] + // CHECK-NEXT: File 0, [[@LINE-2]]:18 -> [[@LINE+12]]: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]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+2]]:5 = [[C5F:#5]] + // CHECK-NEXT: File 0, [[@LINE+1]]:5 -> [[@LINE+7]]:4 = [[C5F]] + if (i == 5) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = [[C5F]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:7 = [[C5T1:#6]] + break; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = [[C5T1]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:5 = [[C5F1:#7]] + sum += i; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = [[C5F1]] i++; } // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C5E:#3]] From bd1d96bb23b264f4976ce800470dd7ed7f74a709 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 23 Dec 2024 12:26:29 +0900 Subject: [PATCH 48/79] Introduce CounterMappingRegion::isBranch(). NFC. Conflicts: clang/lib/CodeGen/CoverageMappingGen.cpp llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h --- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 63be03f231841..b2f4087465308 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -637,8 +637,7 @@ static unsigned getMaxCounterID(const CounterMappingContext &Ctx, unsigned MaxCounterID = 0; for (const auto &Region : Record.MappingRegions) { MaxCounterID = std::max(MaxCounterID, Ctx.getMaxCounterID(Region.Count)); - if (Region.Kind == CounterMappingRegion::BranchRegion || - Region.Kind == CounterMappingRegion::MCDCBranchRegion) + if (Region.isBranch()) MaxCounterID = std::max(MaxCounterID, Ctx.getMaxCounterID(Region.FalseCount)); } From 621263cfb4c13cc30bdfc7347b0c57be353910b1 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 23 Dec 2024 12:34:43 +0900 Subject: [PATCH 49/79] Update the test --- .../CoverageMapping/single-byte-counters.cpp | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp index 74aab4fc31f3d..998cc0d4b4d11 100644 --- a/clang/test/CoverageMapping/single-byte-counters.cpp +++ b/clang/test/CoverageMapping/single-byte-counters.cpp @@ -33,6 +33,18 @@ int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+9]] return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C2E:#3]] } +// CHECK-NEXT: testIfBothReturn +int testIfBothReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+9]]:2 = [[C20:#0]] + int result = 0; + 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]] + return 42; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:14 = [[C2T]] + else // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:15 -> [[@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 = #3 + return -1; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:12 = #3 +} + // CHECK-NEXT: testSwitch int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+17]]:2 = [[C30:#0]] int result; @@ -68,23 +80,28 @@ int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+12]]:2 = return sum; // #0 } -// CHECK-NEXT: testContinue -int testContinue() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+16]]:2 = [[C50:#0]] +// CHECK-NEXT: testContinueBreak +int testContinueBreak() { // CHECK-NEXT: File 0, [[@LINE]]:25 -> [[@LINE+21]]:2 = [[C50:#0]] int i = 0; int sum = 0; - while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = (([[C50]] + [[C5T:#2]]) + [[C5F:#3]]) - // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:10 -> [[@LINE-1]]:16 = [[C5B:#1]], [[C5E:#4]] + while (i < 10) { // CHECK-NEXT: File 0, [[@LINE]]:10 -> [[@LINE]]:16 = (([[C50]] + [[C5T:#2]]) + [[C5F1:#5]]) + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:10 -> [[@LINE-1]]:16 = [[C5B:#1]], [[C5E:#6]] // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:17 -> [[@LINE-2]]:18 = [[C5B]] - // CHECK-NEXT: File 0, [[@LINE-3]]:18 -> [[@LINE+7]]:4 = [[C5B]] + // CHECK-NEXT: File 0, [[@LINE-3]]:18 -> [[@LINE+12]]: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]] continue; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = [[C5T]] - // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:5 = [[C5F]] - sum += i; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = [[C5F]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+2]]:5 = [[C5F:#3]] + // CHECK-NEXT: File 0, [[@LINE+1]]:5 -> [[@LINE+7]]:4 = [[C5F]] + if (i == 5) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = [[C5F]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:7 = [[C5T1:#4]] + break; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = [[C5T1]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:5 = [[C5F1]] + sum += i; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = [[C5F1]] i++; } - // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C5E]] - return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C5E]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = ([[C5T1]] + [[C5E]]) + return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = ([[C5T1]] + [[C5E]]) } // CHECK-NEXT: testFor From 747478eaff0dece607a25298652382b465ecc0e6 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 23 Dec 2024 12:40:32 +0900 Subject: [PATCH 50/79] Update the test --- .../CoverageMapping/single-byte-counters.cpp | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp index 533f791eee19e..e066c672295a9 100644 --- a/clang/test/CoverageMapping/single-byte-counters.cpp +++ b/clang/test/CoverageMapping/single-byte-counters.cpp @@ -36,6 +36,19 @@ int testIfElseReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+10] return result; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:16 = [[C2T]] } +// CHECK-NEXT: testIfBothReturn +int testIfBothReturn(int x) { // CHECK-NEXT: File 0, [[@LINE]]:29 -> [[@LINE+10]]:2 = [[C20:#0]] + int result = 0; + if (x > 0) // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = [[C20]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:7 -> [[@LINE-1]]:12 = [[C2T:#1]], [[C2F:#2]] + // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:13 -> [[@LINE+1]]:5 = [[C2T]] + return 42; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:14 = [[C2T]] + else // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:15 -> [[@LINE+1]]:5 = [[C2F]] + return 0; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE]]:13 = [[C2F]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:14 -> [[@LINE+1]]:3 = 0 + return -1; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:12 = 0 +} + // CHECK-NEXT: testSwitch int testSwitch(int x) { // CHECK-NEXT: File 0, [[@LINE]]:23 -> [[@LINE+17]]:2 = [[C30:#0]] int result; @@ -70,19 +83,25 @@ int testWhile() { // CHECK-NEXT: File 0, [[@LINE]]:17 -> [[@LINE+11]]:2 = return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = [[C4E:#3]] } -// CHECK-NEXT: testContinue -int testContinue() { // CHECK-NEXT: File 0, [[@LINE]]:20 -> [[@LINE+16]]:2 = [[C50:#0]] +// CHECK-NEXT: testContinueBreak +int testContinueBreak() { // CHECK-NEXT: File 0, [[@LINE]]:25 -> [[@LINE+22]]:2 = #0 int i = 0; int sum = 0; 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+8]]:4 = [[C5B]] + // CHECK-NEXT: File 0, [[@LINE-2]]:18 -> [[@LINE+14]]:4 = [[C5B]] if (i == 4) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = [[C5B]] - // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:15 = [[C5T:#4]], [[C5F:#5]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:15 = [[C5T:#4]], [[C5F:#6]] // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:16 -> [[@LINE+1]]:7 = [[C5T]] continue; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:15 = [[C5T]] - // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+1]]:5 = [[C5F]] - sum += i; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = [[C5F]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:16 -> [[@LINE+2]]:5 = [[C5F]] + // CHECK-NEXT: File 0, [[@LINE+1]]:5 -> [[@LINE+8]]:4 = [[C5F]] + if (i == 5) // CHECK-NEXT: File 0, [[@LINE]]:9 -> [[@LINE]]:15 = [[C5F]] + // CHECK-NEXT: Branch,File 0, [[@LINE-1]]:9 -> [[@LINE-1]]:15 = [[C5T1:#5]], [[C5F1:#7]] + // CHECK-NEXT: Gap,File 0, [[@LINE-2]]:16 -> [[@LINE+1]]:7 = [[C5T1]] + break; // CHECK-NEXT: File 0, [[@LINE]]:7 -> [[@LINE]]:12 = [[C5T1]] + // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:13 -> [[@LINE+1]]:5 = [[C5F1]] + sum += i; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = [[C5F1]] i++; } // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = [[C5E:#3]] From f4dc4ebfd585869455be0e9f37294b7037ca9a65 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 23 Dec 2024 15:57:36 +0900 Subject: [PATCH 51/79] 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 52/79] 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 4e41b99fdf41094a85bf473d27d57c527b91a0d8 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 24 Dec 2024 15:53:14 +0900 Subject: [PATCH 53/79] Introduce BranchCounterPair --- clang/lib/CodeGen/CoverageMappingGen.cpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index dff804fbeee92..df29c2cb4ee17 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -938,8 +938,12 @@ struct CounterCoverageMappingBuilder return Counter::getCounter(CounterMap[S]); } - std::pair getBranchCounterPair(const Stmt *S, - Counter ParentCnt) { + struct BranchCounterPair { + Counter Executed; + Counter Skipped; + }; + + BranchCounterPair getBranchCounterPair(const Stmt *S, Counter ParentCnt) { Counter ExecCnt = getRegionCounter(S); return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; } @@ -1617,7 +1621,7 @@ struct CounterCoverageMappingBuilder : addCounters(ParentCount, BackedgeCount, BC.ContinueCount); auto [ExecCount, ExitCount] = (llvm::EnableSingleByteCoverage - ? std::make_pair(getRegionCounter(S), Counter::getZero()) + ? BranchCounterPair{getRegionCounter(S), Counter::getZero()} : getBranchCounterPair(S, CondCount)); if (!llvm::EnableSingleByteCoverage) { assert(ExecCount.isZero() || ExecCount == BodyCount); @@ -1674,7 +1678,7 @@ struct CounterCoverageMappingBuilder : addCounters(BackedgeCount, BC.ContinueCount); auto [ExecCount, ExitCount] = (llvm::EnableSingleByteCoverage - ? std::make_pair(getRegionCounter(S), Counter::getZero()) + ? BranchCounterPair{getRegionCounter(S), Counter::getZero()} : getBranchCounterPair(S, CondCount)); if (!llvm::EnableSingleByteCoverage) { assert(ExecCount.isZero() || ExecCount == BodyCount); @@ -1742,7 +1746,7 @@ struct CounterCoverageMappingBuilder IncrementBC.ContinueCount); auto [ExecCount, ExitCount] = (llvm::EnableSingleByteCoverage - ? std::make_pair(getRegionCounter(S), Counter::getZero()) + ? BranchCounterPair{getRegionCounter(S), Counter::getZero()} : getBranchCounterPair(S, CondCount)); if (!llvm::EnableSingleByteCoverage) { assert(ExecCount.isZero() || ExecCount == BodyCount); @@ -2049,9 +2053,9 @@ struct CounterCoverageMappingBuilder Counter ParentCount = getRegion().getCounter(); auto [ThenCount, ElseCount] = (llvm::EnableSingleByteCoverage - ? std::make_pair(getRegionCounter(S->getThen()), - (S->getElse() ? getRegionCounter(S->getElse()) - : Counter::getZero())) + ? BranchCounterPair{getRegionCounter(S->getThen()), + (S->getElse() ? getRegionCounter(S->getElse()) + : Counter::getZero())} : getBranchCounterPair(S, ParentCount)); // Emitting a counter for the condition makes it easier to interpret the @@ -2124,8 +2128,8 @@ struct CounterCoverageMappingBuilder Counter ParentCount = getRegion().getCounter(); auto [TrueCount, FalseCount] = (llvm::EnableSingleByteCoverage - ? std::make_pair(getRegionCounter(E->getTrueExpr()), - getRegionCounter(E->getFalseExpr())) + ? BranchCounterPair{getRegionCounter(E->getTrueExpr()), + getRegionCounter(E->getFalseExpr())} : getBranchCounterPair(E, ParentCount)); Counter OutCount; From 306d77f3d9afdbb832f920e920008c719a3a3533 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 24 Dec 2024 15:58:13 +0900 Subject: [PATCH 54/79] void verifyCounterMap() const --- clang/lib/CodeGen/CodeGenPGO.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h index 83f35785e5327..9429b6b465207 100644 --- a/clang/lib/CodeGen/CodeGenPGO.h +++ b/clang/lib/CodeGen/CodeGenPGO.h @@ -131,7 +131,7 @@ class CodeGenPGO { // Do nothing. } - void verifyCounterMap() { + void verifyCounterMap() const { // Do nothing. } From a4f05c7a5ca60b8ed2eaf5337cdd04bab25e8170 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 24 Dec 2024 15:58:13 +0900 Subject: [PATCH 55/79] Introduce the dedicated class CounterPair instead of std::pair --- clang/lib/CodeGen/CodeGenFunction.h | 4 +- clang/lib/CodeGen/CodeGenModule.h | 53 +++++++++++++++++------- clang/lib/CodeGen/CodeGenPGO.cpp | 11 +++-- clang/lib/CodeGen/CodeGenPGO.h | 2 +- clang/lib/CodeGen/CoverageMappingGen.cpp | 2 +- 5 files changed, 50 insertions(+), 22 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 0396fa5bef136..87d016a0729ad 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1620,9 +1620,7 @@ class CodeGenFunction : public CodeGenTypeCache { uint64_t LoopCount) const; public: - std::pair getIsCounterPair(const Stmt *S) const { - return PGO.getIsCounterPair(S); - } + auto getIsCounterPair(const Stmt *S) const { return PGO.getIsCounterPair(S); } void markStmtAsUsed(bool Skipped, const Stmt *S) { PGO.markStmtAsUsed(Skipped, S); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 8990ee13991e9..d5ef1a710eb40 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -102,23 +102,48 @@ enum ForDefinition_t : bool { ForDefinition = true }; -class CounterPair : public std::pair { -private: - static constexpr uint32_t None = (1u << 31); /// None is set - +/// The Counter with an optional additional Counter for +/// branches. `Skipped` counter can be calculated with `Executed` and +/// a common Counter (like `Parent`) as `(Parent-Executed)`. +/// +/// In SingleByte mode, Counters are binary. Subtraction is not +/// applicable (but addition is capable). In this case, both +/// `Executed` and `Skipped` counters are required. `Skipped` is +/// `None` by default. It is allocated in the coverage mapping. +/// +/// There might be cases that `Parent` could be induced with +/// `(Executed+Skipped)`. This is not always applicable. +class CounterPair { public: - static constexpr uint32_t Mask = None - 1; + /// Optional value. + class ValueOpt { + private: + static constexpr uint32_t None = (1u << 31); /// None is allocated. + static constexpr uint32_t Mask = None - 1; -public: - CounterPair(unsigned Val = 0) { - assert(!(Val & ~Mask)); - first = Val; - second = None; - } + uint32_t Val; - std::pair getIsCounterPair() const { - return {!(first & None), !(second & None)}; - } + public: + ValueOpt() : Val(None) {} + + ValueOpt(unsigned InitVal) { + assert(!(InitVal & ~Mask)); + Val = InitVal; + } + + bool hasValue() const { return !(Val & None); } + + operator uint32_t() const { return Val; } + }; + + ValueOpt Executed; + ValueOpt Skipped; /// May be None. + + /// Initialized with Skipped=None. + CounterPair(unsigned Val) : Executed(Val) {} + + // FIXME: Should work with {None, None} + CounterPair() : Executed(0) {} }; struct OrderGlobalInitsOrStermFinalizers { diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 75191f86d231c..792373839107f 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -1186,9 +1186,14 @@ CodeGenPGO::applyFunctionAttributes(llvm::IndexedInstrProfReader *PGOReader, } std::pair CodeGenPGO::getIsCounterPair(const Stmt *S) const { - if (!RegionCounterMap || RegionCounterMap->count(S) == 0) + if (!RegionCounterMap) return {false, false}; - return (*RegionCounterMap)[S].getIsCounterPair(); + + auto I = RegionCounterMap->find(S); + if (I == RegionCounterMap->end()) + return {false, false}; + + return {I->second.Executed.hasValue(), I->second.Skipped.hasValue()}; } void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, @@ -1196,7 +1201,7 @@ void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, if (!RegionCounterMap || !Builder.GetInsertBlock()) return; - unsigned Counter = (*RegionCounterMap)[S].first; + unsigned Counter = (*RegionCounterMap)[S].Executed; // Make sure that pointer to global is passed in with zero addrspace // This is relevant during GPU profiling diff --git a/clang/lib/CodeGen/CodeGenPGO.h b/clang/lib/CodeGen/CodeGenPGO.h index 9429b6b465207..1944b640951d5 100644 --- a/clang/lib/CodeGen/CodeGenPGO.h +++ b/clang/lib/CodeGen/CodeGenPGO.h @@ -143,7 +143,7 @@ class CodeGenPGO { return 0; // With profiles from a differing version of clang we can have mismatched // decl counts. Don't crash in such a case. - auto Index = (*RegionCounterMap)[S].first; + auto Index = (*RegionCounterMap)[S].Executed; if (Index >= RegionCounts.size()) return 0; return RegionCounts[Index]; diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 9c191e9394769..6433f930ae41e 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -935,7 +935,7 @@ struct CounterCoverageMappingBuilder /// /// This should only be called on statements that have a dedicated counter. Counter getRegionCounter(const Stmt *S) { - return Counter::getCounter(CounterMap[S].first); + return Counter::getCounter(CounterMap[S].Executed); } /// Push a region onto the stack. From f6c5f4017cc48534d2c3adc68a7c3d97ad45d156 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 24 Dec 2024 16:13:54 +0900 Subject: [PATCH 56/79] Catch up the merge --- clang/lib/CodeGen/CodeGenPGO.cpp | 24 +++++++++++++++------- clang/lib/CodeGen/CoverageMappingGen.cpp | 26 +++++++++++++++++++++--- 2 files changed, 40 insertions(+), 10 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenPGO.cpp b/clang/lib/CodeGen/CodeGenPGO.cpp index 03856795ca51a..ffb1df9ec2cc6 100644 --- a/clang/lib/CodeGen/CodeGenPGO.cpp +++ b/clang/lib/CodeGen/CodeGenPGO.cpp @@ -1140,13 +1140,10 @@ void CodeGenPGO::emitCounterRegionMapping(const Decl *D) { // Scan max(FalseCnt) and update NumRegionCounters. unsigned MaxNumCounters = NumRegionCounters; for (const auto [_, V] : *RegionCounterMap) { - auto HasCounters = V.getIsCounterPair(); - assert((!HasCounters.first || - MaxNumCounters > (V.first & CounterPair::Mask)) && + assert((!V.Executed.hasValue() || MaxNumCounters > V.Executed) && "TrueCnt should not be reassigned"); - if (HasCounters.second) - MaxNumCounters = - std::max(MaxNumCounters, (V.second & CounterPair::Mask) + 1); + if (V.Skipped.hasValue()) + MaxNumCounters = std::max(MaxNumCounters, V.Skipped + 1); } NumRegionCounters = MaxNumCounters; @@ -1215,7 +1212,20 @@ void CodeGenPGO::emitCounterSetOrIncrement(CGBuilderTy &Builder, const Stmt *S, if (!RegionCounterMap) return; - unsigned Counter = (*RegionCounterMap)[S].Executed; + unsigned Counter; + auto &TheMap = (*RegionCounterMap)[S]; + if (!UseSkipPath) { + if (!TheMap.Executed.hasValue()) + return; + Counter = TheMap.Executed; + } else { + if (!TheMap.Skipped.hasValue()) + return; + Counter = TheMap.Skipped; + } + + if (!Builder.GetInsertBlock()) + return; // Make sure that pointer to global is passed in with zero addrspace // This is relevant during GPU profiling diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index e0aa752bcbe9a..0764345af0b32 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -943,8 +943,27 @@ struct CounterCoverageMappingBuilder }; BranchCounterPair getBranchCounterPair(const Stmt *S, Counter ParentCnt) { - Counter ExecCnt = getRegionCounter(S); - return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; + auto &TheMap = CounterMap[S]; + auto ExecCnt = Counter::getCounter(TheMap.Executed); + BranchCounterPair Counters = {ExecCnt, + Builder.subtract(ParentCnt, ExecCnt)}; + + if (!llvm::EnableSingleByteCoverage || !Counters.Skipped.isExpression()) { + assert( + !TheMap.Skipped.hasValue() && + "SkipCnt shouldn't be allocated but refer to an existing counter."); + return Counters; + } + + // Assign second if second is not assigned yet. + if (!TheMap.Skipped.hasValue()) + TheMap.Skipped = NextCounterNum++; + + // Replace an expression (ParentCnt - ExecCnt) with SkipCnt. + Counter SkipCnt = Counter::getCounter(TheMap.Skipped); + MapToExpand[SkipCnt] = Counters.Skipped; + Counters.Skipped = SkipCnt; + return Counters; } /// Returns {TrueCnt,FalseCnt} for "implicit default". @@ -953,8 +972,9 @@ struct CounterCoverageMappingBuilder getSwitchImplicitDefaultCounterPair(const Stmt *Cond, Counter ParentCount, Counter CaseCountSum) { if (llvm::EnableSingleByteCoverage) + // Allocate the new Counter since `subtract(Parent - Sum)` is unavailable. return {Counter::getZero(), // Folded - Counter::getCounter(CounterMap[Cond].second = NextCounterNum++)}; + Counter::getCounter(CounterMap[Cond].Skipped = NextCounterNum++)}; // Simplify is skipped while building the counters above: it can get // really slow on top of switches with thousands of cases. Instead, From aca86d451ab886951a260c171c63c313522266d2 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 24 Dec 2024 16:13:54 +0900 Subject: [PATCH 57/79] Introduce {UseExecPath, UseSkipPath} instead of {false, true} --- clang/lib/CodeGen/CodeGenFunction.h | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 425fce241b983..6145c6a627fc8 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -1627,20 +1627,31 @@ class CodeGenFunction : public CodeGenTypeCache { } void markStmtMaybeUsed(const Stmt *S) { PGO.markStmtMaybeUsed(S); } + enum CounterForIncrement { + UseExecPath = 0, + UseSkipPath, + }; + /// Increment the profiler's counter for the given statement by \p StepV. /// If \p StepV is null, the default increment is 1. void incrementProfileCounter(const Stmt *S, llvm::Value *StepV = nullptr) { - incrementProfileCounter(false, S, false, StepV); + incrementProfileCounter(UseExecPath, S, false, StepV); } - void incrementProfileCounter(bool UseSkipPath, const Stmt *S, + /// Emit increment of Counter. + /// \param ExecSkip Use `Skipped` Counter if UseSkipPath is specified. + /// \param S The Stmt that Counter is associated. + /// \param UseBoth Mark both Exec/Skip as used. (for verification) + /// \param StepV The offset Value for adding to Counter. + void incrementProfileCounter(CounterForIncrement ExecSkip, const Stmt *S, bool UseBoth = false, llvm::Value *StepV = nullptr) { if (CGM.getCodeGenOpts().hasProfileClangInstr() && !CurFn->hasFnAttribute(llvm::Attribute::NoProfile) && !CurFn->hasFnAttribute(llvm::Attribute::SkipProfile)) { auto AL = ApplyDebugLocation::CreateArtificial(*this); - PGO.emitCounterSetOrIncrement(Builder, S, UseSkipPath, UseBoth, StepV); + PGO.emitCounterSetOrIncrement(Builder, S, (ExecSkip == UseSkipPath), + UseBoth, StepV); } PGO.setCurrentStmt(S); } From 1adf497fdf5dfafa139bc259bcf390e03535c459 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 24 Dec 2024 16:20:30 +0900 Subject: [PATCH 58/79] Eliminate (rewind) "refactor" changes --- .../ProfileData/Coverage/CoverageMapping.h | 34 ++++++++----------- .../ProfileData/Coverage/CoverageMapping.cpp | 25 ++++++++------ llvm/tools/llvm-cov/CodeCoverage.cpp | 6 ---- llvm/tools/llvm-cov/CoverageViewOptions.h | 1 - llvm/tools/llvm-cov/SourceCoverageView.h | 10 +----- .../tools/llvm-cov/SourceCoverageViewHTML.cpp | 15 ++++---- .../tools/llvm-cov/SourceCoverageViewText.cpp | 6 ++-- 7 files changed, 39 insertions(+), 58 deletions(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index 6db308fe1b106..dad5f1276f27c 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -370,16 +370,19 @@ struct CountedRegion : public CounterMappingRegion { uint64_t FalseExecutionCount; bool TrueFolded; bool FalseFolded; + bool HasSingleByteCoverage; - CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount) + CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount, + bool HasSingleByteCoverage) : CounterMappingRegion(R), ExecutionCount(ExecutionCount), - FalseExecutionCount(0), TrueFolded(false), FalseFolded(true) {} + FalseExecutionCount(0), TrueFolded(false), FalseFolded(true), + HasSingleByteCoverage(HasSingleByteCoverage) {} CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount, - uint64_t FalseExecutionCount) + uint64_t FalseExecutionCount, bool HasSingleByteCoverage) : CounterMappingRegion(R), ExecutionCount(ExecutionCount), FalseExecutionCount(FalseExecutionCount), TrueFolded(false), - FalseFolded(false) {} + FalseFolded(false), HasSingleByteCoverage(HasSingleByteCoverage) {} }; /// MCDC Record grouping all information together. @@ -722,9 +725,10 @@ struct FunctionRecord { } void pushRegion(CounterMappingRegion Region, uint64_t Count, - uint64_t FalseCount) { + uint64_t FalseCount, bool HasSingleByteCoverage) { if (Region.isBranch()) { - CountedBranchRegions.emplace_back(Region, Count, FalseCount); + CountedBranchRegions.emplace_back(Region, Count, FalseCount, + HasSingleByteCoverage); // If either counter is hard-coded to zero, then this region represents a // constant-folded branch. CountedBranchRegions.back().TrueFolded = Region.Count.isZero(); @@ -733,7 +737,8 @@ struct FunctionRecord { } if (CountedRegions.empty()) ExecutionCount = Count; - CountedRegions.emplace_back(Region, Count, FalseCount); + CountedRegions.emplace_back(Region, Count, FalseCount, + HasSingleByteCoverage); } }; @@ -896,19 +901,14 @@ class CoverageData { std::vector BranchRegions; std::vector MCDCRecords; - bool SingleByteCoverage; - public: - CoverageData() = delete; + CoverageData() = default; - CoverageData(bool Single, StringRef Filename = StringRef()) - : Filename(Filename), SingleByteCoverage(Single) {} + CoverageData(StringRef Filename) : Filename(Filename) {} /// 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 { @@ -941,9 +941,7 @@ class CoverageMapping { DenseMap> FilenameHash2RecordIndices; std::vector> FuncHashMismatches; - bool SingleByteCoverage; - - CoverageMapping(bool Single) : SingleByteCoverage(Single) {} + CoverageMapping() = default; // Load coverage records from readers. static Error loadFromReaders( @@ -987,8 +985,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 diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 27f2ebe180f45..4bb28d47888fa 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -983,8 +983,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); @@ -1046,8 +1045,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) { @@ -1330,8 +1328,14 @@ 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) - Active->ExecutionCount += I->ExecutionCount; + 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; + } } return Regions.drop_back(std::distance(++Active, End)); } @@ -1424,7 +1428,7 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) { } CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const { - CoverageData FileCoverage(SingleByteCoverage, Filename); + CoverageData FileCoverage(Filename); std::vector Regions; // Look up the function records in the given file. Due to hash collisions on @@ -1486,10 +1490,9 @@ CoverageData CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { auto MainFileID = findMainViewFileID(Function); if (!MainFileID) - return CoverageData(SingleByteCoverage); + return CoverageData(); - CoverageData FunctionCoverage(SingleByteCoverage, - Function.Filenames[*MainFileID]); + CoverageData FunctionCoverage(Function.Filenames[*MainFileID]); std::vector Regions; for (const auto &CR : Function.CountedRegions) if (CR.FileID == *MainFileID) { @@ -1517,7 +1520,7 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const { CoverageData CoverageMapping::getCoverageForExpansion( const ExpansionRecord &Expansion) const { CoverageData ExpansionCoverage( - SingleByteCoverage, Expansion.Function.Filenames[Expansion.FileID]); + 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/CodeCoverage.cpp b/llvm/tools/llvm-cov/CodeCoverage.cpp index 0e8360a4ac6ed..5db5c2e023541 100644 --- a/llvm/tools/llvm-cov/CodeCoverage.cpp +++ b/llvm/tools/llvm-cov/CodeCoverage.cpp @@ -1023,11 +1023,6 @@ 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( @@ -1105,7 +1100,6 @@ 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 81e69c3814e30..015c92a1656be 100644 --- a/llvm/tools/llvm-cov/CoverageViewOptions.h +++ b/llvm/tools/llvm-cov/CoverageViewOptions.h @@ -45,7 +45,6 @@ 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 ed7e133d71e08..2b1570d399dd0 100644 --- a/llvm/tools/llvm-cov/SourceCoverageView.h +++ b/llvm/tools/llvm-cov/SourceCoverageView.h @@ -180,8 +180,6 @@ class SourceCoverageView { /// on display. std::vector InstantiationSubViews; - bool BinaryCounters; - /// Get the first uncovered line number for the source file. unsigned getFirstUncoveredLineNo(); @@ -268,10 +266,6 @@ 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; @@ -282,9 +276,7 @@ class SourceCoverageView { const CoverageViewOptions &Options, CoverageData &&CoverageInfo) : SourceName(SourceName), File(File), Options(Options), - CoverageInfo(std::move(CoverageInfo)), - BinaryCounters(Options.BinaryCounters || - CoverageInfo.getSingleByteCoverage()) {} + CoverageInfo(std::move(CoverageInfo)) {} public: static std::unique_ptr diff --git a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp index f3aa7e801597c..e2be576b93cda 100644 --- a/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp +++ b/llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp @@ -1019,22 +1019,19 @@ 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 (CurSegCount == LCSCount) + if (CurSeg->Count == LCS.getExecutionCount()) continue; Snippets[I + 1] = - tag("div", - Snippets[I + 1] + - tag("span", formatCount(CurSegCount), "tooltip-content"), + tag("div", Snippets[I + 1] + tag("span", formatCount(CurSeg->Count), + "tooltip-content"), "tooltip"); if (getOptions().Debug) errs() << "Marker at " << CurSeg->Line << ":" << CurSeg->Col << " = " - << formatCount(CurSegCount) << "\n"; + << formatCount(CurSeg->Count) << "\n"; } } @@ -1054,7 +1051,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", formatCount(Line.getExecutionCount())); std::string CoverageClass = (Line.getExecutionCount() > 0) ? "covered-line" @@ -1109,7 +1106,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", formatCount(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..63f8248e3387b 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 = formatCount(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"; + << formatCount(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 << ": " << formatCount(Count); else OS << ": " << format("%0.2f", (Total != 0 ? 100.0 * Count / Total : 0.0)) << "%"; From dfc99bad0fd0baa6e0d9a39554da041dd02d6568 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 24 Dec 2024 17:29:27 +0900 Subject: [PATCH 59/79] 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 60/79] 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 61/79] 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 28c568ad84edbfb4eb4bc7841c8c6b39e9722094 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 6 Jan 2025 23:37:50 +0900 Subject: [PATCH 62/79] Add a test --- .../ProfileData/CoverageMappingTest.cpp | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/llvm/unittests/ProfileData/CoverageMappingTest.cpp b/llvm/unittests/ProfileData/CoverageMappingTest.cpp index ef147674591c5..46f881ecddb5f 100644 --- a/llvm/unittests/ProfileData/CoverageMappingTest.cpp +++ b/llvm/unittests/ProfileData/CoverageMappingTest.cpp @@ -291,6 +291,45 @@ struct CoverageMappingTest : ::testing::TestWithParam> { } }; +TEST(CoverageMappingTest, expression_subst) { + CounterExpressionBuilder Builder; + CounterExpressionBuilder::SubstMap MapToExpand; + + auto C = [](unsigned ID) { return Counter::getCounter(ID); }; + auto A = [&](Counter LHS, Counter RHS) { return Builder.add(LHS, RHS); }; + // returns {E, N} in clangCodeGen + auto getBranchCounterPair = [&](Counter E, Counter P, Counter N) { + auto Skipped = Builder.subtract(P, E); + MapToExpand[N] = Builder.subst(Skipped, MapToExpand); + }; + + auto E18 = C(5); + auto P18 = C(2); + auto S18 = C(18); + // #18 => (#2 - #5) + getBranchCounterPair(E18, P18, S18); + + auto E22 = S18; + auto P22 = C(0); + auto S22 = C(22); + // #22 => #0 - (#2 - #5) + getBranchCounterPair(E22, P22, S22); + + auto E28 = A(A(C(9), C(11)), C(14)); + auto P28 = S22; + auto S28 = C(28); + // #28 => (((((#0 + #5) - #2) - #9) - #11) - #14) + getBranchCounterPair(E28, P28, S28); + + auto LHS = A(E28, A(S28, S18)); + auto RHS = C(0); + + // W/o subst, LHS cannot be reduced. + ASSERT_FALSE(Builder.subtract(LHS, RHS).isZero()); + // W/ subst, C(18) and C(28) in LHS will be reduced. + ASSERT_TRUE(Builder.subst(Builder.subtract(LHS, RHS), MapToExpand).isZero()); +} + TEST_P(CoverageMappingTest, basic_write_read) { startFunction("func", 0x1234); addCMR(Counter::getCounter(0), "foo", 1, 1, 1, 1); From d92a9d9c74814fc48c1ff5523d5215115021ac40 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Mon, 6 Jan 2025 23:38:11 +0900 Subject: [PATCH 63/79] Prune redundant logic --- llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 3f89414bdbbb9..87d305fc53636 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -157,10 +157,6 @@ Counter CounterExpressionBuilder::subst(Counter C, const SubstMap &Map) { break; } - // Reconfirm if the reconstructed expression would hit the Map. - if (auto I = Map.find(C); I != Map.end()) - return I->second; - return C; } From 82f2e92642fc00e0c07ed3c6506769319c39609a Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 7 Jan 2025 00:06:11 +0900 Subject: [PATCH 64/79] Expand RHS of MapToExpand. This will prevent recursion. --- clang/lib/CodeGen/CoverageMappingGen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 0764345af0b32..a00166881caaa 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -961,7 +961,7 @@ struct CounterCoverageMappingBuilder // Replace an expression (ParentCnt - ExecCnt) with SkipCnt. Counter SkipCnt = Counter::getCounter(TheMap.Skipped); - MapToExpand[SkipCnt] = Counters.Skipped; + MapToExpand[SkipCnt] = Builder.subst(Counters.Skipped, MapToExpand); Counters.Skipped = SkipCnt; return Counters; } From b90fdf61748ad0d585dc48987e5545878da98c59 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 7 Jan 2025 00:06:11 +0900 Subject: [PATCH 65/79] Append an explanation in the comment --- clang/lib/CodeGen/CoverageMappingGen.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index a00166881caaa..bd495f84793f6 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -990,6 +990,14 @@ struct CounterCoverageMappingBuilder return true; // Try comaparison with pre-replaced expressions. + // + // For example, getBranchCounterPair(#0) returns {#1, #0 - #1}. + // The sum of the pair should be equivalent to the Parent, #0. + // OTOH when (#0 - #1) is replaced with the new counter #2, + // The sum is (#1 + #2). If the reverse substitution #2 => (#0 - #1) + // can be applied, the sum can be transformed to (#1 + (#0 - #1)). + // To apply substitutions to both hand expressions, transform (LHS - RHS) + // and check isZero. if (Builder.subst(Builder.subtract(OutCount, ParentCount), MapToExpand) .isZero()) return true; From bee39f375958994fc41524c0870ccf2d006df648 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Tue, 7 Jan 2025 00:20:45 +0900 Subject: [PATCH 66/79] Update test --- clang/test/CoverageMapping/single-byte-counters.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/test/CoverageMapping/single-byte-counters.cpp b/clang/test/CoverageMapping/single-byte-counters.cpp index 79548e19326af..2ef8afa097b8f 100644 --- a/clang/test/CoverageMapping/single-byte-counters.cpp +++ b/clang/test/CoverageMapping/single-byte-counters.cpp @@ -109,8 +109,8 @@ int testContinueBreak() { // CHECK-NEXT: File 0, [[@LINE]]:25 -> [[@LINE+23]]:2 sum += i; // CHECK-NEXT: File 0, [[@LINE]]:5 -> [[@LINE+2]]:4 = [[C5F1]] i++; } - // CHECK-NEXT: Gap,File 0, [[@LINE-1]]:4 -> [[@LINE+1]]:3 = ([[C5T1]] + [[C5E]]) - return sum; // CHECK-NEXT: File 0, [[@LINE]]:3 -> [[@LINE]]:13 = ([[C5T1]] + [[C5E]]) + // #0 + return sum; // #0 } // CHECK-NEXT: testFor From d854fb123be0449e83093f11e9f826c9baa3b766 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 08:32:58 +0900 Subject: [PATCH 67/79] Rewind switch DefaultCase. (to #113112) --- clang/lib/CodeGen/CoverageMappingGen.cpp | 26 ++++++++---------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index df29c2cb4ee17..d1968c5861c95 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -948,20 +948,6 @@ struct CounterCoverageMappingBuilder return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; } - /// Returns {TrueCnt,FalseCnt} for "implicit default". - /// FalseCnt is considered as the False count on SwitchStmt. - std::pair - getSwitchImplicitDefaultCounterPair(const Stmt *Cond, Counter ParentCount, - Counter CaseCountSum) { - // Simplify is skipped while building the counters above: it can get - // really slow on top of switches with thousands of cases. Instead, - // trigger simplification by adding zero to the last counter. - CaseCountSum = - addCounters(CaseCountSum, Counter::getZero(), /*Simplify=*/true); - - return {CaseCountSum, Builder.subtract(ParentCount, CaseCountSum)}; - } - bool IsCounterEqual(Counter OutCount, Counter ParentCount) { if (OutCount == ParentCount) return true; @@ -1920,9 +1906,15 @@ struct CounterCoverageMappingBuilder // the hidden branch, which will be added later by the CodeGen. This region // will be associated with the switch statement's condition. if (!HasDefaultCase) { - auto Counters = getSwitchImplicitDefaultCounterPair( - S->getCond(), ParentCount, CaseCountSum); - createBranchRegion(S->getCond(), Counters.first, Counters.second); + // Simplify is skipped while building the counters above: it can get + // really slow on top of switches with thousands of cases. Instead, + // trigger simplification by adding zero to the last counter. + CaseCountSum = + addCounters(CaseCountSum, Counter::getZero(), /*Simplify=*/true); + + // This is considered as the False count on SwitchStmt. + Counter SwitchFalse = subtractCounters(ParentCount, CaseCountSum); + createBranchRegion(S->getCond(), CaseCountSum, SwitchFalse); } } From bac29679dcc3d1e2f4b01270d8b1abb0858c549e Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 08:42:38 +0900 Subject: [PATCH 68/79] Enable addCounters --- clang/lib/CodeGen/CoverageMappingGen.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index d1968c5861c95..a973bcbb3f765 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -919,15 +919,11 @@ struct CounterCoverageMappingBuilder /// Return a counter for the sum of \c LHS and \c RHS. Counter addCounters(Counter LHS, Counter RHS, bool Simplify = true) { - assert(!llvm::EnableSingleByteCoverage && - "cannot add counters when single byte coverage mode is enabled"); return Builder.add(LHS, RHS, Simplify); } Counter addCounters(Counter C1, Counter C2, Counter C3, bool Simplify = true) { - assert(!llvm::EnableSingleByteCoverage && - "cannot add counters when single byte coverage mode is enabled"); return addCounters(addCounters(C1, C2, Simplify), C3, Simplify); } From 6bae87d6193a88ab093ab472ff4a2d27f9e5e288 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 09:05:46 +0900 Subject: [PATCH 69/79] Get rid of structual bindings --- clang/lib/CodeGen/CoverageMappingGen.cpp | 41 +++++++++++++----------- 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index a973bcbb3f765..c03eb6a55af5e 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -1601,12 +1601,13 @@ struct CounterCoverageMappingBuilder llvm::EnableSingleByteCoverage ? getRegionCounter(S->getCond()) : addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - auto [ExecCount, ExitCount] = + auto BranchCount = (llvm::EnableSingleByteCoverage ? BranchCounterPair{getRegionCounter(S), Counter::getZero()} : getBranchCounterPair(S, CondCount)); if (!llvm::EnableSingleByteCoverage) { - assert(ExecCount.isZero() || ExecCount == BodyCount); + assert(BranchCount.Executed.isZero() || + BranchCount.Executed == BodyCount); } propagateCounts(CondCount, S->getCond()); adjustForOutOfOrderTraversal(getEnd(S)); @@ -1618,7 +1619,7 @@ struct CounterCoverageMappingBuilder Counter OutCount = llvm::EnableSingleByteCoverage ? getRegionCounter(S) - : addCounters(BC.BreakCount, ExitCount); + : addCounters(BC.BreakCount, BranchCount.Skipped); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); @@ -1629,7 +1630,7 @@ struct CounterCoverageMappingBuilder // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, ExitCount); + createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped); } void VisitDoStmt(const DoStmt *S) { @@ -1658,18 +1659,19 @@ struct CounterCoverageMappingBuilder Counter CondCount = llvm::EnableSingleByteCoverage ? getRegionCounter(S->getCond()) : addCounters(BackedgeCount, BC.ContinueCount); - auto [ExecCount, ExitCount] = + auto BranchCount = (llvm::EnableSingleByteCoverage ? BranchCounterPair{getRegionCounter(S), Counter::getZero()} : getBranchCounterPair(S, CondCount)); if (!llvm::EnableSingleByteCoverage) { - assert(ExecCount.isZero() || ExecCount == BodyCount); + assert(BranchCount.Executed.isZero() || + BranchCount.Executed == BodyCount); } propagateCounts(CondCount, S->getCond()); Counter OutCount = llvm::EnableSingleByteCoverage ? getRegionCounter(S) - : addCounters(BC.BreakCount, ExitCount); + : addCounters(BC.BreakCount, BranchCount.Skipped); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; @@ -1677,7 +1679,7 @@ struct CounterCoverageMappingBuilder // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, ExitCount); + createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped); if (BodyHasTerminateStmt) HasTerminateStmt = true; @@ -1726,12 +1728,13 @@ struct CounterCoverageMappingBuilder : addCounters( addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount), IncrementBC.ContinueCount); - auto [ExecCount, ExitCount] = + auto BranchCount = (llvm::EnableSingleByteCoverage ? BranchCounterPair{getRegionCounter(S), Counter::getZero()} : getBranchCounterPair(S, CondCount)); if (!llvm::EnableSingleByteCoverage) { - assert(ExecCount.isZero() || ExecCount == BodyCount); + assert(BranchCount.Executed.isZero() || + BranchCount.Executed == BodyCount); } if (const Expr *Cond = S->getCond()) { @@ -1747,7 +1750,8 @@ struct CounterCoverageMappingBuilder Counter OutCount = llvm::EnableSingleByteCoverage ? getRegionCounter(S) - : addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, ExitCount); + : addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, + BranchCount.Skipped); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; @@ -1757,7 +1761,7 @@ struct CounterCoverageMappingBuilder // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, ExitCount); + createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped); } void VisitCXXForRangeStmt(const CXXForRangeStmt *S) { @@ -1792,9 +1796,10 @@ struct CounterCoverageMappingBuilder OutCount = getRegionCounter(S); else { LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - auto [ExecCount, SkipCount] = getBranchCounterPair(S, LoopCount); - ExitCount = SkipCount; - assert(ExecCount.isZero() || ExecCount == BodyCount); + auto BranchCount = getBranchCounterPair(S, LoopCount); + ExitCount = BranchCount.Skipped; + assert(BranchCount.Executed.isZero() || + BranchCount.Executed == BodyCount); OutCount = addCounters(BC.BreakCount, ExitCount); } if (!IsCounterEqual(OutCount, ParentCount)) { @@ -1828,9 +1833,9 @@ struct CounterCoverageMappingBuilder Counter LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - auto [ExecCount, ExitCount] = getBranchCounterPair(S, LoopCount); - assert(ExecCount.isZero() || ExecCount == BodyCount); - Counter OutCount = addCounters(BC.BreakCount, ExitCount); + auto BranchCount = getBranchCounterPair(S, LoopCount); + assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount); + Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; From c8edf58d644e80281e00577920125fa1d7618f47 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 09:22:58 +0900 Subject: [PATCH 70/79] Flatten with getBranchCounterPair(SkipCntForOld) --- clang/lib/CodeGen/CoverageMappingGen.cpp | 95 +++++++++++------------- 1 file changed, 44 insertions(+), 51 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index c03eb6a55af5e..0495a60e53c24 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -939,8 +939,17 @@ struct CounterCoverageMappingBuilder Counter Skipped; }; - BranchCounterPair getBranchCounterPair(const Stmt *S, Counter ParentCnt) { + BranchCounterPair + getBranchCounterPair(const Stmt *S, Counter ParentCnt, + std::optional SkipCntForOld = std::nullopt) { Counter ExecCnt = getRegionCounter(S); + + // The old behavior of SingleByte shouldn't emit Branches. + if (llvm::EnableSingleByteCoverage) { + assert(SkipCntForOld); + return {ExecCnt, *SkipCntForOld}; + } + return {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; } @@ -1601,14 +1610,10 @@ struct CounterCoverageMappingBuilder llvm::EnableSingleByteCoverage ? getRegionCounter(S->getCond()) : addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - auto BranchCount = - (llvm::EnableSingleByteCoverage - ? BranchCounterPair{getRegionCounter(S), Counter::getZero()} - : getBranchCounterPair(S, CondCount)); - if (!llvm::EnableSingleByteCoverage) { - assert(BranchCount.Executed.isZero() || - BranchCount.Executed == BodyCount); - } + auto BranchCount = getBranchCounterPair(S, CondCount, getRegionCounter(S)); + assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount || + llvm::EnableSingleByteCoverage); + propagateCounts(CondCount, S->getCond()); adjustForOutOfOrderTraversal(getEnd(S)); @@ -1617,10 +1622,10 @@ struct CounterCoverageMappingBuilder if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); - Counter OutCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BC.BreakCount, BranchCount.Skipped); - + assert( + !llvm::EnableSingleByteCoverage || + (BC.BreakCount.isZero() && BranchCount.Skipped == getRegionCounter(S))); + Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; @@ -1659,19 +1664,16 @@ struct CounterCoverageMappingBuilder Counter CondCount = llvm::EnableSingleByteCoverage ? getRegionCounter(S->getCond()) : addCounters(BackedgeCount, BC.ContinueCount); - auto BranchCount = - (llvm::EnableSingleByteCoverage - ? BranchCounterPair{getRegionCounter(S), Counter::getZero()} - : getBranchCounterPair(S, CondCount)); - if (!llvm::EnableSingleByteCoverage) { - assert(BranchCount.Executed.isZero() || - BranchCount.Executed == BodyCount); - } + auto BranchCount = getBranchCounterPair(S, CondCount, getRegionCounter(S)); + assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount || + llvm::EnableSingleByteCoverage); + propagateCounts(CondCount, S->getCond()); - Counter OutCount = llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BC.BreakCount, BranchCount.Skipped); + assert( + !llvm::EnableSingleByteCoverage || + (BC.BreakCount.isZero() && BranchCount.Skipped == getRegionCounter(S))); + Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; @@ -1728,14 +1730,9 @@ struct CounterCoverageMappingBuilder : addCounters( addCounters(ParentCount, BackedgeCount, BodyBC.ContinueCount), IncrementBC.ContinueCount); - auto BranchCount = - (llvm::EnableSingleByteCoverage - ? BranchCounterPair{getRegionCounter(S), Counter::getZero()} - : getBranchCounterPair(S, CondCount)); - if (!llvm::EnableSingleByteCoverage) { - assert(BranchCount.Executed.isZero() || - BranchCount.Executed == BodyCount); - } + auto BranchCount = getBranchCounterPair(S, CondCount, getRegionCounter(S)); + assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount || + llvm::EnableSingleByteCoverage); if (const Expr *Cond = S->getCond()) { propagateCounts(CondCount, Cond); @@ -1747,11 +1744,10 @@ struct CounterCoverageMappingBuilder if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); - Counter OutCount = - llvm::EnableSingleByteCoverage - ? getRegionCounter(S) - : addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, - BranchCount.Skipped); + assert(!llvm::EnableSingleByteCoverage || + (BodyBC.BreakCount.isZero() && IncrementBC.BreakCount.isZero())); + Counter OutCount = addCounters(BodyBC.BreakCount, IncrementBC.BreakCount, + BranchCount.Skipped); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; @@ -1789,19 +1785,16 @@ struct CounterCoverageMappingBuilder if (Gap) fillGapAreaWithCount(Gap->getBegin(), Gap->getEnd(), BodyCount); - Counter OutCount; - Counter ExitCount; - Counter LoopCount; - if (llvm::EnableSingleByteCoverage) - OutCount = getRegionCounter(S); - else { - LoopCount = addCounters(ParentCount, BackedgeCount, BC.ContinueCount); - auto BranchCount = getBranchCounterPair(S, LoopCount); - ExitCount = BranchCount.Skipped; - assert(BranchCount.Executed.isZero() || - BranchCount.Executed == BodyCount); - OutCount = addCounters(BC.BreakCount, ExitCount); - } + Counter LoopCount = + addCounters(ParentCount, BackedgeCount, BC.ContinueCount); + auto BranchCount = getBranchCounterPair(S, LoopCount, getRegionCounter(S)); + assert(BranchCount.Executed.isZero() || BranchCount.Executed == BodyCount || + llvm::EnableSingleByteCoverage); + assert( + !llvm::EnableSingleByteCoverage || + (BC.BreakCount.isZero() && BranchCount.Skipped == getRegionCounter(S))); + + Counter OutCount = addCounters(BC.BreakCount, BranchCount.Skipped); if (!IsCounterEqual(OutCount, ParentCount)) { pushRegion(OutCount); GapRegionCounter = OutCount; @@ -1811,7 +1804,7 @@ struct CounterCoverageMappingBuilder // Create Branch Region around condition. if (!llvm::EnableSingleByteCoverage) - createBranchRegion(S->getCond(), BodyCount, ExitCount); + createBranchRegion(S->getCond(), BodyCount, BranchCount.Skipped); } void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) { From af759727a1dbe2e8b0a172e8ab919135290e4fd4 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 10:07:56 +0900 Subject: [PATCH 71/79] Revert "Rewind switch DefaultCase. (to #113112)" This reverts commit d854fb123be0449e83093f11e9f826c9baa3b766. --- clang/lib/CodeGen/CoverageMappingGen.cpp | 26 ++++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 0cf78dea7be19..64b23711c22ff 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -975,6 +975,20 @@ struct CounterCoverageMappingBuilder return Counters; } + /// Returns {TrueCnt,FalseCnt} for "implicit default". + /// FalseCnt is considered as the False count on SwitchStmt. + std::pair + getSwitchImplicitDefaultCounterPair(const Stmt *Cond, Counter ParentCount, + Counter CaseCountSum) { + // Simplify is skipped while building the counters above: it can get + // really slow on top of switches with thousands of cases. Instead, + // trigger simplification by adding zero to the last counter. + CaseCountSum = + addCounters(CaseCountSum, Counter::getZero(), /*Simplify=*/true); + + return {CaseCountSum, Builder.subtract(ParentCount, CaseCountSum)}; + } + bool IsCounterEqual(Counter OutCount, Counter ParentCount) { if (OutCount == ParentCount) return true; @@ -1933,15 +1947,9 @@ struct CounterCoverageMappingBuilder // the hidden branch, which will be added later by the CodeGen. This region // will be associated with the switch statement's condition. if (!HasDefaultCase) { - // Simplify is skipped while building the counters above: it can get - // really slow on top of switches with thousands of cases. Instead, - // trigger simplification by adding zero to the last counter. - CaseCountSum = - addCounters(CaseCountSum, Counter::getZero(), /*Simplify=*/true); - - // This is considered as the False count on SwitchStmt. - Counter SwitchFalse = subtractCounters(ParentCount, CaseCountSum); - createBranchRegion(S->getCond(), CaseCountSum, SwitchFalse); + auto Counters = getSwitchImplicitDefaultCounterPair( + S->getCond(), ParentCount, CaseCountSum); + createBranchRegion(S->getCond(), Counters.first, Counters.second); } } From fa04eb4af95c1ca7377279728cb004bcd2324d01 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 10:04:09 +0900 Subject: [PATCH 72/79] Resurrect merge conflict --- clang/lib/CodeGen/CoverageMappingGen.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 64b23711c22ff..87f1113e14e9d 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -980,6 +980,11 @@ struct CounterCoverageMappingBuilder std::pair getSwitchImplicitDefaultCounterPair(const Stmt *Cond, Counter ParentCount, Counter CaseCountSum) { + if (llvm::EnableSingleByteCoverage) + // Allocate the new Counter since `subtract(Parent - Sum)` is unavailable. + return {Counter::getZero(), // Folded + Counter::getCounter(CounterMap[Cond].Skipped = NextCounterNum++)}; + // Simplify is skipped while building the counters above: it can get // really slow on top of switches with thousands of cases. Instead, // trigger simplification by adding zero to the last counter. From 122393694892e7a718e8c612b5650388075e2833 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 10:33:02 +0900 Subject: [PATCH 73/79] Dissolve assert --- clang/lib/CodeGen/CoverageMappingGen.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 393d4c61b63c0..bbfd4cfcee34f 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -949,10 +949,8 @@ struct CounterCoverageMappingBuilder auto ExecCnt = Counter::getCounter(TheMap.Executed); // The old behavior of SingleByte shouldn't emit Branches. - if (llvm::EnableSingleByteCoverage) { - assert(SkipCntForOld); + if (llvm::EnableSingleByteCoverage && SkipCntForOld) return {ExecCnt, *SkipCntForOld}; - } BranchCounterPair Counters = {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; From 3c6252260ee11e3a453076b4d96ffffe20d49998 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 10:33:02 +0900 Subject: [PATCH 74/79] Dissolve assert --- clang/lib/CodeGen/CoverageMappingGen.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index ba2414cbe2a7e..db421fa1c767d 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -949,10 +949,8 @@ struct CounterCoverageMappingBuilder auto ExecCnt = Counter::getCounter(TheMap.Executed); // The old behavior of SingleByte shouldn't emit Branches. - if (llvm::EnableSingleByteCoverage) { - assert(SkipCntForOld); + if (llvm::EnableSingleByteCoverage && SkipCntForOld) return {ExecCnt, *SkipCntForOld}; - } BranchCounterPair Counters = {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; From f2ba2192053cd335f8f848071b1e08fc6f071808 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 18:10:52 +0900 Subject: [PATCH 75/79] Update comments --- clang/lib/CodeGen/CoverageMappingGen.cpp | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 0495a60e53c24..8bc5d73bbd0ce 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -935,16 +935,32 @@ struct CounterCoverageMappingBuilder } struct BranchCounterPair { - Counter Executed; - Counter Skipped; + Counter Executed; ///< The Counter previously assigned. + Counter Skipped; ///< An expression (Parent-Executed), or equivalent to it. }; + /// Retrieve or assign the pair of Counter(s). + /// + /// This returns BranchCounterPair {Executed, Skipped}. + /// Executed is the Counter associated with S assigned by an earlier + /// CounterMapping pass. + /// Skipped may be an expression (Executed - ParentCnt) or newly + /// assigned Counter in EnableSingleByteCoverage, as subtract + /// expressions are not available in this mode. + /// + /// \param S Key to the CounterMap + /// \param ParentCnt The Counter representing how many times S is evaluated. + /// \param SkipCntForOld (To be removed later) Optional fake Counter + /// to override Skipped for adjustment of + /// expressions in the old behavior of + /// EnableSingleByteCoverage that is unaware of + /// Branch coverage. BranchCounterPair getBranchCounterPair(const Stmt *S, Counter ParentCnt, std::optional SkipCntForOld = std::nullopt) { Counter ExecCnt = getRegionCounter(S); - // The old behavior of SingleByte shouldn't emit Branches. + // The old behavior of SingleByte is unaware of Branches. if (llvm::EnableSingleByteCoverage) { assert(SkipCntForOld); return {ExecCnt, *SkipCntForOld}; From 97015cb5e015a517d83bf67e3e8f65310f51bc55 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 18:11:02 +0900 Subject: [PATCH 76/79] Decorate the mock --- clang/lib/CodeGen/CoverageMappingGen.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 8bc5d73bbd0ce..72c027fa8e566 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -962,7 +962,8 @@ struct CounterCoverageMappingBuilder // The old behavior of SingleByte is unaware of Branches. if (llvm::EnableSingleByteCoverage) { - assert(SkipCntForOld); + assert(SkipCntForOld && + "SingleByte must provide SkipCntForOld as a fake Skipped count."); return {ExecCnt, *SkipCntForOld}; } From 0e2997d02e7c60c698364d6fad234e444bc92851 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Wed, 8 Jan 2025 18:15:53 +0900 Subject: [PATCH 77/79] Dissolve the old behavior --- clang/lib/CodeGen/CoverageMappingGen.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index d1334ed8a8ac7..ce8387ae848ce 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -942,16 +942,9 @@ struct CounterCoverageMappingBuilder Counter Skipped; }; - BranchCounterPair - getBranchCounterPair(const Stmt *S, Counter ParentCnt, - std::optional SkipCntForOld = std::nullopt) { + BranchCounterPair getBranchCounterPair(const Stmt *S, Counter ParentCnt) { auto &TheMap = CounterMap[S]; auto ExecCnt = Counter::getCounter(TheMap.Executed); - - // The old behavior of SingleByte shouldn't emit Branches. - if (llvm::EnableSingleByteCoverage && SkipCntForOld) - return {ExecCnt, *SkipCntForOld}; - BranchCounterPair Counters = {ExecCnt, Builder.subtract(ParentCnt, ExecCnt)}; From 9a40d20d0c468f7da49d156fd4c7752e9902033b Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 9 Jan 2025 14:11:45 +0900 Subject: [PATCH 78/79] Will be pruned after the migration of SingleByte. --- clang/lib/CodeGen/CoverageMappingGen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 72c027fa8e566..dfffa12b639f2 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -961,6 +961,7 @@ struct CounterCoverageMappingBuilder Counter ExecCnt = getRegionCounter(S); // The old behavior of SingleByte is unaware of Branches. + // Will be pruned after the migration of SingleByte. if (llvm::EnableSingleByteCoverage) { assert(SkipCntForOld && "SingleByte must provide SkipCntForOld as a fake Skipped count."); From b548e71a3cf55167d5b49e010cc76c8c82f29280 Mon Sep 17 00:00:00 2001 From: NAKAMURA Takumi Date: Thu, 9 Jan 2025 15:19:00 +0900 Subject: [PATCH 79/79] Add comments --- llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h index dad5f1276f27c..edae71491191e 100644 --- a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h +++ b/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h @@ -215,9 +215,12 @@ class CounterExpressionBuilder { /// LHS. Counter subtract(Counter LHS, Counter RHS, bool Simplify = true); + /// K to V map. K will be Counter in most cases. V may be Counter or + /// Expression. using SubstMap = std::map; - /// Return a counter for each term in the expression replaced by SubstMap. + /// \return A counter equivalent to \C, with each term in its + /// expression replaced with term from \p Map. Counter subst(Counter C, const SubstMap &Map); };
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: