summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/test/tools/llvm-cov/Inputs/deferred-regions.covmappingbin0 -> 688 bytes
-rw-r--r--llvm/test/tools/llvm-cov/Inputs/deferred-regions.profdatabin0 -> 1208 bytes
-rw-r--r--llvm/test/tools/llvm-cov/deferred-region.cpp79
-rw-r--r--llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp4
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageView.cpp45
-rw-r--r--llvm/tools/llvm-cov/SourceCoverageView.h18
6 files changed, 122 insertions, 24 deletions
diff --git a/llvm/test/tools/llvm-cov/Inputs/deferred-regions.covmapping b/llvm/test/tools/llvm-cov/Inputs/deferred-regions.covmapping
new file mode 100644
index 00000000000..757f3eea720
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/deferred-regions.covmapping
Binary files differ
diff --git a/llvm/test/tools/llvm-cov/Inputs/deferred-regions.profdata b/llvm/test/tools/llvm-cov/Inputs/deferred-regions.profdata
new file mode 100644
index 00000000000..0bacac01ccf
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/Inputs/deferred-regions.profdata
Binary files differ
diff --git a/llvm/test/tools/llvm-cov/deferred-region.cpp b/llvm/test/tools/llvm-cov/deferred-region.cpp
new file mode 100644
index 00000000000..3704d0ed515
--- /dev/null
+++ b/llvm/test/tools/llvm-cov/deferred-region.cpp
@@ -0,0 +1,79 @@
+// RUN: llvm-cov show %S/Inputs/deferred-regions.covmapping -instr-profile %S/Inputs/deferred-regions.profdata -show-line-counts-or-regions -dump -filename-equivalence %s 2>&1 | FileCheck %s
+
+void foo(int x) {
+ if (x == 0) {
+ return; // CHECK: [[@LINE]]|{{ +}}1|
+ }
+
+} // CHECK: [[@LINE]]|{{ +}}2|
+
+void bar() {
+ return;
+
+} // CHECK: [[@LINE]]|{{ +}}1|
+
+void for_loop() {
+ if (false)
+ return; // CHECK: [[@LINE]]|{{ +}}0|
+
+ for (int i = 0; i < 10; ++i) { // CHECK: [[@LINE]]|{{ +}}2|
+ if (i % 2 == 0)
+ continue; // CHECK: [[@LINE]]|{{ +}}1|
+
+ if (i % 5 == 0)
+ break; // CHECK: [[@LINE]]|{{ +}}0|
+
+ int x = i;
+ return; // CHECK: [[@LINE]]|{{ +}}1|
+
+ } // CHECK: [[@LINE]]|{{ +}}1|
+}
+
+struct Error {};
+
+void while_loop() {
+ if (false)
+ return; // CHECK: [[@LINE]]|{{ +}}0|
+
+ int x = 0;
+ while (++x < 10) { // CHECK: [[@LINE]]|{{ +}}3|
+ if (x == 1)
+ continue; // CHECK: [[@LINE]]|{{ +}}1|
+
+ while (++x < 4) { // CHECK: [[@LINE]]|{{ +}}1|
+ if (x == 3)
+ break; // CHECK: [[@LINE]]|{{ +}}1|
+ // CHECK: [[@LINE]]|{{ +}}0|
+ while (++x < 5) {} // CHECK: [[@LINE]]|{{ +}}0|
+ } // CHECK: [[@LINE]]|{{ +}}1|
+
+ if (x == 0)
+ throw Error(); // CHECK: [[@LINE]]|{{ +}}0|
+
+ while (++x < 9) { // CHECK: [[@LINE]]|{{ +}}6|
+ if (x == 0) // CHECK: [[@LINE]]|{{ +}}5|
+ break; // CHECK: [[@LINE]]|{{ +}}0|
+
+ }
+ }
+}
+
+void gotos() {
+ if (false)
+ goto out; // CHECK: [[@LINE]]|{{ +}}0|
+
+ return;
+
+out: // CHECK: [[@LINE]]|{{ +}}1|
+ return;
+}
+
+int main() {
+ foo(0);
+ foo(1);
+ bar();
+ for_loop();
+ while_loop();
+ gotos();
+ return 0;
+}
diff --git a/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp b/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
index bdb0e1bd3a9..4bc3ad5dfdc 100644
--- a/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
+++ b/llvm/test/tools/llvm-cov/showLineExecutionCounts.cpp
@@ -6,7 +6,7 @@
int main() { // TEXT: [[@LINE]]| 161|int main(
int x = 0; // TEXT: [[@LINE]]| 161| int x
// TEXT: [[@LINE]]| 161|
- if (x) { // TEXT: [[@LINE]]| 0| if (x)
+ if (x) { // TEXT: [[@LINE]]| 161| if (x)
x = 0; // TEXT: [[@LINE]]| 0| x = 0
} else { // TEXT: [[@LINE]]| 161| } else
x = 1; // TEXT: [[@LINE]]| 161| x = 1
@@ -50,7 +50,7 @@ int main() { // TEXT: [[@LINE]]| 161|int main(
// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>int main() {
// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre> int x = 0
// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre>
-// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre> if (x) {
+// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre> if (x) {
// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='uncovered-line'><pre>0</pre></td><td class='code'><pre>
// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre><span class='red'> }</span>
// HTML: <td class='line-number'><a name='L[[@LINE-44]]' href='#L[[@LINE-44]]'><pre>[[@LINE-44]]</pre></a></td><td class='covered-line'><pre>161</pre></td><td class='code'><pre> x = 1;
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.cpp b/llvm/tools/llvm-cov/SourceCoverageView.cpp
index 52b8ff1747f..6630f3333bd 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.cpp
+++ b/llvm/tools/llvm-cov/SourceCoverageView.cpp
@@ -83,6 +83,41 @@ CoveragePrinter::create(const CoverageViewOptions &Opts) {
llvm_unreachable("Unknown coverage output format!");
}
+LineCoverageStats::LineCoverageStats(
+ ArrayRef<const coverage::CoverageSegment *> LineSegments,
+ const coverage::CoverageSegment *WrappedSegment) {
+ // Find the minimum number of regions which start in this line.
+ unsigned MinRegionCount = 0;
+ auto isStartOfRegion = [](const coverage::CoverageSegment *S) {
+ return S->HasCount && S->IsRegionEntry;
+ };
+ for (unsigned I = 0; I < LineSegments.size() && MinRegionCount < 2; ++I)
+ if (isStartOfRegion(LineSegments[I]))
+ ++MinRegionCount;
+
+ ExecutionCount = 0;
+ HasMultipleRegions = MinRegionCount > 1;
+ Mapped = (WrappedSegment && WrappedSegment->HasCount) || (MinRegionCount > 0);
+
+ if (!Mapped)
+ return;
+
+ // Pick the max count among regions which start and end on this line, to
+ // avoid erroneously using the wrapped count, and to avoid picking region
+ // counts which come from deferred regions.
+ if (LineSegments.size() > 1) {
+ for (unsigned I = 0; I < LineSegments.size() - 1; ++I)
+ ExecutionCount = std::max(ExecutionCount, LineSegments[I]->Count);
+ return;
+ }
+
+ // Just pick the maximum count.
+ if (WrappedSegment && WrappedSegment->HasCount)
+ ExecutionCount = WrappedSegment->Count;
+ if (!LineSegments.empty())
+ ExecutionCount = std::max(ExecutionCount, LineSegments[0]->Count);
+}
+
unsigned SourceCoverageView::getFirstUncoveredLineNo() {
auto CheckIfUncovered = [](const coverage::CoverageSegment &S) {
return S.HasCount && S.Count == 0;
@@ -207,17 +242,11 @@ void SourceCoverageView::print(raw_ostream &OS, bool WholeFile,
while (NextSegment != EndSegment && NextSegment->Line == LI.line_number())
LineSegments.push_back(&*NextSegment++);
- // Calculate a count to be for the line as a whole.
- LineCoverageStats LineCount;
- if (WrappedSegment && WrappedSegment->HasCount)
- LineCount.addRegionCount(WrappedSegment->Count);
- for (const auto *S : LineSegments)
- if (S->HasCount && S->IsRegionEntry)
- LineCount.addRegionStartCount(S->Count);
-
renderLinePrefix(OS, ViewDepth);
if (getOptions().ShowLineNumbers)
renderLineNumberColumn(OS, LI.line_number());
+
+ LineCoverageStats LineCount{LineSegments, WrappedSegment};
if (getOptions().ShowLineStats)
renderLineCoverageColumn(OS, LineCount);
diff --git a/llvm/tools/llvm-cov/SourceCoverageView.h b/llvm/tools/llvm-cov/SourceCoverageView.h
index 9cb608fed60..c9f0c57b5cb 100644
--- a/llvm/tools/llvm-cov/SourceCoverageView.h
+++ b/llvm/tools/llvm-cov/SourceCoverageView.h
@@ -67,25 +67,15 @@ struct InstantiationView {
/// \brief Coverage statistics for a single line.
struct LineCoverageStats {
uint64_t ExecutionCount;
- unsigned RegionCount;
+ bool HasMultipleRegions;
bool Mapped;
- LineCoverageStats() : ExecutionCount(0), RegionCount(0), Mapped(false) {}
+ LineCoverageStats(ArrayRef<const coverage::CoverageSegment *> LineSegments,
+ const coverage::CoverageSegment *WrappedSegment);
bool isMapped() const { return Mapped; }
- bool hasMultipleRegions() const { return RegionCount > 1; }
-
- void addRegionStartCount(uint64_t Count) {
- // The max of all region starts is the most interesting value.
- addRegionCount(RegionCount ? std::max(ExecutionCount, Count) : Count);
- ++RegionCount;
- }
-
- void addRegionCount(uint64_t Count) {
- Mapped = true;
- ExecutionCount = Count;
- }
+ bool hasMultipleRegions() const { return HasMultipleRegions; }
};
/// \brief A file manager that handles format-aware file creation.
OpenPOWER on IntegriCloud