diff options
author | Chris Lattner <sabre@nondot.org> | 2008-01-16 05:49:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-01-16 05:49:24 +0000 |
commit | 572dee71af1313e6742e1dfd5274fff326b9ef1c (patch) | |
tree | 12c20642044bdae9b10cc2d0a5acc6b713c4e422 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | 8c231e5dda26b790ff388fe2f70eeeda621c9261 (diff) |
Factor the ReachesChainWithoutSideEffects out of dag combiner into
a public SDOperand::reachesChainWithoutSideEffects method. No
functionality change.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46050 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 381e9dec64..67da854aa4 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3562,6 +3562,37 @@ bool SDNode::isOperand(SDNode *N) const { return false; } +/// reachesChainWithoutSideEffects - Return true if this operand (which must +/// be a chain) reaches the specified operand without crossing any +/// side-effecting instructions. In practice, this looks through token +/// factors and non-volatile loads. In order to remain efficient, this only +/// looks a couple of nodes in, it does not do an exhaustive search. +bool SDOperand::reachesChainWithoutSideEffects(SDOperand Dest, + unsigned Depth) const { + if (*this == Dest) return true; + + // Don't search too deeply, we just want to be able to see through + // TokenFactor's etc. + if (Depth == 0) return false; + + // If this is a token factor, all inputs to the TF happen in parallel. If any + // of the operands of the TF reach dest, then we can do the xform. + if (getOpcode() == ISD::TokenFactor) { + for (unsigned i = 0, e = getNumOperands(); i != e; ++i) + if (getOperand(i).reachesChainWithoutSideEffects(Dest, Depth-1)) + return true; + return false; + } + + // Loads don't have side effects, look through them. + if (LoadSDNode *Ld = dyn_cast<LoadSDNode>(*this)) { + if (!Ld->isVolatile()) + return Ld->getChain().reachesChainWithoutSideEffects(Dest, Depth-1); + } + return false; +} + + static void findPredecessor(SDNode *N, const SDNode *P, bool &found, SmallPtrSet<SDNode *, 32> &Visited) { if (found || !Visited.insert(N)) |