diff options
author | Vedant Kumar <vsk@apple.com> | 2017-09-18 23:37:28 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2017-09-18 23:37:28 +0000 |
commit | ad8f637bd83aeeca7321d6c74b3d7787587c0d55 (patch) | |
tree | e771084274c8fde30518a8c9f08c7ffb4e2cd3dd /llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | |
parent | 27d1b14ab056a3de64cf93c80a10886e2dc904f7 (diff) | |
download | llvm-ad8f637bd83aeeca7321d6c74b3d7787587c0d55.zip llvm-ad8f637bd83aeeca7321d6c74b3d7787587c0d55.tar.gz llvm-ad8f637bd83aeeca7321d6c74b3d7787587c0d55.tar.bz2 |
[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/Coverage/CoverageMapping.cpp')
-rw-r--r-- | llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 81e1c6b..4c257cf 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). |