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