diff options
| author | Dan Gohman <gohman@apple.com> | 2012-05-10 17:21:30 +0000 |
|---|---|---|
| committer | Dan Gohman <gohman@apple.com> | 2012-05-10 17:21:30 +0000 |
| commit | 0291246ce7eb37b085821dc0a722ea30b1ccf1bd (patch) | |
| tree | 59bbd389e43126c1a4427a74bfbcc920d6dc561a /llvm/lib/Analysis | |
| parent | 300d629924b25301decd0d851f07d277a842e929 (diff) | |
| download | bcm5719-llvm-0291246ce7eb37b085821dc0a722ea30b1ccf1bd.tar.gz bcm5719-llvm-0291246ce7eb37b085821dc0a722ea30b1ccf1bd.zip | |
Rewrite ScalarEvolution::hasOperand to use an explicit worklist instead
of recursion, to avoid excessive stack usage on deep expressions.
llvm-svn: 156554
Diffstat (limited to 'llvm/lib/Analysis')
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 85 |
1 files changed, 50 insertions, 35 deletions
diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 205227ca0b7..685092710df 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/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) { |

