From ad8f637bd83aeeca7321d6c74b3d7787587c0d55 Mon Sep 17 00:00:00 2001 From: Vedant Kumar Date: Mon, 18 Sep 2017 23:37:28 +0000 Subject: [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 --- llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp') diff --git a/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp b/llvm/lib/ProfileData/Coverage/CoverageMappingReader.cpp index 9bf70c2..467a36c 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::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::max()), but because @@ -534,11 +541,16 @@ Expected> CovMapFuncRecordReader::get( return llvm::make_unique>(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>(P, R, F); + if (Version == CovMapVersion::Version2) + return llvm::make_unique>(P, R, F); + else + return llvm::make_unique>(P, R, F); } llvm_unreachable("Unsupported version"); } -- cgit v1.1