Index: llvm/include/llvm/Analysis/ScalarEvolution.h =================================================================== --- llvm/include/llvm/Analysis/ScalarEvolution.h +++ 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); @@ -1502,6 +1505,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; Index: llvm/lib/Analysis/ScalarEvolution.cpp =================================================================== --- llvm/lib/Analysis/ScalarEvolution.cpp +++ llvm/lib/Analysis/ScalarEvolution.cpp @@ -1101,6 +1101,7 @@ SCEVPtrToIntExpr(ID.Intern(SCEVAllocator), Op, IntPtrTy); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -1221,6 +1222,7 @@ new (SCEVAllocator) SCEVTruncateExpr(ID.Intern(SCEVAllocator), Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -1275,6 +1277,7 @@ Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -1604,6 +1607,7 @@ Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -1873,6 +1877,7 @@ Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -1912,6 +1917,7 @@ Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Op); return S; } @@ -2109,6 +2115,7 @@ Op, Ty); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, { Op }); return S; } @@ -2894,6 +2901,7 @@ SCEVAddExpr(ID.Intern(SCEVAllocator), O, Ops.size()); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Ops); } S->setNoWrapFlags(Flags); return S; @@ -2917,6 +2925,7 @@ SCEVAddRecExpr(ID.Intern(SCEVAllocator), O, Ops.size(), L); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Ops); } setNoWrapFlags(S, Flags); return S; @@ -2939,6 +2948,7 @@ O, Ops.size()); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Ops); } S->setNoWrapFlags(Flags); return S; @@ -3448,6 +3458,7 @@ LHS, RHS); UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, {LHS, RHS}); return S; } @@ -3842,6 +3853,7 @@ UniqueSCEVs.InsertNode(S, IP); addToLoopUseLists(S); + registerUser(S, Ops); return S; } @@ -12415,6 +12427,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)), @@ -13378,6 +13391,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];