diff options
author | Justin Bogner <mail@justinbogner.com> | 2014-10-02 16:04:03 +0000 |
---|---|---|
committer | Justin Bogner <mail@justinbogner.com> | 2014-10-02 16:04:03 +0000 |
commit | d6a9e4b3bea625545cebdcd6247e78a922211a9d (patch) | |
tree | f04b0fc4b9b2f70a81ec03a2f0869dcbc04cb6d0 /llvm/lib/ProfileData/CoverageMapping.cpp | |
parent | 51d1c74d78913adc409fb0727341d1f7637428bf (diff) | |
download | bcm5719-llvm-d6a9e4b3bea625545cebdcd6247e78a922211a9d.tar.gz bcm5719-llvm-d6a9e4b3bea625545cebdcd6247e78a922211a9d.zip |
InstrProf: Don't keep a large sparse list around just to zero it
The Terms vector here represented a polynomial of of all possible
counters, and is used to simplify expressions when generating coverage
mapping. There are a few problems with this:
1. Keeping the vector as a member is wasteful, since we clear it every
time we use it.
2. Most expressions refer to a subset of the counters, so we end up
iterating over a large number of zeros doing nothing a lot of the
time.
This updates the user of the vector to store the terms locally, and
uses a sort and combine approach so that we only operate on counters
that are actually used in a given expression. For small cases this
makes very little difference, but in cases with a very large number of
counted regions this is a significant performance fix.
llvm-svn: 218879
Diffstat (limited to 'llvm/lib/ProfileData/CoverageMapping.cpp')
-rw-r--r-- | llvm/lib/ProfileData/CoverageMapping.cpp | 62 |
1 files changed, 38 insertions, 24 deletions
diff --git a/llvm/lib/ProfileData/CoverageMapping.cpp b/llvm/lib/ProfileData/CoverageMapping.cpp index 115256358ed..3a568720b08 100644 --- a/llvm/lib/ProfileData/CoverageMapping.cpp +++ b/llvm/lib/ProfileData/CoverageMapping.cpp @@ -27,10 +27,6 @@ using namespace coverage; #define DEBUG_TYPE "coverage-mapping" -CounterExpressionBuilder::CounterExpressionBuilder(unsigned NumCounterValues) { - Terms.resize(NumCounterValues); -} - Counter CounterExpressionBuilder::get(const CounterExpression &E) { for (unsigned I = 0, S = Expressions.size(); I < S; ++I) { if (Expressions[I] == E) @@ -40,50 +36,68 @@ Counter CounterExpressionBuilder::get(const CounterExpression &E) { return Counter::getExpression(Expressions.size() - 1); } -void CounterExpressionBuilder::extractTerms(Counter C, int Sign) { +void CounterExpressionBuilder::extractTerms( + Counter C, int Sign, SmallVectorImpl<std::pair<unsigned, int>> &Terms) { switch (C.getKind()) { case Counter::Zero: break; case Counter::CounterValueReference: - Terms[C.getCounterID()] += Sign; + Terms.push_back(std::make_pair(C.getCounterID(), Sign)); break; case Counter::Expression: const auto &E = Expressions[C.getExpressionID()]; - extractTerms(E.LHS, Sign); - extractTerms(E.RHS, E.Kind == CounterExpression::Subtract ? -Sign : Sign); + extractTerms(E.LHS, Sign, Terms); + extractTerms(E.RHS, E.Kind == CounterExpression::Subtract ? -Sign : Sign, + Terms); break; } } Counter CounterExpressionBuilder::simplify(Counter ExpressionTree) { // Gather constant terms. - for (auto &I : Terms) - I = 0; - extractTerms(ExpressionTree); + llvm::SmallVector<std::pair<unsigned, int>, 32> Terms; + extractTerms(ExpressionTree, +1, Terms); + + // Group the terms by counter ID. + std::sort(Terms.begin(), Terms.end(), + [](const std::pair<unsigned, int> &LHS, + const std::pair<unsigned, int> &RHS) { + return LHS.first < RHS.first; + }); + + // Combine terms by counter ID to eliminate counters that sum to zero. + auto Prev = Terms.begin(); + for (auto I = Prev + 1, E = Terms.end(); I != E; ++I) { + if (I->first == Prev->first) { + Prev->second += I->second; + continue; + } + ++Prev; + *Prev = *I; + } + Terms.erase(++Prev, Terms.end()); Counter C; - // Create additions. - // Note: the additions are created first - // to avoid creation of a tree like ((0 - X) + Y) instead of (Y - X). - for (unsigned I = 0, S = Terms.size(); I < S; ++I) { - if (Terms[I] <= 0) + // Create additions. We do this before subtractions to avoid constructs like + // ((0 - X) + Y), as opposed to (Y - X). + for (auto Term : Terms) { + if (Term.second <= 0) continue; - for (int J = 0; J < Terms[I]; ++J) { + for (int I = 0; I < Term.second; ++I) if (C.isZero()) - C = Counter::getCounter(I); + C = Counter::getCounter(Term.first); else C = get(CounterExpression(CounterExpression::Add, C, - Counter::getCounter(I))); - } + Counter::getCounter(Term.first))); } // Create subtractions. - for (unsigned I = 0, S = Terms.size(); I < S; ++I) { - if (Terms[I] >= 0) + for (auto Term : Terms) { + if (Term.second >= 0) continue; - for (int J = 0; J < (-Terms[I]); ++J) + for (int I = 0; I < -Term.second; ++I) C = get(CounterExpression(CounterExpression::Subtract, C, - Counter::getCounter(I))); + Counter::getCounter(Term.first))); } return C; } |