llvm-cov: Combine segments that cover the same location

If we have multiple coverage counts for the same segment, we need to
add them up rather than arbitrarily choosing one. This fixes that and
adds a test with template instantiations to exercise it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@218432 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Justin Bogner 2014-09-25 00:34:18 +00:00
parent 0253523c92
commit aacc919bfd
5 changed files with 62 additions and 4 deletions

View File

@ -274,6 +274,7 @@ struct CoverageSegment {
Count = NewCount;
HasCount = true;
}
void addCount(uint64_t NewCount) { setCount(Count + NewCount); }
};
/// \brief Coverage information to be processed or displayed.

View File

@ -19,11 +19,14 @@
#include "llvm/ADT/SmallSet.h"
#include "llvm/ProfileData/CoverageMappingReader.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
using namespace coverage;
#define DEBUG_TYPE "coverage-mapping"
CounterExpressionBuilder::CounterExpressionBuilder(unsigned NumCounterValues) {
Terms.resize(NumCounterValues);
}
@ -228,6 +231,7 @@ class SegmentBuilder {
/// Start a segment with no count specified.
void startSegment(unsigned Line, unsigned Col) {
DEBUG(dbgs() << "Top level segment at " << Line << ":" << Col << "\n");
Segments.emplace_back(Line, Col, /*IsRegionEntry=*/false);
}
@ -242,9 +246,13 @@ class SegmentBuilder {
Segments.emplace_back(Line, Col, IsRegionEntry);
S = Segments.back();
}
DEBUG(dbgs() << "Segment at " << Line << ":" << Col);
// Set this region's count.
if (Region.Kind != coverage::CounterMappingRegion::SkippedRegion)
if (Region.Kind != coverage::CounterMappingRegion::SkippedRegion) {
DEBUG(dbgs() << " with count " << Region.ExecutionCount);
Segments.back().setCount(Region.ExecutionCount);
}
DEBUG(dbgs() << "\n");
}
/// Start a segment for the given region.
@ -272,9 +280,15 @@ public:
while (!ActiveRegions.empty() &&
ActiveRegions.back()->endLoc() <= Region.startLoc())
popRegion();
// Add this region to the stack.
ActiveRegions.push_back(&Region);
startSegment(Region);
if (Segments.size() && Segments.back().Line == Region.LineStart &&
Segments.back().Col == Region.ColumnStart) {
if (Region.Kind != coverage::CounterMappingRegion::SkippedRegion)
Segments.back().addCount(Region.ExecutionCount);
} else {
// Add this region to the stack.
ActiveRegions.push_back(&Region);
startSegment(Region);
}
}
// Pop any regions that are left in the stack.
while (!ActiveRegions.empty())

View File

@ -0,0 +1,43 @@
// RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -no-colors -filename-equivalence %s | FileCheck -check-prefix=CHECK -check-prefix=ALL %s
// RUN: llvm-cov show %S/Inputs/templateInstantiations.covmapping -instr-profile %S/Inputs/templateInstantiations.profdata -no-colors -filename-equivalence -name=_Z4funcIbEiT_ %s | FileCheck -check-prefix=CHECK -check-prefix=FILTER %s
// before coverage // WHOLE-FILE: | [[@LINE]]|// before
// FILTER-NOT: | [[@LINE-1]]|// before
template<typename T> // ALL: | [[@LINE]]|template<typename T>
int func(T x) { // ALL-NEXT: 2| [[@LINE]]|int func(T x) {
if(x) // ALL-NEXT: 2| [[@LINE]]| if(x)
return 0; // ALL-NEXT: 1| [[@LINE]]| return 0;
else // ALL-NEXT: 1| [[@LINE]]| else
return 1; // ALL-NEXT: 1| [[@LINE]]| return 1;
int j = 1; // ALL-NEXT: 0| [[@LINE]]| int j = 1;
} // ALL-NEXT: 1| [[@LINE]]|}
// CHECK: {{^ *(\| )?}}_Z4funcIbEiT_:
// CHECK-NEXT: 1| [[@LINE-9]]|int func(T x) {
// CHECK-NEXT: 1| [[@LINE-9]]| if(x)
// CHECK-NEXT: 1| [[@LINE-9]]| return 0;
// CHECK-NEXT: 1| [[@LINE-9]]| else
// CHECK-NEXT: 0| [[@LINE-9]]| return 1;
// CHECK-NEXT: 0| [[@LINE-9]]| int j = 1;
// CHECK-NEXT: 1| [[@LINE-9]]|}
// ALL: {{^ *}}| _Z4funcIiEiT_:
// FILTER-NOT: {{^ *(\| )?}} _Z4funcIiEiT_:
// ALL-NEXT: 1| [[@LINE-19]]|int func(T x) {
// ALL-NEXT: 1| [[@LINE-19]]| if(x)
// ALL-NEXT: 0| [[@LINE-19]]| return 0;
// ALL-NEXT: 1| [[@LINE-19]]| else
// ALL-NEXT: 1| [[@LINE-19]]| return 1;
// ALL-NEXT: 0| [[@LINE-19]]| int j = 1;
// ALL-NEXT: 1| [[@LINE-19]]|}
int main() { // ALL: 1| [[@LINE]]|int main() {
func<int>(0); // ALL-NEXT: 1| [[@LINE]]| func<int>(0);
func<bool>(true); // ALL-NEXT: 1| [[@LINE]]| func<bool>(true);
return 0; // ALL-NEXT: 1| [[@LINE]]| return 0;
} // ALL-NEXT: 1| [[@LINE]]|}
// after coverage // ALL-NEXT: | [[@LINE]]|// after
// FILTER-NOT: | [[@LINE-1]]|// after
// llvm-cov doesn't work on big endian yet
// XFAIL: powerpc64-, s390x, mips-, mips64-, sparc