summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorSanjoy Das <sanjoy@playingwithpointers.com>2019-03-29 22:00:12 +0000
committerSanjoy Das <sanjoy@playingwithpointers.com>2019-03-29 22:00:12 +0000
commit32fd32bc6f6de46b96c9e09575694d34f248d6ee (patch)
tree46f38e99b2c21cb556edfef2b6d0a57121a0ce89 /llvm/lib/Analysis/ScalarEvolution.cpp
parentf085cc5aa7c10e39fbaea277e9702132a0152396 (diff)
downloadbcm5719-llvm-32fd32bc6f6de46b96c9e09575694d34f248d6ee.tar.gz
bcm5719-llvm-32fd32bc6f6de46b96c9e09575694d34f248d6ee.zip
[SCEV] Check the cache in get{S|U}MaxExpr before doing any work
Summary: This lets us avoid e.g. checking if A >=s B in getSMaxExpr(A, B) if we've already established that (A smax B) is the best we can do. Fixes PR41225. Reviewers: asbirlea Subscribers: mcrosier, jlebar, bixia, jdoerfert, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D60010 llvm-svn: 357320
Diffstat (limited to 'llvm/lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--llvm/lib/Analysis/ScalarEvolution.cpp45
1 files changed, 33 insertions, 12 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 920e0dd2782..fd759bd80fc 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -3523,6 +3523,17 @@ const SCEV *ScalarEvolution::getSMaxExpr(const SCEV *LHS,
return getSMaxExpr(Ops);
}
+std::tuple<const SCEV *, FoldingSetNodeID, void *>
+ScalarEvolution::findExistingSCEVInCache(int SCEVType,
+ ArrayRef<const SCEV *> Ops) {
+ FoldingSetNodeID ID;
+ void *IP = nullptr;
+ ID.AddInteger(SCEVType);
+ for (unsigned i = 0, e = Ops.size(); i != e; ++i)
+ ID.AddPointer(Ops[i]);
+ return {UniqueSCEVs.FindNodeOrInsertPos(ID, IP), std::move(ID), IP};
+}
+
const SCEV *
ScalarEvolution::getSMaxExpr(SmallVectorImpl<const SCEV *> &Ops) {
assert(!Ops.empty() && "Cannot get empty smax!");
@@ -3537,6 +3548,11 @@ ScalarEvolution::getSMaxExpr(SmallVectorImpl<const SCEV *> &Ops) {
// Sort by complexity, this groups all similar expression types together.
GroupByComplexity(Ops, &LI, DT);
+ // Check if we have created the same SMax expression before.
+ if (const SCEV *S = std::get<0>(findExistingSCEVInCache(scSMaxExpr, Ops))) {
+ return S;
+ }
+
// If there are any constants, fold them together.
unsigned Idx = 0;
if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
@@ -3604,16 +3620,16 @@ ScalarEvolution::getSMaxExpr(SmallVectorImpl<const SCEV *> &Ops) {
// Okay, it looks like we really DO need an smax expr. Check to see if we
// already have one, otherwise create a new one.
+ const SCEV *ExistingSCEV;
FoldingSetNodeID ID;
- ID.AddInteger(scSMaxExpr);
- for (unsigned i = 0, e = Ops.size(); i != e; ++i)
- ID.AddPointer(Ops[i]);
- void *IP = nullptr;
- if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
+ void *IP;
+ std::tie(ExistingSCEV, ID, IP) = findExistingSCEVInCache(scSMaxExpr, Ops);
+ if (ExistingSCEV)
+ return ExistingSCEV;
const SCEV **O = SCEVAllocator.Allocate<const SCEV *>(Ops.size());
std::uninitialized_copy(Ops.begin(), Ops.end(), O);
- SCEV *S = new (SCEVAllocator) SCEVSMaxExpr(ID.Intern(SCEVAllocator),
- O, Ops.size());
+ SCEV *S =
+ new (SCEVAllocator) SCEVSMaxExpr(ID.Intern(SCEVAllocator), O, Ops.size());
UniqueSCEVs.InsertNode(S, IP);
addToLoopUseLists(S);
return S;
@@ -3639,6 +3655,11 @@ ScalarEvolution::getUMaxExpr(SmallVectorImpl<const SCEV *> &Ops) {
// Sort by complexity, this groups all similar expression types together.
GroupByComplexity(Ops, &LI, DT);
+ // Check if we have created the same UMax expression before.
+ if (const SCEV *S = std::get<0>(findExistingSCEVInCache(scUMaxExpr, Ops))) {
+ return S;
+ }
+
// If there are any constants, fold them together.
unsigned Idx = 0;
if (const SCEVConstant *LHSC = dyn_cast<SCEVConstant>(Ops[0])) {
@@ -3707,12 +3728,12 @@ ScalarEvolution::getUMaxExpr(SmallVectorImpl<const SCEV *> &Ops) {
// Okay, it looks like we really DO need a umax expr. Check to see if we
// already have one, otherwise create a new one.
+ const SCEV *ExistingSCEV;
FoldingSetNodeID ID;
- ID.AddInteger(scUMaxExpr);
- for (unsigned i = 0, e = Ops.size(); i != e; ++i)
- ID.AddPointer(Ops[i]);
- void *IP = nullptr;
- if (const SCEV *S = UniqueSCEVs.FindNodeOrInsertPos(ID, IP)) return S;
+ void *IP;
+ std::tie(ExistingSCEV, ID, IP) = findExistingSCEVInCache(scUMaxExpr, Ops);
+ if (ExistingSCEV)
+ return ExistingSCEV;
const SCEV **O = SCEVAllocator.Allocate<const SCEV *>(Ops.size());
std::uninitialized_copy(Ops.begin(), Ops.end(), O);
SCEV *S = new (SCEVAllocator) SCEVUMaxExpr(ID.Intern(SCEVAllocator),
OpenPOWER on IntegriCloud