SCEVValidator: Move into own file

llvm-svn: 143960
diff --git a/polly/lib/Analysis/ScopDetection.cpp b/polly/lib/Analysis/ScopDetection.cpp
index 883fe2c..efc7dfa 100644
--- a/polly/lib/Analysis/ScopDetection.cpp
+++ b/polly/lib/Analysis/ScopDetection.cpp
@@ -48,6 +48,7 @@
 
 #include "polly/LinkAllPasses.h"
 #include "polly/Support/ScopHelper.h"
+#include "polly/Support/SCEVValidator.h"
 #include "polly/Support/AffineSCEVIterator.h"
 
 #include "llvm/LLVMContext.h"
@@ -108,227 +109,6 @@
 
 //===----------------------------------------------------------------------===//
 // ScopDetection.
-
-namespace SCEVType {
-  enum TYPE {INT, PARAM, IV, INVALID};
-}
-
-struct ValidatorResult {
-  SCEVType::TYPE type;
-
-  ValidatorResult() : type(SCEVType::INVALID) {};
-
-  ValidatorResult(const ValidatorResult &vres) {
-    type = vres.type;
-  };
-
-  ValidatorResult(SCEVType::TYPE type) : type(type) {};
-
-  bool isConstant() {
-    return type == SCEVType::INT || type == SCEVType::PARAM;
-  }
-
-  bool isValid() {
-    return type != SCEVType::INVALID;
-  }
-
-  bool isIV() {
-    return type == SCEVType::IV;
-  }
-
-  bool isINT() {
-    return type == SCEVType::INT;
-  }
-};
-
-/// Check if a SCEV is valid in a SCoP.
-struct SCEVValidator
-  : public SCEVVisitor<SCEVValidator, struct ValidatorResult> {
-private:
-  const Region *R;
-  ScalarEvolution &SE;
-  Value **BaseAddress;
-
-public:
-  static bool isValid(const Region *R, const SCEV *Scev,
-                      ScalarEvolution &SE,
-                      Value **BaseAddress = NULL) {
-    if (isa<SCEVCouldNotCompute>(Scev))
-      return false;
-
-    if (BaseAddress)
-      *BaseAddress = NULL;
-
-    SCEVValidator Validator(R, SE, BaseAddress);
-    ValidatorResult Result = Validator.visit(Scev);
-
-    return Result.isValid();
-  }
-
-  SCEVValidator(const Region *R, ScalarEvolution &SE,
-                Value **BaseAddress) : R(R), SE(SE),
-    BaseAddress(BaseAddress) {};
-
-  struct ValidatorResult visitConstant(const SCEVConstant *Constant) {
-    return ValidatorResult(SCEVType::INT);
-  }
-
-  struct ValidatorResult visitTruncateExpr(const SCEVTruncateExpr* Expr) {
-    ValidatorResult Op = visit(Expr->getOperand());
-
-    // We currently do not represent a truncate expression as an affine
-    // expression. If it is constant during Scop execution, we treat it as a
-    // parameter, otherwise we bail out.
-    if (Op.isConstant())
-      return ValidatorResult(SCEVType::PARAM);
-
-    return ValidatorResult (SCEVType::INVALID);
-  }
-
-  struct ValidatorResult visitZeroExtendExpr(const SCEVZeroExtendExpr * Expr) {
-    ValidatorResult Op = visit(Expr->getOperand());
-
-    // We currently do not represent a zero extend expression as an affine
-    // expression. If it is constant during Scop execution, we treat it as a
-    // parameter, otherwise we bail out.
-    if (Op.isConstant())
-      return ValidatorResult (SCEVType::PARAM);
-
-    return ValidatorResult(SCEVType::INVALID);
-  }
-
-  struct ValidatorResult visitSignExtendExpr(const SCEVSignExtendExpr* Expr) {
-    // We currently allow only signed SCEV expressions. In the case of a
-    // signed value, a sign extend is a noop.
-    //
-    // TODO: Reconsider this when we add support for unsigned values.
-    return visit(Expr->getOperand());
-  }
-
-  struct ValidatorResult visitAddExpr(const SCEVAddExpr* Expr) {
-    ValidatorResult Return(SCEVType::INT);
-
-    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
-      ValidatorResult Op = visit(Expr->getOperand(i));
-
-      if (!Op.isValid())
-        return ValidatorResult(SCEVType::INVALID);
-
-      Return.type = std::max(Return.type, Op.type);
-    }
-
-    // TODO: Check for NSW and NUW.
-    return Return;
-  }
-
-  struct ValidatorResult visitMulExpr(const SCEVMulExpr* Expr) {
-    ValidatorResult Return(SCEVType::INT);
-
-    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
-      ValidatorResult Op = visit(Expr->getOperand(i));
-
-      if (Op.type == SCEVType::INT)
-        continue;
-
-      if (Op.type == SCEVType::INVALID || Return.type != SCEVType::INT)
-        return ValidatorResult(SCEVType::INVALID);
-
-      Return.type = Op.type;
-    }
-
-    // TODO: Check for NSW and NUW.
-    return Return;
-  }
-
-  struct ValidatorResult visitUDivExpr(const SCEVUDivExpr* Expr) {
-    ValidatorResult LHS = visit(Expr->getLHS());
-    ValidatorResult RHS = visit(Expr->getRHS());
-
-    // We currently do not represent a unsigned devision as an affine
-    // expression. If the division is constant during Scop execution we treat it
-    // as a parameter, otherwise we bail out.
-    if (LHS.isConstant() && RHS.isConstant())
-      return ValidatorResult(SCEVType::PARAM);
-
-    return ValidatorResult(SCEVType::INVALID);
-  }
-
-  struct ValidatorResult visitAddRecExpr(const SCEVAddRecExpr* Expr) {
-    if (!Expr->isAffine())
-      return ValidatorResult(SCEVType::INVALID);
-
-    ValidatorResult Start = visit(Expr->getStart());
-    ValidatorResult Recurrence = visit(Expr->getStepRecurrence(SE));
-
-    if (!Start.isValid() || !Recurrence.isValid() || Recurrence.isIV())
-      return ValidatorResult(SCEVType::INVALID);
-
-
-    if (!R->contains(Expr->getLoop())) {
-      if (Start.isIV())
-        return ValidatorResult(SCEVType::INVALID);
-      else
-        return ValidatorResult(SCEVType::PARAM);
-    }
-
-    if (!Recurrence.isINT())
-      return ValidatorResult(SCEVType::INVALID);
-
-    return ValidatorResult(SCEVType::IV);
-  }
-
-  struct ValidatorResult visitSMaxExpr(const SCEVSMaxExpr* Expr) {
-    ValidatorResult Return(SCEVType::INT);
-
-    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
-      ValidatorResult Op = visit(Expr->getOperand(i));
-
-      if (!Op.isValid())
-        return ValidatorResult(SCEVType::INVALID);
-
-      Return.type = std::max(Return.type, Op.type);
-    }
-
-    return Return;
-  }
-
-  struct ValidatorResult visitUMaxExpr(const SCEVUMaxExpr* Expr) {
-    // We do not support unsigned operations. If 'Expr' is constant during Scop
-    // execution we treat this as a parameter, otherwise we bail out.
-    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
-      ValidatorResult Op = visit(Expr->getOperand(i));
-
-      if (!Op.isConstant())
-        return ValidatorResult(SCEVType::INVALID);
-    }
-
-    return ValidatorResult(SCEVType::PARAM);
-  }
-
-  ValidatorResult visitUnknown(const SCEVUnknown* Expr) {
-    Value *V = Expr->getValue();
-
-    if (isa<UndefValue>(V))
-      return ValidatorResult(SCEVType::INVALID);
-
-    if (BaseAddress) {
-      if (*BaseAddress)
-        return ValidatorResult(SCEVType::INVALID);
-      else
-        *BaseAddress = V;
-    }
-
-    if (Instruction *I = dyn_cast<Instruction>(Expr->getValue()))
-      if (R->contains(I))
-        return ValidatorResult(SCEVType::INVALID);
-
-    if (BaseAddress)
-      return ValidatorResult(SCEVType::PARAM);
-    else
-      return ValidatorResult(SCEVType::PARAM);
-  }
-};
-
 bool ScopDetection::isMaxRegionInScop(const Region &R) const {
   // The Region is valid only if it could be found in the set.
   return ValidRegions.count(&R);
@@ -457,8 +237,8 @@
     const SCEV *ScevLHS = SE->getSCEV(ICmp->getOperand(0));
     const SCEV *ScevRHS = SE->getSCEV(ICmp->getOperand(1));
 
-    bool affineLHS = SCEVValidator::isValid(&Context.CurRegion, ScevLHS, *SE);
-    bool affineRHS = SCEVValidator::isValid(&Context.CurRegion, ScevRHS, *SE);
+    bool affineLHS = isAffineExpr(&Context.CurRegion, ScevLHS, *SE);
+    bool affineRHS = isAffineExpr(&Context.CurRegion, ScevRHS, *SE);
 
     if (!affineLHS || !affineRHS)
       INVALID(AffFunc, "Non affine branch in BB: " + BB.getNameStr());
@@ -499,8 +279,7 @@
   Value *Ptr = getPointerOperand(Inst), *BasePtr;
   const SCEV *AccessFunction = SE->getSCEV(Ptr);
 
-  if (!SCEVValidator::isValid(&Context.CurRegion, AccessFunction, *SE,
-                                 &BasePtr))
+  if (!isAffineExpr(&Context.CurRegion, AccessFunction, *SE, &BasePtr))
     INVALID(AffFunc, "Bad memory address " << *AccessFunction);
 
   // FIXME: Also check with isValidAffineFunction, as for the moment it is
@@ -628,7 +407,7 @@
 
   // Is the loop count affine?
   const SCEV *LoopCount = SE->getBackedgeTakenCount(L);
-  if (!SCEVValidator::isValid(&Context.CurRegion, LoopCount, *SE))
+  if (!isAffineExpr(&Context.CurRegion, LoopCount, *SE))
     INVALID(LoopBound, "Non affine loop bound '" << *LoopCount << "' in loop: "
                        << L->getHeader()->getNameStr());