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];