[llvm-commits] [polly] r143960 - in /polly/trunk: include/polly/Support/SCEVValidator.h lib/Analysis/ScopDetection.cpp lib/Support/CMakeLists.txt lib/Support/SCEVValidator.cpp

Tobias Grosser grosser at fim.uni-passau.de
Mon Nov 7 04:58:54 PST 2011


Author: grosser
Date: Mon Nov  7 06:58:54 2011
New Revision: 143960

URL: http://llvm.org/viewvc/llvm-project?rev=143960&view=rev
Log:
SCEVValidator: Move into own file

Added:
    polly/trunk/include/polly/Support/SCEVValidator.h   (with props)
    polly/trunk/lib/Support/SCEVValidator.cpp
Modified:
    polly/trunk/lib/Analysis/ScopDetection.cpp
    polly/trunk/lib/Support/CMakeLists.txt

Added: polly/trunk/include/polly/Support/SCEVValidator.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/SCEVValidator.h?rev=143960&view=auto
==============================================================================
--- polly/trunk/include/polly/Support/SCEVValidator.h (added)
+++ polly/trunk/include/polly/Support/SCEVValidator.h Mon Nov  7 06:58:54 2011
@@ -0,0 +1,27 @@
+//===--- SCEVValidator.h - Detect Scops -------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Checks if a SCEV expression represents a valid affine expression.
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_SCEV_VALIDATOR_H
+#define POLLY_SCEV_VALIDATOR_H
+
+namespace llvm {
+  class Region;
+  class SCEV;
+  class ScalarEvolution;
+  class Value;
+}
+
+namespace polly {
+  bool isAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
+                    llvm::ScalarEvolution &SE, llvm::Value **BaseAddress = 0);
+}
+
+#endif

Propchange: polly/trunk/include/polly/Support/SCEVValidator.h
------------------------------------------------------------------------------
    svn:executable = *

Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=143960&r1=143959&r2=143960&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Mon Nov  7 06:58:54 2011
@@ -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());
 

Modified: polly/trunk/lib/Support/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/CMakeLists.txt?rev=143960&r1=143959&r2=143960&view=diff
==============================================================================
--- polly/trunk/lib/Support/CMakeLists.txt (original)
+++ polly/trunk/lib/Support/CMakeLists.txt Mon Nov  7 06:58:54 2011
@@ -1,5 +1,6 @@
 add_polly_library(PollySupport
   AffSCEVItTester.cpp
   GICHelper.cpp
+  SCEVValidator.cpp
   ScopHelper.cpp
   )

Added: polly/trunk/lib/Support/SCEVValidator.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/SCEVValidator.cpp?rev=143960&view=auto
==============================================================================
--- polly/trunk/lib/Support/SCEVValidator.cpp (added)
+++ polly/trunk/lib/Support/SCEVValidator.cpp Mon Nov  7 06:58:54 2011
@@ -0,0 +1,231 @@
+
+#include "polly/Support/SCEVValidator.h"
+
+#include "llvm/Analysis/ScalarEvolution.h"
+#include "llvm/Analysis/ScalarEvolutionExpressions.h"
+#include "llvm/Analysis/RegionInfo.h"
+
+using namespace llvm;
+
+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:
+  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);
+  }
+};
+
+namespace polly {
+  bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
+                    Value **BaseAddress) {
+    if (isa<SCEVCouldNotCompute>(Expr))
+      return false;
+
+    if (BaseAddress)
+      *BaseAddress = NULL;
+
+    SCEVValidator Validator(R, SE, BaseAddress);
+    ValidatorResult Result = Validator.visit(Expr);
+
+    return Result.isValid();
+  }
+}
+
+





More information about the llvm-commits mailing list