summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ProfileData
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2017-09-18 23:37:28 +0000
committerVedant Kumar <vsk@apple.com>2017-09-18 23:37:28 +0000
commitad8f637bd83aeeca7321d6c74b3d7787587c0d55 (patch)
treee771084274c8fde30518a8c9f08c7ffb4e2cd3dd /llvm/lib/ProfileData
parent27d1b14ab056a3de64cf93c80a10886e2dc904f7 (diff)
downloadbcm5719-llvm-ad8f637bd83aeeca7321d6c74b3d7787587c0d55.tar.gz
bcm5719-llvm-ad8f637bd83aeeca7321d6c74b3d7787587c0d55.zip
[Coverage] Use gap regions to select better line exec counts
After clang started emitting deferred regions (r312818), llvm-cov has had a hard time picking reasonable line execuction counts. There have been one or two generic improvements in this area (e.g r310012), but line counts can still report coverage for whitespace instead of code (llvm.org/PR34612). To fix the problem: * Introduce a new region kind so that frontends can explicitly label gap areas. This is done by changing the encoding of the columnEnd field of MappingRegion. This doesn't substantially increase binary size, and makes it easy to maintain backwards-compatibility. * Don't set the line count to a count from a gap area, unless the count comes from a wrapped segment. * Don't highlight gap areas as uncovered. Fixes llvm.org/PR34612. llvm-svn: 313597
Diffstat (limited to 'llvm/lib/ProfileData')
-rw-r--r--llvm/lib/ProfileData/Coverage/CoverageMapping.cpp14
-rw-r--r--llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp16
-rw-r--r--llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp1
3 files changed, 24 insertions, 7 deletions
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
index 81e1c6bc645..4c257cf38e5 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp
@@ -320,7 +320,7 @@ class SegmentBuilder {
/// Emit a segment with the count from \p Region starting at \p StartLoc.
//
- /// \p IsRegionEntry: The segment is at the start of a new region.
+ /// \p IsRegionEntry: The segment is at the start of a new non-gap region.
/// \p EmitSkippedRegion: The segment must be emitted as a skipped region.
void startSegment(const CountedRegion &Region, LineColPair StartLoc,
bool IsRegionEntry, bool EmitSkippedRegion = false) {
@@ -337,7 +337,8 @@ class SegmentBuilder {
if (HasCount)
Segments.emplace_back(StartLoc.first, StartLoc.second,
- Region.ExecutionCount, IsRegionEntry);
+ Region.ExecutionCount, IsRegionEntry,
+ Region.Kind == CounterMappingRegion::GapRegion);
else
Segments.emplace_back(StartLoc.first, StartLoc.second, IsRegionEntry);
@@ -346,7 +347,8 @@ class SegmentBuilder {
dbgs() << "Segment at " << Last.Line << ":" << Last.Col
<< " (count = " << Last.Count << ")"
<< (Last.IsRegionEntry ? ", RegionEntry" : "")
- << (!Last.HasCount ? ", Skipped" : "") << "\n";
+ << (!Last.HasCount ? ", Skipped" : "")
+ << (Last.IsGapRegion ? ", Gap" : "") << "\n";
});
}
@@ -419,20 +421,22 @@ class SegmentBuilder {
completeRegionsUntil(CurStartLoc, FirstCompletedRegion);
}
+ bool GapRegion = CR.value().Kind == CounterMappingRegion::GapRegion;
+
// Try to emit a segment for the current region.
if (CurStartLoc == CR.value().endLoc()) {
// Avoid making zero-length regions active. If it's the last region,
// emit a skipped segment. Otherwise use its predecessor's count.
const bool Skipped = (CR.index() + 1) == Regions.size();
startSegment(ActiveRegions.empty() ? CR.value() : *ActiveRegions.back(),
- CurStartLoc, true, Skipped);
+ CurStartLoc, !GapRegion, Skipped);
continue;
}
if (CR.index() + 1 == Regions.size() ||
CurStartLoc != Regions[CR.index() + 1].startLoc()) {
// Emit a segment if the next region doesn't start at the same location
// as this one.
- startSegment(CR.value(), CurStartLoc, true);
+ startSegment(CR.value(), CurStartLoc, !GapRegion);
}
// This region is active (i.e not completed).
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
index 9bf70c2e3aa..467a36ca748 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp
@@ -216,6 +216,13 @@ Error RawCoverageMappingReader::readMappingRegionsSubArray(
if (auto Err = readIntMax(ColumnEnd, std::numeric_limits<unsigned>::max()))
return Err;
LineStart += LineStartDelta;
+
+ // If the high bit of ColumnEnd is set, this is a gap region.
+ if (ColumnEnd & (1U << 31)) {
+ Kind = CounterMappingRegion::GapRegion;
+ ColumnEnd &= ~(1U << 31);
+ }
+
// Adjust the column locations for the empty regions that are supposed to
// cover whole lines. Those regions should be encoded with the
// column range (1 -> std::numeric_limits<unsigned>::max()), but because
@@ -534,11 +541,16 @@ Expected<std::unique_ptr<CovMapFuncRecordReader>> CovMapFuncRecordReader::get(
return llvm::make_unique<VersionedCovMapFuncRecordReader<
CovMapVersion::Version1, IntPtrT, Endian>>(P, R, F);
case CovMapVersion::Version2:
+ case CovMapVersion::Version3:
// Decompress the name data.
if (Error E = P.create(P.getNameData()))
return std::move(E);
- return llvm::make_unique<VersionedCovMapFuncRecordReader<
- CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
+ if (Version == CovMapVersion::Version2)
+ return llvm::make_unique<VersionedCovMapFuncRecordReader<
+ CovMapVersion::Version2, IntPtrT, Endian>>(P, R, F);
+ else
+ return llvm::make_unique<VersionedCovMapFuncRecordReader<
+ CovMapVersion::Version3, IntPtrT, Endian>>(P, R, F);
}
llvm_unreachable("Unsupported version");
}
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
index 4a1ce16c486..49e82e48105 100644
--- a/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
+++ b/llvm/lib/ProfileData/Coverage/CoverageMappingWriter.cpp
@@ -171,6 +171,7 @@ void CoverageMappingWriter::write(raw_ostream &OS) {
Counter Count = Minimizer.adjust(I->Count);
switch (I->Kind) {
case CounterMappingRegion::CodeRegion:
+ case CounterMappingRegion::GapRegion:
writeCounter(MinExpressions, Count, OS);
break;
case CounterMappingRegion::ExpansionRegion: {
OpenPOWER on IntegriCloud