diff options
author | Junmo Park <junmoz.park@samsung.com> | 2016-02-16 06:46:58 +0000 |
---|---|---|
committer | Junmo Park <junmoz.park@samsung.com> | 2016-02-16 06:46:58 +0000 |
commit | 4ee5ab9daf89d7159a373d49668e4ca7f08972bb (patch) | |
tree | 179926fb511d01c347ea320aa4e49ee546903321 /lib/Analysis/ScalarEvolutionExpander.cpp | |
parent | b1fb18e8f74b382638ffff857c53f53d443e46d5 (diff) |
[SCEVExpander] Make findExistingExpansion smarter
Summary:
Extending findExistingExpansion can use existing value in ExprValueMap.
This patch gives 0.3~0.5% performance improvements on
benchmarks(test-suite, spec2000, spec2006, commercial benchmark)
Reviewers: mzolotukhin, sanjoy, zzheng
Differential Revision: http://reviews.llvm.org/D15559
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@260938 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ScalarEvolutionExpander.cpp')
-rw-r--r-- | lib/Analysis/ScalarEvolutionExpander.cpp | 60 |
1 files changed, 35 insertions, 25 deletions
diff --git a/lib/Analysis/ScalarEvolutionExpander.cpp b/lib/Analysis/ScalarEvolutionExpander.cpp index 45b0adac6ee..58c0c334a06 100644 --- a/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/lib/Analysis/ScalarEvolutionExpander.cpp @@ -1598,6 +1598,34 @@ Value *SCEVExpander::expandCodeFor(const SCEV *SH, Type *Ty) { return V; } +Value *SCEVExpander::FindValueInExprValueMap(const SCEV *S, + const Instruction *InsertPt) { + SetVector<Value *> *Set = SE.getSCEVValues(S); + // If the expansion is not in CanonicalMode, and the SCEV contains any + // sub scAddRecExpr type SCEV, it is required to expand the SCEV literally. + if (CanonicalMode || !SE.containsAddRecurrence(S)) { + // If S is scConstant, it may be worse to reuse an existing Value. + if (S->getSCEVType() != scConstant && Set) { + // Choose a Value from the set which dominates the insertPt. + // insertPt should be inside the Value's parent loop so as not to break + // the LCSSA form. + for (auto const &Ent : *Set) { + Instruction *EntInst = nullptr; + if (Ent && isa<Instruction>(Ent) && + (EntInst = cast<Instruction>(Ent)) && + S->getType() == Ent->getType() && + EntInst->getFunction() == InsertPt->getFunction() && + SE.DT.dominates(EntInst, InsertPt) && + (SE.LI.getLoopFor(EntInst->getParent()) == nullptr || + SE.LI.getLoopFor(EntInst->getParent())->contains(InsertPt))) { + return Ent; + } + } + } + } + return nullptr; +} + // The expansion of SCEV will either reuse a previous Value in ExprValueMap, // or expand the SCEV literally. Specifically, if the expansion is in LSRMode, // and the SCEV contains any sub scAddRecExpr type SCEV, it will be expanded @@ -1643,31 +1671,8 @@ Value *SCEVExpander::expand(const SCEV *S) { Builder.SetInsertPoint(InsertPt); // Expand the expression into instructions. - SetVector<Value *> *Set = SE.getSCEVValues(S); - Value *V = nullptr; - // If the expansion is not in CanonicalMode, and the SCEV contains any - // sub scAddRecExpr type SCEV, it is required to expand the SCEV literally. - if (CanonicalMode || !SE.containsAddRecurrence(S)) { - // If S is scConstant, it may be worse to reuse an existing Value. - if (S->getSCEVType() != scConstant && Set) { - // Choose a Value from the set which dominates the insertPt. - // insertPt should be inside the Value's parent loop so as not to break - // the LCSSA form. - for (auto const &Ent : *Set) { - Instruction *EntInst = nullptr; - if (Ent && isa<Instruction>(Ent) && - (EntInst = cast<Instruction>(Ent)) && - S->getType() == Ent->getType() && - EntInst->getFunction() == InsertPt->getFunction() && - SE.DT.dominates(EntInst, InsertPt) && - (SE.LI.getLoopFor(EntInst->getParent()) == nullptr || - SE.LI.getLoopFor(EntInst->getParent())->contains(InsertPt))) { - V = Ent; - break; - } - } - } - } + Value *V = FindValueInExprValueMap(S, InsertPt); + if (!V) V = visit(S); @@ -1877,6 +1882,11 @@ Value *SCEVExpander::findExistingExpansion(const SCEV *S, return RHS; } + // Use expand's logic which is used for reusing a previous Value in + // ExprValueMap. + if (Value *Val = FindValueInExprValueMap(S, At)) + return Val; + // There is potential to make this significantly smarter, but this simple // heuristic already gets some interesting cases. |