Index: llvm/trunk/include/llvm/ProfileData/CoverageMapping.h =================================================================== --- llvm/trunk/include/llvm/ProfileData/CoverageMapping.h +++ llvm/trunk/include/llvm/ProfileData/CoverageMapping.h @@ -144,17 +144,24 @@ SkippedRegion }; + static const unsigned EncodingHasCodeBeforeBits = 1; + Counter Count; unsigned FileID, ExpandedFileID; unsigned LineStart, ColumnStart, LineEnd, ColumnEnd; RegionKind Kind; + /// \brief A flag that is set to true when there is already code before + /// this region on the same line. + /// This is useful to accurately compute the execution counts for a line. + bool HasCodeBefore; CounterMappingRegion(Counter Count, unsigned FileID, unsigned LineStart, unsigned ColumnStart, unsigned LineEnd, - unsigned ColumnEnd, RegionKind Kind = CodeRegion) + unsigned ColumnEnd, bool HasCodeBefore = false, + RegionKind Kind = CodeRegion) : Count(Count), FileID(FileID), ExpandedFileID(0), LineStart(LineStart), ColumnStart(ColumnStart), LineEnd(LineEnd), ColumnEnd(ColumnEnd), - Kind(Kind) {} + Kind(Kind), HasCodeBefore(HasCodeBefore) {} bool operator<(const CounterMappingRegion &Other) const { if (FileID != Other.FileID) Index: llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp =================================================================== --- llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp +++ llvm/trunk/lib/ProfileData/CoverageMappingReader.cpp @@ -170,13 +170,17 @@ } // Read the source range. - uint64_t LineStartDelta, ColumnStart, NumLines, ColumnEnd; + uint64_t LineStartDelta, CodeBeforeColumnStart, NumLines, ColumnEnd; if (auto Err = readIntMax(LineStartDelta, std::numeric_limits::max())) return Err; - if (auto Err = - readIntMax(ColumnStart, std::numeric_limits::max())) + if (auto Err = readULEB128(CodeBeforeColumnStart)) return Err; + bool HasCodeBefore = CodeBeforeColumnStart & 1; + uint64_t ColumnStart = CodeBeforeColumnStart >> + CounterMappingRegion::EncodingHasCodeBeforeBits; + if (ColumnStart > std::numeric_limits::max()) + return error(instrprof_error::malformed); if (auto Err = readIntMax(NumLines, std::numeric_limits::max())) return Err; if (auto Err = readIntMax(ColumnEnd, std::numeric_limits::max())) @@ -194,9 +198,9 @@ ColumnStart = 1; ColumnEnd = std::numeric_limits::max(); } - MappingRegions.push_back( - CounterMappingRegion(C, InferredFileID, LineStart, ColumnStart, - LineStart + NumLines, ColumnEnd, Kind)); + MappingRegions.push_back(CounterMappingRegion( + C, InferredFileID, LineStart, ColumnStart, LineStart + NumLines, + ColumnEnd, HasCodeBefore, Kind)); MappingRegions.back().ExpandedFileID = ExpandedFileID; } return success(); Index: llvm/trunk/lib/ProfileData/CoverageMappingWriter.cpp =================================================================== --- llvm/trunk/lib/ProfileData/CoverageMappingWriter.cpp +++ llvm/trunk/lib/ProfileData/CoverageMappingWriter.cpp @@ -181,7 +181,11 @@ } assert(I.LineStart >= PrevLineStart); encodeULEB128(I.LineStart - PrevLineStart, OS); - encodeULEB128(I.ColumnStart, OS); + uint64_t CodeBeforeColumnStart = + uint64_t(I.HasCodeBefore) | + (uint64_t(I.ColumnStart) + << CounterMappingRegion::EncodingHasCodeBeforeBits); + encodeULEB128(CodeBeforeColumnStart, OS); assert(I.LineEnd >= I.LineStart); encodeULEB128(I.LineEnd - I.LineStart, OS); encodeULEB128(I.ColumnEnd, OS);