mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-24 11:42:57 +01:00
Factor SCEV traversal code so I can use it elsewhere. No functionality.
llvm-svn: 160203
This commit is contained in:
parent
12ea066486
commit
7efd13174a
@ -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
|
||||
|
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user