diff options
| -rw-r--r-- | llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h | 67 | ||||
| -rw-r--r-- | llvm/lib/Analysis/ScalarEvolution.cpp | 70 | 
2 files changed, 86 insertions, 51 deletions
diff --git a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h index 47b37102918..cf15f73a751 100644 --- a/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h +++ b/llvm/include/llvm/Analysis/ScalarEvolutionExpressions.h @@ -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 diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index 884ceec7a00..f0f3b1cb66e 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -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) {  | 

