1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 19:52:54 +01:00

Factor SCEV traversal code so I can use it elsewhere. No functionality.

llvm-svn: 160203
This commit is contained in:
Andrew Trick 2012-07-13 23:33:03 +00:00
parent 12ea066486
commit 7efd13174a
2 changed files with 87 additions and 52 deletions

View File

@ -493,6 +493,73 @@ namespace llvm {
llvm_unreachable("Invalid use of SCEVCouldNotCompute!");
}
};
/// Visit all nodes in the expression tree using worklist traversal.
///
/// Visitor implements:
/// // return true to follow this node.
/// bool follow(const SCEV *S);
/// // return true to terminate the search.
/// bool isDone();
template<typename SV>
class SCEVTraversal {
SV &Visitor;
SmallVector<const SCEV *, 8> Worklist;
void push(const SCEV *S) {
if (Visitor.follow(S))
Worklist.push_back(S);
}
public:
SCEVTraversal(SV& V): Visitor(V) {}
void visitAll(const SCEV *Root) {
push(Root);
while (!Worklist.empty() && !Visitor.isDone()) {
const SCEV *S = Worklist.pop_back_val();
switch (S->getSCEVType()) {
case scConstant:
case scUnknown:
break;
case scTruncate:
case scZeroExtend:
case scSignExtend:
push(cast<SCEVCastExpr>(S)->getOperand());
break;
case scAddExpr:
case scMulExpr:
case scSMaxExpr:
case scUMaxExpr:
case scAddRecExpr: {
const SCEVNAryExpr *NAry = cast<SCEVNAryExpr>(S);
for (SCEVNAryExpr::op_iterator I = NAry->op_begin(),
E = NAry->op_end(); I != E; ++I) {
push(*I);
}
break;
}
case scUDivExpr: {
const SCEVUDivExpr *UDiv = cast<SCEVUDivExpr>(S);
push(UDiv->getLHS());
push(UDiv->getRHS());
break;
}
case scCouldNotCompute:
llvm_unreachable("Attempt to use a SCEVCouldNotCompute object!");
default:
llvm_unreachable("Unknown SCEV kind!");
}
}
}
};
/// Use SCEVTraversal to visit all nodes in the givien expression tree.
template<typename SV>
void visitAll(const SCEV *Root, SV& Visitor) {
SCEVTraversal<SV> T(Visitor);
T.visitAll(Root);
}
}
#endif

View File

@ -6894,59 +6894,27 @@ bool ScalarEvolution::properlyDominates(const SCEV *S, const BasicBlock *BB) {
return getBlockDisposition(S, BB) == ProperlyDominatesBlock;
}
namespace {
// Search for a SCEV expression node within an expression tree.
// Implements SCEVTraversal::Visitor.
struct SCEVSearch {
const SCEV *Node;
bool IsFound;
SCEVSearch(const SCEV *N): Node(N), IsFound(false) {}
bool follow(const SCEV *S) {
IsFound |= (S == Node);
return !IsFound;
}
bool isDone() const { return IsFound; }
};
}
bool ScalarEvolution::hasOperand(const SCEV *S, const SCEV *Op) const {
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;
}
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;
SCEVSearch Search(Op);
visitAll(S, Search);
return Search.IsFound;
}
void ScalarEvolution::forgetMemoizedResults(const SCEV *S) {