diff --git a/llvm/include/llvm/Analysis/ScalarEvolution.h b/llvm/include/llvm/Analysis/ScalarEvolution.h --- a/llvm/include/llvm/Analysis/ScalarEvolution.h +++ b/llvm/include/llvm/Analysis/ScalarEvolution.h @@ -537,6 +537,9 @@ std::pair getStrengthenedNoWrapFlagsFromBinOp(const OverflowingBinaryOperator *OBO); + /// Notify this ScalarEvolution that \p User directly uses SCEVs in \p Ops. + void registerUser(const SCEV *User, ArrayRef Ops); + /// Return a SCEV expression for the full generality of the specified /// expression. const SCEV *getSCEV(Value *V); @@ -1506,6 +1509,9 @@ /// Compute a BlockDisposition value. BlockDisposition computeBlockDisposition(const SCEV *S, const BasicBlock *BB); + /// Stores all SCEV that use a given SCEV as its direct operand. + DenseMap > SCEVUsers; + /// Memoized results from getRange DenseMap UnsignedRanges; diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -1099,6 +1099,7 @@ SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -1219,6 +1220,7 @@ new (SCEVAllocator) SCEVTruncateExpr(ID.Intern(SCEVAllocator), Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -1273,6 +1275,7 @@ Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -1602,6 +1605,7 @@ Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -1871,6 +1875,7 @@ Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -1910,6 +1915,7 @@ Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -2107,6 +2113,7 @@ Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, { Op }); return S; } @@ -2892,6 +2899,7 @@ SCEVAddExpr(ID.Intern(SCEVAllocator), O, Ops.size()); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Ops); } S->setNoWrapFlags(Flags); return S; @@ -2915,6 +2923,7 @@ SCEVAddRecExpr(ID.Intern(SCEVAllocator), O, Ops.size(), L); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Ops); } setNoWrapFlags(S, Flags); return S; @@ -2937,6 +2946,7 @@ O, Ops.size()); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Ops); } S->setNoWrapFlags(Flags); return S; @@ -3446,6 +3456,7 @@ LHS, RHS); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, {LHS, RHS}); return S; } @@ -3840,6 +3851,7 @@ UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Ops); return S; } @@ -12325,6 +12337,7 @@ LoopDispositions(std::move(Arg.LoopDispositions)), LoopPropertiesCache(std::move(Arg.LoopPropertiesCache)), BlockDispositions(std::move(Arg.BlockDispositions)), + SCEVUsers(std::move(Arg.SCEVUsers)), UnsignedRanges(std::move(Arg.UnsignedRanges)), SignedRanges(std::move(Arg.SignedRanges)), UniqueSCEVs(std::move(Arg.UniqueSCEVs)), @@ -13288,6 +13301,12 @@ Loop &L) : SE(SE), L(L) {} +void ScalarEvolution::registerUser(const SCEV *User, + ArrayRef Ops) { + for (auto *Op : Ops) + SCEVUsers[Op].insert(User); +} + const SCEV *PredicatedScalarEvolution::getSCEV(Value *V) { const SCEV *Expr = SE.getSCEV(V); RewriteEntry &Entry = RewriteMap[Expr];