summaryrefslogtreecommitdiffstats
path: root/llvm/lib/ProfileData
diff options
context:
space:
mode:
authorVedant Kumar <vsk@apple.com>2017-10-18 23:58:28 +0000
committerVedant Kumar <vsk@apple.com>2017-10-18 23:58:28 +0000
commit821160d5efc38b84cd51efc4d94acd3948e22873 (patch)
treec54a57109398ecdb5e33ca063a2ddf80bce2ca3c /llvm/lib/ProfileData
parente955f6183749410992ef358b2d49b8cae2acaae1 (diff)
downloadbcm5719-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.cpp53
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:
OpenPOWER on IntegriCloud