diff options
author | Igor Kudrin <ikudrin.dev@gmail.com> | 2016-05-05 09:39:45 +0000 |
---|---|---|
committer | Igor Kudrin <ikudrin.dev@gmail.com> | 2016-05-05 09:39:45 +0000 |
commit | 27d8dd39cf3c1fde9ce24bf7a5e8a36ce232582b (patch) | |
tree | e895dfc22976db0f728b7db8e9006335c0300bd9 /llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | |
parent | bb06ffaff39b9d0a1f008b5fa49438b1641e500c (diff) | |
download | bcm5719-llvm-27d8dd39cf3c1fde9ce24bf7a5e8a36ce232582b.tar.gz bcm5719-llvm-27d8dd39cf3c1fde9ce24bf7a5e8a36ce232582b.zip |
[Coverage] Combine counts of expansion regions if there are no code regions for the same area.
Differential Revision: http://reviews.llvm.org/D18831
llvm-svn: 268620
Diffstat (limited to 'llvm/lib/ProfileData/Coverage/CoverageMapping.cpp')
-rw-r--r-- | llvm/lib/ProfileData/Coverage/CoverageMapping.cpp | 47 |
1 files changed, 31 insertions, 16 deletions
diff --git a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp index 5d86f1de3ad..9fdd37081c9 100644 --- a/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/Coverage/CoverageMapping.cpp @@ -334,13 +334,25 @@ class SegmentBuilder { /// Sort a nested sequence of regions from a single file. static void sortNestedRegions(MutableArrayRef<CountedRegion> Regions) { - std::sort(Regions.begin(), Regions.end(), - [](const CountedRegion &LHS, const CountedRegion &RHS) { - if (LHS.startLoc() == RHS.startLoc()) - // When LHS completely contains RHS, we sort LHS first. - return RHS.endLoc() < LHS.endLoc(); - return LHS.startLoc() < RHS.startLoc(); - }); + std::sort(Regions.begin(), Regions.end(), [](const CountedRegion &LHS, + const CountedRegion &RHS) { + if (LHS.startLoc() != RHS.startLoc()) + return LHS.startLoc() < RHS.startLoc(); + if (LHS.endLoc() != RHS.endLoc()) + // When LHS completely contains RHS, we sort LHS first. + return RHS.endLoc() < LHS.endLoc(); + // If LHS and RHS cover the same area, we need to sort them according + // to their kinds so that the most suitable region will become "active" + // in combineRegions(). Because we accumulate counter values only from + // regions of the same kind as the first region of the area, prefer + // CodeRegion to ExpansionRegion and ExpansionRegion to SkippedRegion. + static_assert(coverage::CounterMappingRegion::CodeRegion < + coverage::CounterMappingRegion::ExpansionRegion && + coverage::CounterMappingRegion::ExpansionRegion < + coverage::CounterMappingRegion::SkippedRegion, + "Unexpected order of region kind values"); + return LHS.Kind < RHS.Kind; + }); } /// Combine counts of regions which cover the same area. @@ -360,15 +372,18 @@ class SegmentBuilder { continue; } // Merge duplicate region. - if (I->Kind != coverage::CounterMappingRegion::CodeRegion) - // Add counts only from CodeRegions. - continue; - if (Active->Kind == coverage::CounterMappingRegion::SkippedRegion) - // We have to overwrite SkippedRegions because of special handling - // of them in startSegment(). - *Active = *I; - else - // Otherwise, just append the count. + // If CodeRegions and ExpansionRegions cover the same area, it's probably + // a macro which is fully expanded to another macro. In that case, we need + // to accumulate counts only from CodeRegions, or else the area will be + // counted twice. + // On the other hand, a macro may have a nested macro in its body. If the + // outer macro is used several times, the ExpansionRegion for the nested + // macro will also be added several times. These ExpansionRegions cover + // the same source locations and have to be combined to reach the correct + // value for that area. + // We add counts of the regions of the same kind as the active region + // to handle the both situations. + if (I->Kind == Active->Kind) Active->ExecutionCount += I->ExecutionCount; } return Regions.drop_back(std::distance(++Active, End)); |