Skip to content

Commit 2293b8d

Browse files
committed
Merge remote-tracking branches 'origin/users/chapuni/cov/single/refactor' and 'origin/users/chapuni/cov/single/unify' into users/chapuni/cov/merge/forfile-base
3 parents 7ec139a + 3780e07 + 5b6c0b0 commit 2293b8d

File tree

9 files changed

+107
-74
lines changed

9 files changed

+107
-74
lines changed

llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -364,19 +364,16 @@ struct CountedRegion : public CounterMappingRegion {
364364
uint64_t FalseExecutionCount;
365365
bool TrueFolded;
366366
bool FalseFolded;
367-
bool HasSingleByteCoverage;
368367

369-
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
370-
bool HasSingleByteCoverage)
368+
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount)
371369
: CounterMappingRegion(R), ExecutionCount(ExecutionCount),
372-
FalseExecutionCount(0), TrueFolded(false), FalseFolded(true),
373-
HasSingleByteCoverage(HasSingleByteCoverage) {}
370+
FalseExecutionCount(0), TrueFolded(false), FalseFolded(true) {}
374371

375372
CountedRegion(const CounterMappingRegion &R, uint64_t ExecutionCount,
376-
uint64_t FalseExecutionCount, bool HasSingleByteCoverage)
373+
uint64_t FalseExecutionCount)
377374
: CounterMappingRegion(R), ExecutionCount(ExecutionCount),
378375
FalseExecutionCount(FalseExecutionCount), TrueFolded(false),
379-
FalseFolded(false), HasSingleByteCoverage(HasSingleByteCoverage) {}
376+
FalseFolded(false) {}
380377
};
381378

382379
/// MCDC Record grouping all information together.
@@ -719,10 +716,9 @@ struct FunctionRecord {
719716
}
720717

721718
void pushRegion(CounterMappingRegion Region, uint64_t Count,
722-
uint64_t FalseCount, bool HasSingleByteCoverage) {
719+
uint64_t FalseCount) {
723720
if (Region.isBranch()) {
724-
CountedBranchRegions.emplace_back(Region, Count, FalseCount,
725-
HasSingleByteCoverage);
721+
CountedBranchRegions.emplace_back(Region, Count, FalseCount);
726722
// If either counter is hard-coded to zero, then this region represents a
727723
// constant-folded branch.
728724
CountedBranchRegions.back().TrueFolded = Region.Count.isZero();
@@ -731,8 +727,7 @@ struct FunctionRecord {
731727
}
732728
if (CountedRegions.empty())
733729
ExecutionCount = Count;
734-
CountedRegions.emplace_back(Region, Count, FalseCount,
735-
HasSingleByteCoverage);
730+
CountedRegions.emplace_back(Region, Count, FalseCount);
736731
}
737732
};
738733

@@ -889,20 +884,28 @@ class InstantiationGroup {
889884
class CoverageData {
890885
friend class CoverageMapping;
891886

887+
protected:
892888
std::string Filename;
893889
std::vector<CoverageSegment> Segments;
894890
std::vector<ExpansionRecord> Expansions;
895891
std::vector<CountedRegion> BranchRegions;
896892
std::vector<MCDCRecord> MCDCRecords;
897893

894+
bool SingleByteCoverage = false;
895+
898896
public:
899897
CoverageData() = default;
900898

901-
CoverageData(StringRef Filename) : Filename(Filename) {}
899+
CoverageData(bool Single, StringRef Filename)
900+
: Filename(Filename), SingleByteCoverage(Single) {}
901+
902+
CoverageData(CoverageData &&RHS) = default;
902903

903904
/// Get the name of the file this data covers.
904905
StringRef getFilename() const { return Filename; }
905906

907+
bool getSingleByteCoverage() const { return SingleByteCoverage; }
908+
906909
/// Get an iterator over the coverage segments for this object. The segments
907910
/// are guaranteed to be uniqued and sorted by location.
908911
std::vector<CoverageSegment>::const_iterator begin() const {
@@ -935,6 +938,8 @@ class CoverageMapping {
935938
DenseMap<size_t, SmallVector<unsigned, 0>> FilenameHash2RecordIndices;
936939
std::vector<std::pair<std::string, uint64_t>> FuncHashMismatches;
937940

941+
std::optional<bool> SingleByteCoverage;
942+
938943
CoverageMapping() = default;
939944

940945
// Load coverage records from readers.

llvm/lib/ProfileData/Coverage/CoverageMapping.cpp

Lines changed: 52 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,6 @@ Error CoverageMapping::loadFunctionRecord(
805805
else
806806
OrigFuncName = getFuncNameWithoutPrefix(OrigFuncName, Record.Filenames[0]);
807807

808-
bool SingleByteCoverage = ProfileReader.hasSingleByteCoverage();
809808
CounterMappingContext Ctx(Record.Expressions);
810809

811810
std::vector<uint64_t> Counts;
@@ -871,10 +870,7 @@ Error CoverageMapping::loadFunctionRecord(
871870
consumeError(std::move(E));
872871
return Error::success();
873872
}
874-
Function.pushRegion(
875-
Region, (SingleByteCoverage && *ExecutionCount ? 1 : *ExecutionCount),
876-
(SingleByteCoverage && *AltExecutionCount ? 1 : *AltExecutionCount),
877-
SingleByteCoverage);
873+
Function.pushRegion(Region, *ExecutionCount, *AltExecutionCount);
878874

879875
// Record ExpansionRegion.
880876
if (Region.Kind == CounterMappingRegion::ExpansionRegion) {
@@ -936,6 +932,9 @@ Error CoverageMapping::loadFunctionRecord(
936932
Error CoverageMapping::loadFromReaders(
937933
ArrayRef<std::unique_ptr<CoverageMappingReader>> CoverageReaders,
938934
IndexedInstrProfReader &ProfileReader, CoverageMapping &Coverage) {
935+
assert(!Coverage.SingleByteCoverage ||
936+
*Coverage.SingleByteCoverage == ProfileReader.hasSingleByteCoverage());
937+
Coverage.SingleByteCoverage = ProfileReader.hasSingleByteCoverage();
939938
for (const auto &CoverageReader : CoverageReaders) {
940939
for (auto RecordOrErr : *CoverageReader) {
941940
if (Error E = RecordOrErr.takeError())
@@ -1296,14 +1295,8 @@ class SegmentBuilder {
12961295
// value for that area.
12971296
// We add counts of the regions of the same kind as the active region
12981297
// to handle the both situations.
1299-
if (I->Kind == Active->Kind) {
1300-
assert(I->HasSingleByteCoverage == Active->HasSingleByteCoverage &&
1301-
"Regions are generated in different coverage modes");
1302-
if (I->HasSingleByteCoverage)
1303-
Active->ExecutionCount = Active->ExecutionCount || I->ExecutionCount;
1304-
else
1305-
Active->ExecutionCount += I->ExecutionCount;
1306-
}
1298+
if (I->Kind == Active->Kind)
1299+
Active->ExecutionCount += I->ExecutionCount;
13071300
}
13081301
return Regions.drop_back(std::distance(++Active, End));
13091302
}
@@ -1346,6 +1339,37 @@ class SegmentBuilder {
13461339
}
13471340
};
13481341

1342+
struct MergeableCoverageData : public CoverageData {
1343+
std::vector<CountedRegion> CodeRegions;
1344+
1345+
MergeableCoverageData(bool Single, StringRef Filename)
1346+
: CoverageData(Single, Filename) {}
1347+
1348+
void addFunctionRegions(
1349+
const FunctionRecord &Function,
1350+
std::function<bool(const CounterMappingRegion &CR)> shouldProcess,
1351+
std::function<bool(const CountedRegion &CR)> shouldExpand) {
1352+
for (const auto &CR : Function.CountedRegions)
1353+
if (shouldProcess(CR)) {
1354+
CodeRegions.push_back(CR);
1355+
if (shouldExpand(CR))
1356+
Expansions.emplace_back(CR, Function);
1357+
}
1358+
// Capture branch regions specific to the function (excluding expansions).
1359+
for (const auto &CR : Function.CountedBranchRegions)
1360+
if (shouldProcess(CR))
1361+
BranchRegions.push_back(CR);
1362+
// Capture MCDC records specific to the function.
1363+
for (const auto &MR : Function.MCDCRecords)
1364+
if (shouldProcess(MR.getDecisionRegion()))
1365+
MCDCRecords.push_back(MR);
1366+
}
1367+
1368+
CoverageData buildSegments() {
1369+
Segments = SegmentBuilder::buildSegments(CodeRegions);
1370+
return CoverageData(std::move(*this));
1371+
}
1372+
};
13491373
} // end anonymous namespace
13501374

13511375
std::vector<StringRef> CoverageMapping::getUniqueSourceFiles() const {
@@ -1396,8 +1420,8 @@ static bool isExpansion(const CountedRegion &R, unsigned FileID) {
13961420
}
13971421

13981422
CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
1399-
CoverageData FileCoverage(Filename);
1400-
std::vector<CountedRegion> Regions;
1423+
assert(SingleByteCoverage);
1424+
MergeableCoverageData FileCoverage(*SingleByteCoverage, Filename);
14011425

14021426
// Look up the function records in the given file. Due to hash collisions on
14031427
// the filename, we may get back some records that are not in the file.
@@ -1407,26 +1431,14 @@ CoverageData CoverageMapping::getCoverageForFile(StringRef Filename) const {
14071431
const FunctionRecord &Function = Functions[RecordIndex];
14081432
auto MainFileID = findMainViewFileID(Filename, Function);
14091433
auto FileIDs = gatherFileIDs(Filename, Function);
1410-
for (const auto &CR : Function.CountedRegions)
1411-
if (FileIDs.test(CR.FileID)) {
1412-
Regions.push_back(CR);
1413-
if (MainFileID && isExpansion(CR, *MainFileID))
1414-
FileCoverage.Expansions.emplace_back(CR, Function);
1415-
}
1416-
// Capture branch regions specific to the function (excluding expansions).
1417-
for (const auto &CR : Function.CountedBranchRegions)
1418-
if (FileIDs.test(CR.FileID))
1419-
FileCoverage.BranchRegions.push_back(CR);
1420-
// Capture MCDC records specific to the function.
1421-
for (const auto &MR : Function.MCDCRecords)
1422-
if (FileIDs.test(MR.getDecisionRegion().FileID))
1423-
FileCoverage.MCDCRecords.push_back(MR);
1434+
FileCoverage.addFunctionRegions(
1435+
Function, [&](auto &CR) { return FileIDs.test(CR.FileID); },
1436+
[&](auto &CR) { return (MainFileID && isExpansion(CR, *MainFileID)); });
14241437
}
14251438

14261439
LLVM_DEBUG(dbgs() << "Emitting segments for file: " << Filename << "\n");
1427-
FileCoverage.Segments = SegmentBuilder::buildSegments(Regions);
14281440

1429-
return FileCoverage;
1441+
return FileCoverage.buildSegments();
14301442
}
14311443

14321444
std::vector<InstantiationGroup>
@@ -1460,35 +1472,24 @@ CoverageMapping::getCoverageForFunction(const FunctionRecord &Function) const {
14601472
if (!MainFileID)
14611473
return CoverageData();
14621474

1463-
CoverageData FunctionCoverage(Function.Filenames[*MainFileID]);
1464-
std::vector<CountedRegion> Regions;
1465-
for (const auto &CR : Function.CountedRegions)
1466-
if (CR.FileID == *MainFileID) {
1467-
Regions.push_back(CR);
1468-
if (isExpansion(CR, *MainFileID))
1469-
FunctionCoverage.Expansions.emplace_back(CR, Function);
1470-
}
1471-
// Capture branch regions specific to the function (excluding expansions).
1472-
for (const auto &CR : Function.CountedBranchRegions)
1473-
if (CR.FileID == *MainFileID)
1474-
FunctionCoverage.BranchRegions.push_back(CR);
1475-
1476-
// Capture MCDC records specific to the function.
1477-
for (const auto &MR : Function.MCDCRecords)
1478-
if (MR.getDecisionRegion().FileID == *MainFileID)
1479-
FunctionCoverage.MCDCRecords.push_back(MR);
1475+
assert(SingleByteCoverage);
1476+
MergeableCoverageData FunctionCoverage(*SingleByteCoverage,
1477+
Function.Filenames[*MainFileID]);
1478+
FunctionCoverage.addFunctionRegions(
1479+
Function, [&](auto &CR) { return (CR.FileID == *MainFileID); },
1480+
[&](auto &CR) { return isExpansion(CR, *MainFileID); });
14801481

14811482
LLVM_DEBUG(dbgs() << "Emitting segments for function: " << Function.Name
14821483
<< "\n");
1483-
FunctionCoverage.Segments = SegmentBuilder::buildSegments(Regions);
14841484

1485-
return FunctionCoverage;
1485+
return FunctionCoverage.buildSegments();
14861486
}
14871487

14881488
CoverageData CoverageMapping::getCoverageForExpansion(
14891489
const ExpansionRecord &Expansion) const {
1490+
assert(SingleByteCoverage);
14901491
CoverageData ExpansionCoverage(
1491-
Expansion.Function.Filenames[Expansion.FileID]);
1492+
*SingleByteCoverage, Expansion.Function.Filenames[Expansion.FileID]);
14921493
std::vector<CountedRegion> Regions;
14931494
for (const auto &CR : Expansion.Function.CountedRegions)
14941495
if (CR.FileID == Expansion.FileID) {

llvm/test/tools/llvm-cov/branch-macros.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
// RUN: llvm-profdata merge %S/Inputs/branch-macros.proftext -o %t.profdata
22
// 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
3+
// 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
34
// 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
45

56
// RUN: yaml2obj %S/Inputs/branch-macros-single.yaml -o %t.o

llvm/test/tools/llvm-cov/showLineExecutionCounts.test

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// RUN: llvm-profdata merge %S/Inputs/lineExecutionCounts.proftext -o %t.profdata
44

55
// 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
6+
// 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
67
// 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
78

89
// Test -output-dir.
@@ -16,8 +17,10 @@
1617
//
1718
// Test html output.
1819
// RUN: llvm-cov show %S/Inputs/lineExecutionCounts.covmapping -format html -o %t.dir/html -instr-profile %t.profdata -path-equivalence=/tmp,%S/Inputs
20+
// 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
1921
// 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
2022
// RUN: FileCheck -check-prefixes=HTML,HTML-WHOLE-FILE -input-file %t.dir/html/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp
23+
// RUN: FileCheck -check-prefixes=HTML-BINARY,HTML-WHOLE-FILE -input-file %t.dir/html.binary/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp
2124
// RUN: FileCheck -check-prefixes=HTML,HTML-FILTER -input-file %t.dir/html.filtered/coverage/tmp/showLineExecutionCounts.cpp.html %S/Inputs/showLineExecutionCounts.cpp
2225
//
2326
// Test index creation.

llvm/tools/llvm-cov/CodeCoverage.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1023,6 +1023,12 @@ int CodeCoverageTool::doShow(int argc, const char **argv,
10231023
cl::alias ShowOutputDirectoryA("o", cl::desc("Alias for --output-dir"),
10241024
cl::aliasopt(ShowOutputDirectory));
10251025

1026+
cl::opt<bool> BinaryCounters(
1027+
"binary-counters", cl::Optional,
1028+
cl::desc("Show when lines/branches are covered (1) or uncovered (0) "
1029+
"instead of showing actual counter values."),
1030+
cl::cat(ViewCategory));
1031+
10261032
cl::opt<uint32_t> TabSize(
10271033
"tab-size", cl::init(2),
10281034
cl::desc(
@@ -1100,6 +1106,7 @@ int CodeCoverageTool::doShow(int argc, const char **argv,
11001106
ViewOpts.ShowFunctionInstantiations = ShowInstantiations;
11011107
ViewOpts.ShowDirectoryCoverage = ShowDirectoryCoverage;
11021108
ViewOpts.ShowOutputDirectory = ShowOutputDirectory;
1109+
ViewOpts.BinaryCounters = BinaryCounters;
11031110
ViewOpts.TabSize = TabSize;
11041111
ViewOpts.ProjectTitle = ProjectTitle;
11051112

llvm/tools/llvm-cov/CoverageViewOptions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct CoverageViewOptions {
4545
bool SkipExpansions;
4646
bool SkipFunctions;
4747
bool SkipBranches;
48+
bool BinaryCounters;
4849
OutputFormat Format;
4950
BranchOutputType ShowBranches;
5051
std::string ShowOutputDirectory;

llvm/tools/llvm-cov/SourceCoverageView.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,8 @@ class SourceCoverageView {
180180
/// on display.
181181
std::vector<InstantiationView> InstantiationSubViews;
182182

183+
bool BinaryCounters;
184+
183185
/// Get the first uncovered line number for the source file.
184186
unsigned getFirstUncoveredLineNo();
185187

@@ -266,6 +268,14 @@ class SourceCoverageView {
266268
/// digits.
267269
static std::string formatCount(uint64_t N);
268270

271+
uint64_t BinaryCount(uint64_t N) const {
272+
return (N && BinaryCounters ? 1 : N);
273+
}
274+
275+
std::string formatBinaryCount(uint64_t N) const {
276+
return formatCount(BinaryCount(N));
277+
}
278+
269279
/// Check if region marker output is expected for a line.
270280
bool shouldRenderRegionMarkers(const LineCoverageStats &LCS) const;
271281

@@ -276,7 +286,9 @@ class SourceCoverageView {
276286
const CoverageViewOptions &Options,
277287
CoverageData &&CoverageInfo)
278288
: SourceName(SourceName), File(File), Options(Options),
279-
CoverageInfo(std::move(CoverageInfo)) {}
289+
CoverageInfo(std::move(CoverageInfo)),
290+
BinaryCounters(Options.BinaryCounters ||
291+
CoverageInfo.getSingleByteCoverage()) {}
280292

281293
public:
282294
static std::unique_ptr<SourceCoverageView>

llvm/tools/llvm-cov/SourceCoverageViewHTML.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,19 +1019,22 @@ void SourceCoverageViewHTML::renderLine(raw_ostream &OS, LineRef L,
10191019
// Just consider the segments which start *and* end on this line.
10201020
for (unsigned I = 0, E = Segments.size() - 1; I < E; ++I) {
10211021
const auto *CurSeg = Segments[I];
1022+
auto CurSegCount = BinaryCount(CurSeg->Count);
1023+
auto LCSCount = BinaryCount(LCS.getExecutionCount());
10221024
if (!CurSeg->IsRegionEntry)
10231025
continue;
1024-
if (CurSeg->Count == LCS.getExecutionCount())
1026+
if (CurSegCount == LCSCount)
10251027
continue;
10261028

10271029
Snippets[I + 1] =
1028-
tag("div", Snippets[I + 1] + tag("span", formatCount(CurSeg->Count),
1029-
"tooltip-content"),
1030+
tag("div",
1031+
Snippets[I + 1] +
1032+
tag("span", formatCount(CurSegCount), "tooltip-content"),
10301033
"tooltip");
10311034

10321035
if (getOptions().Debug)
10331036
errs() << "Marker at " << CurSeg->Line << ":" << CurSeg->Col << " = "
1034-
<< formatCount(CurSeg->Count) << "\n";
1037+
<< formatCount(CurSegCount) << "\n";
10351038
}
10361039
}
10371040

@@ -1051,7 +1054,7 @@ void SourceCoverageViewHTML::renderLineCoverageColumn(
10511054
raw_ostream &OS, const LineCoverageStats &Line) {
10521055
std::string Count;
10531056
if (Line.isMapped())
1054-
Count = tag("pre", formatCount(Line.getExecutionCount()));
1057+
Count = tag("pre", formatBinaryCount(Line.getExecutionCount()));
10551058
std::string CoverageClass =
10561059
(Line.getExecutionCount() > 0)
10571060
? "covered-line"
@@ -1106,7 +1109,7 @@ void SourceCoverageViewHTML::renderBranchView(raw_ostream &OS, BranchView &BRV,
11061109

11071110
OS << tag("span", Label, (Count ? "None" : "red branch")) << ": ";
11081111
if (getOptions().ShowBranchCounts)
1109-
OS << tag("span", formatCount(Count),
1112+
OS << tag("span", formatBinaryCount(Count),
11101113
(Count ? "covered-line" : "uncovered-line"));
11111114
else
11121115
OS << format("%0.2f", (Total != 0 ? 100.0 * Count / Total : 0.0)) << "%";

0 commit comments

Comments
 (0)