Skip to content

Commit 61b294a

Browse files
authored
Introduce CounterExpressionBuilder::subst(C, Map) (#112698)
This return a counter for each term in the expression replaced by ReplaceMap. At the moment, this doesn't update the Map, so Map is marked as `const`.
1 parent 24a92f5 commit 61b294a

File tree

3 files changed

+73
-0
lines changed

3 files changed

+73
-0
lines changed

llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <cassert>
3535
#include <cstdint>
3636
#include <iterator>
37+
#include <map>
3738
#include <memory>
3839
#include <optional>
3940
#include <sstream>
@@ -214,6 +215,14 @@ class CounterExpressionBuilder {
214215
/// Return a counter that represents the expression that subtracts RHS from
215216
/// LHS.
216217
Counter subtract(Counter LHS, Counter RHS, bool Simplify = true);
218+
219+
/// K to V map. K will be Counter in most cases. V may be Counter or
220+
/// Expression.
221+
using SubstMap = std::map<Counter, Counter>;
222+
223+
/// \return A counter equivalent to \C, with each term in its
224+
/// expression replaced with term from \p Map.
225+
Counter subst(Counter C, const SubstMap &Map);
217226
};
218227

219228
using LineColPair = std::pair<unsigned, unsigned>;

llvm/lib/ProfileData/Coverage/CoverageMapping.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,31 @@ Counter CounterExpressionBuilder::subtract(Counter LHS, Counter RHS,
135135
return Simplify ? simplify(Cnt) : Cnt;
136136
}
137137

138+
Counter CounterExpressionBuilder::subst(Counter C, const SubstMap &Map) {
139+
// Replace C with the value found in Map even if C is Expression.
140+
if (auto I = Map.find(C); I != Map.end())
141+
return I->second;
142+
143+
if (!C.isExpression())
144+
return C;
145+
146+
auto CE = Expressions[C.getExpressionID()];
147+
auto NewLHS = subst(CE.LHS, Map);
148+
auto NewRHS = subst(CE.RHS, Map);
149+
150+
// Reconstruct Expression with induced subexpressions.
151+
switch (CE.Kind) {
152+
case CounterExpression::Add:
153+
C = add(NewLHS, NewRHS);
154+
break;
155+
case CounterExpression::Subtract:
156+
C = subtract(NewLHS, NewRHS);
157+
break;
158+
}
159+
160+
return C;
161+
}
162+
138163
void CounterMappingContext::dump(const Counter &C, raw_ostream &OS) const {
139164
switch (C.getKind()) {
140165
case Counter::Zero:

llvm/unittests/ProfileData/CoverageMappingTest.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,45 @@ struct CoverageMappingTest : ::testing::TestWithParam<std::tuple<bool, bool>> {
291291
}
292292
};
293293

294+
TEST(CoverageMappingTest, expression_subst) {
295+
CounterExpressionBuilder Builder;
296+
CounterExpressionBuilder::SubstMap MapToExpand;
297+
298+
auto C = [](unsigned ID) { return Counter::getCounter(ID); };
299+
auto A = [&](Counter LHS, Counter RHS) { return Builder.add(LHS, RHS); };
300+
// returns {E, N} in clangCodeGen
301+
auto getBranchCounterPair = [&](Counter E, Counter P, Counter N) {
302+
auto Skipped = Builder.subtract(P, E);
303+
MapToExpand[N] = Builder.subst(Skipped, MapToExpand);
304+
};
305+
306+
auto E18 = C(5);
307+
auto P18 = C(2);
308+
auto S18 = C(18);
309+
// #18 => (#2 - #5)
310+
getBranchCounterPair(E18, P18, S18);
311+
312+
auto E22 = S18;
313+
auto P22 = C(0);
314+
auto S22 = C(22);
315+
// #22 => #0 - (#2 - #5)
316+
getBranchCounterPair(E22, P22, S22);
317+
318+
auto E28 = A(A(C(9), C(11)), C(14));
319+
auto P28 = S22;
320+
auto S28 = C(28);
321+
// #28 => (((((#0 + #5) - #2) - #9) - #11) - #14)
322+
getBranchCounterPair(E28, P28, S28);
323+
324+
auto LHS = A(E28, A(S28, S18));
325+
auto RHS = C(0);
326+
327+
// W/o subst, LHS cannot be reduced.
328+
ASSERT_FALSE(Builder.subtract(LHS, RHS).isZero());
329+
// W/ subst, C(18) and C(28) in LHS will be reduced.
330+
ASSERT_TRUE(Builder.subst(Builder.subtract(LHS, RHS), MapToExpand).isZero());
331+
}
332+
294333
TEST_P(CoverageMappingTest, basic_write_read) {
295334
startFunction("func", 0x1234);
296335
addCMR(Counter::getCounter(0), "foo", 1, 1, 1, 1);

0 commit comments

Comments
 (0)