Factor SCEV traversal code so I can use it elsewhere. No functionality.
authorAndrew Trick <atrick@apple.com>
Fri, 13 Jul 2012 23:33:03 +0000 (23:33 +0000)
committerAndrew Trick <atrick@apple.com>
Fri, 13 Jul 2012 23:33:03 +0000 (23:33 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@160203 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Analysis/ScalarEvolutionExpressions.h
lib/Analysis/ScalarEvolution.cpp

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