[llvm-commits] [polly] r163472 - in /polly/trunk/lib: Analysis/ScopDetection.cpp Support/SCEVValidator.cpp

Tobias Grosser grosser at fim.uni-passau.de
Sat Sep 8 07:00:37 PDT 2012


Author: grosser
Date: Sat Sep  8 09:00:37 2012
New Revision: 163472

URL: http://llvm.org/viewvc/llvm-project?rev=163472&view=rev
Log:
SCEVValidator: Add debug output that gives the reason for invalid expressions

Modified:
    polly/trunk/lib/Analysis/ScopDetection.cpp
    polly/trunk/lib/Support/SCEVValidator.cpp

Modified: polly/trunk/lib/Analysis/ScopDetection.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopDetection.cpp?rev=163472&r1=163471&r2=163472&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopDetection.cpp (original)
+++ polly/trunk/lib/Analysis/ScopDetection.cpp Sat Sep  8 09:00:37 2012
@@ -251,7 +251,7 @@
   AccessFunction = SE->getMinusSCEV(AccessFunction, BasePointer);
 
   if (!isAffineExpr(&Context.CurRegion, AccessFunction, *SE, BaseValue) && !AllowNonAffine)
-    INVALID(AffFunc, "Non affine access function" << *AccessFunction);
+    INVALID(AffFunc, "Non affine access function: " << *AccessFunction);
 
   // FIXME: Alias Analysis thinks IntToPtrInst aliases with alloca instructions
   // created by IndependentBlocks Pass.

Modified: polly/trunk/lib/Support/SCEVValidator.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/SCEVValidator.cpp?rev=163472&r1=163471&r2=163472&view=diff
==============================================================================
--- polly/trunk/lib/Support/SCEVValidator.cpp (original)
+++ polly/trunk/lib/Support/SCEVValidator.cpp Sat Sep  8 09:00:37 2012
@@ -1,6 +1,8 @@
 
 #include "polly/Support/SCEVValidator.h"
 
+#define DEBUG_TYPE "polly-scev-validator"
+#include "llvm/Support/Debug.h"
 #include "llvm/Analysis/ScalarEvolution.h"
 #include "llvm/Analysis/ScalarEvolutionExpressions.h"
 #include "llvm/Analysis/RegionInfo.h"
@@ -41,10 +43,6 @@
   std::vector<const SCEV*> Parameters;
 
 public:
-
-  /// @brief Create an invalid result.
-  ValidatorResult() : Type(SCEVType::INVALID) {};
-
   /// @brief The copy constructor
   ValidatorResult(const ValidatorResult &Source) {
     Type = Source.Type;
@@ -61,6 +59,11 @@
     Parameters.push_back(Expr);
   };
 
+  /// @brief Get the type of the ValidatorResult.
+  SCEVType::TYPE getType() {
+    return Type;
+  }
+
   /// @brief Is the analyzed SCEV constant during the execution of the SCoP.
   bool isConstant() {
     return Type == SCEVType::INT || Type == SCEVType::PARAM;
@@ -81,6 +84,11 @@
     return Type == SCEVType::INT;
   }
 
+  /// @brief Is the analyzed SCEV of Type PARAM.
+  bool isPARAM() {
+    return Type == SCEVType::PARAM;
+  }
+
   /// @brief Get the parameters of this validator result.
   std::vector<const SCEV*> getParameters() {
     return Parameters;
@@ -105,16 +113,16 @@
   void print(raw_ostream &OS) {
     switch (Type) {
       case SCEVType::INT:
-        OS << "SCEVType::INT\n";
+        OS << "SCEVType::INT";
       break;
       case SCEVType::PARAM:
-        OS << "SCEVType::PARAM\n";
+        OS << "SCEVType::PARAM";
       break;
       case SCEVType::IV:
-        OS << "SCEVType::IV\n";
+        OS << "SCEVType::IV";
       break;
       case SCEVType::INVALID:
-        OS << "SCEVType::INVALID\n";
+        OS << "SCEVType::INVALID";
       break;
     }
   }
@@ -145,25 +153,41 @@
   class 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, Expr);
+    switch (Op.getType()) {
+      case SCEVType::INT:
+      case SCEVType::PARAM:
+       // 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.
+        return ValidatorResult(SCEVType::PARAM, Expr);
+      case SCEVType::IV:
+        DEBUG(dbgs() << "INVALID: Truncation of SCEVType::IV expression");
+        return ValidatorResult(SCEVType::INVALID);
+      case SCEVType::INVALID:
+        return Op;
+    }
 
-    return ValidatorResult(SCEVType::INVALID);
+    llvm_unreachable("Unknown SCEVType");
   }
 
   class 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, Expr);
+    switch (Op.getType()) {
+      case SCEVType::INT:
+      case SCEVType::PARAM:
+       // 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.
+        return ValidatorResult(SCEVType::PARAM, Expr);
+      case SCEVType::IV:
+        DEBUG(dbgs() << "INVALID: ZeroExtend of SCEVType::IV expression");
+        return ValidatorResult(SCEVType::INVALID);
+      case SCEVType::INVALID:
+        return Op;
+    }
 
-    return ValidatorResult(SCEVType::INVALID);
+    llvm_unreachable("Unknown SCEVType");
   }
 
   class ValidatorResult visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
@@ -179,11 +203,11 @@
 
     for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
       ValidatorResult Op = visit(Expr->getOperand(i));
-
-      if (!Op.isValid())
-        return ValidatorResult(SCEVType::INVALID);
-
       Return.merge(Op);
+
+      // Early exit.
+      if (!Return.isValid())
+        break;
     }
 
     // TODO: Check for NSW and NUW.
@@ -199,8 +223,15 @@
       if (Op.isINT())
         continue;
 
-      if (!Op.isValid() || !Return.isINT())
+      if ((Op.isIV() || Op.isPARAM()) && !Return.isINT() ) {
+        DEBUG(dbgs() << "INVALID: More than one non-int operand in MulExpr\n"
+                     << "\tExpr: " << *Expr << "\n"
+                     << "\tPrevious expression type: " << Return << "\n"
+                     << "\tNext operand (" << Op << "): "
+                     << *Expr->getOperand(i) << "\n");
+
         return ValidatorResult(SCEVType::INVALID);
+      }
 
       Return.merge(Op);
     }
@@ -219,18 +250,24 @@
     if (LHS.isConstant() && RHS.isConstant())
       return ValidatorResult(SCEVType::PARAM, Expr);
 
+    DEBUG(dbgs() << "INVALID: unsigned division of non-constant expressions");
     return ValidatorResult(SCEVType::INVALID);
   }
 
   class ValidatorResult visitAddRecExpr(const SCEVAddRecExpr *Expr) {
-    if (!Expr->isAffine())
+    if (!Expr->isAffine()) {
+      DEBUG(dbgs() << "INVALID: AddRec is not affine");
       return ValidatorResult(SCEVType::INVALID);
+    }
 
     ValidatorResult Start = visit(Expr->getStart());
     ValidatorResult Recurrence = visit(Expr->getStepRecurrence(SE));
 
-    if (!Start.isValid() || !Recurrence.isConstant())
-      return ValidatorResult(SCEVType::INVALID);
+    if (!Start.isValid())
+      return Start;
+
+    if (!Recurrence.isValid())
+      return Recurrence;
 
     if (R->contains(Expr->getLoop())) {
       if (Recurrence.isINT()) {
@@ -239,13 +276,14 @@
         return Result;
       }
 
+      DEBUG(dbgs() << "INVALID: AddRec within scop has non-int"
+                      "recurrence part");
       return ValidatorResult(SCEVType::INVALID);
     }
 
-    if (Start.isConstant())
-      return ValidatorResult(SCEVType::PARAM, Expr);
-
-    return ValidatorResult(SCEVType::INVALID);
+    assert (Start.isConstant() && Recurrence.isConstant()
+            && "Expected 'Start' and 'Recurrence' to be constant");
+    return ValidatorResult(SCEVType::PARAM, Expr);
   }
 
   class ValidatorResult visitSMaxExpr(const SCEVSMaxExpr *Expr) {
@@ -255,7 +293,7 @@
       ValidatorResult Op = visit(Expr->getOperand(i));
 
       if (!Op.isValid())
-        return ValidatorResult(SCEVType::INVALID);
+        return Op;
 
       Return.merge(Op);
     }
@@ -269,8 +307,10 @@
     for (int i = 0, e = Expr->getNumOperands(); i < e; ++i) {
       ValidatorResult Op = visit(Expr->getOperand(i));
 
-      if (!Op.isConstant())
+      if (!Op.isConstant()) {
+        DEBUG(dbgs() << "INVALID: UMaxExpr has a non-constant operand");
         return ValidatorResult(SCEVType::INVALID);
+      }
     }
 
     return ValidatorResult(SCEVType::PARAM, Expr);
@@ -286,18 +326,27 @@
     //     A[i] = 1;
     //
     // See test/CodeGen/20120316-InvalidCast.ll
-    if (!Expr->getType()->isIntegerTy())
+    if (!Expr->getType()->isIntegerTy()) {
+      DEBUG(dbgs() << "INVALID: UnknownExpr is not an integer type");
       return ValidatorResult(SCEVType::INVALID);
+    }
 
-    if (isa<UndefValue>(V))
+    if (isa<UndefValue>(V)) {
+      DEBUG(dbgs() << "INVALID: UnknownExpr references an undef value");
       return ValidatorResult(SCEVType::INVALID);
+    }
 
     if (Instruction *I = dyn_cast<Instruction>(Expr->getValue()))
-      if (R->contains(I))
+      if (R->contains(I)) {
+        DEBUG(dbgs() << "INVALID: UnknownExpr references an instruction "
+                        "within the region\n");
         return ValidatorResult(SCEVType::INVALID);
+      }
 
-    if (BaseAddress == V)
+    if (BaseAddress == V) {
+      DEBUG(dbgs() << "INVALID: UnknownExpr references BaseAddress\n");
       return ValidatorResult(SCEVType::INVALID);
+    }
 
     return ValidatorResult(SCEVType::PARAM, Expr);
   }
@@ -310,8 +359,20 @@
       return false;
 
     SCEVValidator Validator(R, SE, BaseAddress);
+    DEBUG(
+      dbgs() << "\n";
+      dbgs() << "Expr: " << *Expr << "\n";
+      dbgs() << "Region: " << R->getNameStr() << "\n";
+      dbgs() << " -> ");
+
     ValidatorResult Result = Validator.visit(Expr);
 
+    DEBUG(
+      if (Result.isValid())
+        dbgs() << "VALID\n";
+      dbgs() << "\n";
+    );
+
     return Result.isValid();
   }
 





More information about the llvm-commits mailing list