diff options
author | Vedant Kumar <vsk@apple.com> | 2017-10-18 23:58:28 +0000 |
---|---|---|
committer | Vedant Kumar <vsk@apple.com> | 2017-10-18 23:58:28 +0000 |
commit | 821160d5efc38b84cd51efc4d94acd3948e22873 (patch) | |
tree | c54a57109398ecdb5e33ca063a2ddf80bce2ca3c /llvm/lib/ProfileData | |
parent | e955f6183749410992ef358b2d49b8cae2acaae1 (diff) | |
download | bcm5719-llvm-821160d5efc38b84cd51efc4d94acd3948e22873.tar.gz bcm5719-llvm-821160d5efc38b84cd51efc4d94acd3948e22873.zip |
[llvm-cov] Move LineCoverageIterator to libCoverage. NFC.
LineCoverageIterator makes it easy for clients of coverage data to
determine line execution counts for a file or function. The coverage
iteration logic is tricky enough that it really pays not to have
multiple copies of it. Hopefully having just one implementation in LLVM
will make the iteration logic easier to test, reuse, and update.
This commit is NFC but I've added a unit test to go along with it just
because it's easy to do now.
llvm-svn: 316141
Diffstat (limited to 'llvm/lib/ProfileData')
-rw-r--r-- | llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 52f9447aa3e..bda61768e7b 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -671,6 +671,59 @@ CoverageData CoverageMapping::getCoverageForExpansion( return ExpansionCoverage; } +LineCoverageStats::LineCoverageStats( + ArrayRef<const coverage::CoverageSegment *> LineSegments, + const coverage::CoverageSegment *WrappedSegment, unsigned Line) + : ExecutionCount(0), HasMultipleRegions(false), Mapped(false), Line(Line), + LineSegments(LineSegments), WrappedSegment(WrappedSegment) { + // Find the minimum number of regions which start in this line. + unsigned MinRegionCount = 0; + auto isStartOfRegion = [](const coverage::CoverageSegment *S) { + return !S->IsGapRegion && S->HasCount && S->IsRegionEntry; + }; + for (unsigned I = 0; I < LineSegments.size() && MinRegionCount < 2; ++I) + if (isStartOfRegion(LineSegments[I])) + ++MinRegionCount; + + bool StartOfSkippedRegion = !LineSegments.empty() && + !LineSegments.front()->HasCount && + LineSegments.front()->IsRegionEntry; + + HasMultipleRegions = MinRegionCount > 1; + Mapped = + !StartOfSkippedRegion && + ((WrappedSegment && WrappedSegment->HasCount) || (MinRegionCount > 0)); + + if (!Mapped) + return; + + // Pick the max count from the non-gap, region entry segments. If there + // aren't any, use the wrapped count. + if (!MinRegionCount) { + ExecutionCount = WrappedSegment->Count; + return; + } + for (const auto *LS : LineSegments) + if (isStartOfRegion(LS)) + ExecutionCount = std::max(ExecutionCount, LS->Count); +} + +LineCoverageIterator &LineCoverageIterator::operator++() { + if (Next == CD.end()) { + Stats = LineCoverageStats(); + Ended = true; + return *this; + } + if (Segments.size()) + WrappedSegment = Segments.back(); + Segments.clear(); + while (Next != CD.end() && Next->Line == Line) + Segments.push_back(&*Next++); + Stats = LineCoverageStats(Segments, WrappedSegment, Line); + ++Line; + return *this; +} + static std::string getCoverageMapErrString(coveragemap_error Err) { switch (Err) { case coveragemap_error::success: |