summaryrefslogtreecommitdiff
path: root/lib/Analysis/ScalarEvolution.cpp
diff options
context:
space:
mode:
authorDan Gohman <gohman@apple.com>2012-05-10 17:21:30 +0000
committerDan Gohman <gohman@apple.com>2012-05-10 17:21:30 +0000
commitac84461e5ab64bf534a8cf11fa833b5f3569c101 (patch)
tree6f25d1539a5d8a3e4fceb63e0e87e1afc1732b99 /lib/Analysis/ScalarEvolution.cpp
parente54874471cf565bbacdca69c95ae7287badc578f (diff)
downloadllvm-ac84461e5ab64bf534a8cf11fa833b5f3569c101.tar.gz
llvm-ac84461e5ab64bf534a8cf11fa833b5f3569c101.tar.bz2
llvm-ac84461e5ab64bf534a8cf11fa833b5f3569c101.tar.xz
Rewrite ScalarEvolution::hasOperand to use an explicit worklist instead
of recursion, to avoid excessive stack usage on deep expressions. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156554 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/ScalarEvolution.cpp')
-rw-r--r--lib/Analysis/ScalarEvolution.cpp85
1 files changed, 50 insertions, 35 deletions
diff --git a/lib/Analysis/ScalarEvolution.cpp b/lib/Analysis/ScalarEvolution.cpp
index 205227ca0b..685092710d 100644
--- a/lib/Analysis/ScalarEvolution.cpp
+++ b/lib/Analysis/ScalarEvolution.cpp
@@ -6860,43 +6860,58 @@ bool ScalarEvolution::properlyDominates(const SCEV *S, const BasicBlock *BB) {
}
bool ScalarEvolution::hasOperand(const SCEV *S, const SCEV *Op) const {
- switch (S->getSCEVType()) {
- case scConstant:
- return false;
- case scTruncate:
- case scZeroExtend:
- case scSignExtend: {
- const SCEVCastExpr *Cast = cast<SCEVCastExpr>(S);
- const SCEV *CastOp = Cast->getOperand();
- return Op == CastOp || hasOperand(CastOp, Op);
- }
- case scAddRecExpr:
- case scAddExpr:
- case scMulExpr:
- case scUMaxExpr:
- case scSMaxExpr: {
- const SCEVNAryExpr *NAry = cast<SCEVNAryExpr>(S);
- for (SCEVNAryExpr::op_iterator I = NAry->op_begin(), E = NAry->op_end();
- I != E; ++I) {
- const SCEV *NAryOp = *I;
- if (NAryOp == Op || hasOperand(NAryOp, Op))
+ SmallVector<const SCEV *, 8> Worklist;
+ Worklist.push_back(S);
+ do {
+ S = Worklist.pop_back_val();
+
+ switch (S->getSCEVType()) {
+ case scConstant:
+ break;
+ case scTruncate:
+ case scZeroExtend:
+ case scSignExtend: {
+ const SCEVCastExpr *Cast = cast<SCEVCastExpr>(S);
+ const SCEV *CastOp = Cast->getOperand();
+ if (Op == CastOp)
return true;
+ Worklist.push_back(CastOp);
+ break;
}
- return false;
- }
- case scUDivExpr: {
- const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(S);
- const SCEV *LHS = UDiv->getLHS(), *RHS = UDiv->getRHS();
- return LHS == Op || hasOperand(LHS, Op) ||
- RHS == Op || hasOperand(RHS, Op);
- }
- case scUnknown:
- return false;
- case scCouldNotCompute:
- llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
- default:
- llvm_unreachable("Unknown SCEV kind!");
- }
+ case scAddRecExpr:
+ case scAddExpr:
+ case scMulExpr:
+ case scUMaxExpr:
+ case scSMaxExpr: {
+ const SCEVNAryExpr *NAry = cast<SCEVNAryExpr>(S);
+ for (SCEVNAryExpr::op_iterator I = NAry->op_begin(), E = NAry->op_end();
+ I != E; ++I) {
+ const SCEV *NAryOp = *I;
+ if (NAryOp == Op)
+ return true;
+ Worklist.push_back(NAryOp);
+ }
+ break;
+ }
+ case scUDivExpr: {
+ const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(S);
+ const SCEV *LHS = UDiv->getLHS(), *RHS = UDiv->getRHS();
+ if (LHS == Op || RHS == Op)
+ return true;
+ Worklist.push_back(LHS);
+ Worklist.push_back(RHS);
+ break;
+ }
+ case scUnknown:
+ break;
+ case scCouldNotCompute:
+ llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
+ default:
+ llvm_unreachable("Unknown SCEV kind!");
+ }
+ } while (!Worklist.empty());
+
+ return false;
}
void ScalarEvolution::forgetMemoizedResults(const SCEV *S) {