diff options
author | Wei Mi <wmi@google.com> | 2016-07-20 16:40:33 +0000 |
---|---|---|
committer | Wei Mi <wmi@google.com> | 2016-07-20 16:40:33 +0000 |
commit | db80c0c77f5347b6f0126b0bb98ed20a39516fd0 (patch) | |
tree | a90658b91396d465a26dea3bdb5ea4602a3a8bf1 /llvm/lib/Analysis/ScalarEvolutionExpander.cpp | |
parent | be53c65fab8b240a8bbc804dec012ab0cf1422f4 (diff) | |
download | bcm5719-llvm-db80c0c77f5347b6f0126b0bb98ed20a39516fd0.tar.gz bcm5719-llvm-db80c0c77f5347b6f0126b0bb98ed20a39516fd0.zip |
Use ValueOffsetPair to enhance value reuse during SCEV expansion.
In D12090, the ExprValueMap was added to reuse existing value during SCEV expansion.
However, const folding and sext/zext distribution can make the reuse still difficult.
A simplified case is: suppose we know S1 expands to V1 in ExprValueMap, and
S1 = S2 + C_a
S3 = S2 + C_b
where C_a and C_b are different SCEVConstants. Then we'd like to expand S3 as
V1 - C_a + C_b instead of expanding S2 literally. It is helpful when S2 is a
complex SCEV expr and S2 has no entry in ExprValueMap, which is usually caused
by the fact that S3 is generated from S1 after const folding.
In order to do that, we represent ExprValueMap as a mapping from SCEV to
ValueOffsetPair. We will save both S1->{V1, 0} and S2->{V1, C_a} into the
ExprValueMap when we create SCEV for V1. When S3 is expanded, it will first
expand S2 to V1 - C_a because of S2->{V1, C_a} in the map, then expand S3 to
V1 - C_a + C_b.
Differential Revision: https://reviews.llvm.org/D21313
llvm-svn: 276136
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolutionExpander.cpp')
-rw-r--r-- | llvm/lib/Analysis/ScalarEvolutionExpander.cpp | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp index 77e4ec7ab40..87681d53e2f 100644 --- a/llvm/lib/Analysis/ScalarEvolutionExpander.cpp +++ b/llvm/lib/Analysis/ScalarEvolutionExpander.cpp @@ -1626,9 +1626,10 @@ 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); +ScalarEvolution::ValueOffsetPair +SCEVExpander::FindValueInExprValueMap(const SCEV *S, + const Instruction *InsertPt) { + SetVector<ScalarEvolution::ValueOffsetPair> *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)) { @@ -1637,21 +1638,21 @@ Value *SCEVExpander::FindValueInExprValueMap(const SCEV *S, // 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) { + for (auto const &VOPair : *Set) { + Value *V = VOPair.first; + ConstantInt *Offset = VOPair.second; Instruction *EntInst = nullptr; - if (Ent && isa<Instruction>(Ent) && - (EntInst = cast<Instruction>(Ent)) && - S->getType() == Ent->getType() && + if (V && isa<Instruction>(V) && (EntInst = cast<Instruction>(V)) && + S->getType() == V->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; - } + SE.LI.getLoopFor(EntInst->getParent())->contains(InsertPt))) + return {V, Offset}; } } } - return nullptr; + return {nullptr, nullptr}; } // The expansion of SCEV will either reuse a previous Value in ExprValueMap, @@ -1699,10 +1700,14 @@ Value *SCEVExpander::expand(const SCEV *S) { Builder.SetInsertPoint(InsertPt); // Expand the expression into instructions. - Value *V = FindValueInExprValueMap(S, InsertPt); + ScalarEvolution::ValueOffsetPair VO = FindValueInExprValueMap(S, InsertPt); + Value *V = VO.first; if (!V) V = visit(S); + else if (VO.second) { + V = Builder.CreateSub(V, VO.second); + } // Remember the expanded value for this SCEV at this location. // @@ -1915,7 +1920,7 @@ Value *SCEVExpander::findExistingExpansion(const SCEV *S, // Use expand's logic which is used for reusing a previous Value in // ExprValueMap. - if (Value *Val = FindValueInExprValueMap(S, At)) + if (Value *Val = FindValueInExprValueMap(S, At).first) return Val; // There is potential to make this significantly smarter, but this simple |