[polly] r177313 - Correct function to decide if a SCEV can be ignored

Sebastian Pop spop at codeaurora.org
Mon Mar 18 13:21:13 PDT 2013


Author: spop
Date: Mon Mar 18 15:21:13 2013
New Revision: 177313

URL: http://llvm.org/viewvc/llvm-project?rev=177313&view=rev
Log:
Correct function to decide if a SCEV can be ignored

When doing SCEV based code generation, we ignore instructions calculating values
that are fully defined by a SCEV expression. The values that are calculated by
this instructions are recalculated on demand.

This commit improves the check to verify if certain instructions can be ignored
and recalculated on demand.

Added:
    polly/trunk/test/Isl/Ast/single_loop_strip_mine.ll
    polly/trunk/test/Isl/Ast/single_loop_strip_mine___%for.cond---%for.end.jscop
Modified:
    polly/trunk/include/polly/Support/SCEVValidator.h
    polly/trunk/lib/CodeGen/BlockGenerators.cpp
    polly/trunk/lib/Support/SCEVValidator.cpp

Modified: polly/trunk/include/polly/Support/SCEVValidator.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/Support/SCEVValidator.h?rev=177313&r1=177312&r2=177313&view=diff
==============================================================================
--- polly/trunk/include/polly/Support/SCEVValidator.h (original)
+++ polly/trunk/include/polly/Support/SCEVValidator.h Mon Mar 18 15:21:13 2013
@@ -22,6 +22,12 @@ namespace llvm {
 }
 
 namespace polly {
+  /// Returns true when the SCEV contains references to instructions within the
+  /// region.
+  ///
+  /// @param S The SCEV to analyze.
+  /// @param R The region in which we look for dependences.
+  bool hasScalarDepsInsideRegion(const llvm::SCEV *S, const llvm::Region *R);
   bool isAffineExpr(const llvm::Region *R, const llvm::SCEV *Expression,
                     llvm::ScalarEvolution &SE,
                     const llvm::Value *BaseAddress = 0);

Modified: polly/trunk/lib/CodeGen/BlockGenerators.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/BlockGenerators.cpp?rev=177313&r1=177312&r2=177313&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/BlockGenerators.cpp (original)
+++ polly/trunk/lib/CodeGen/BlockGenerators.cpp Mon Mar 18 15:21:13 2013
@@ -17,6 +17,7 @@
 #include "polly/CodeGen/CodeGeneration.h"
 #include "polly/CodeGen/BlockGenerators.h"
 #include "polly/Support/GICHelper.h"
+#include "polly/Support/SCEVValidator.h"
 
 #include "llvm/Analysis/LoopInfo.h"
 #include "llvm/Analysis/ScalarEvolution.h"
@@ -147,15 +148,10 @@ BlockGenerator::BlockGenerator(IRBuilder
 
 bool BlockGenerator::isSCEVIgnore(const Instruction *Inst) {
   if (SCEVCodegen && SE.isSCEVable(Inst->getType()))
-    if (const SCEV *Scev = SE.getSCEV(const_cast<Instruction*>(Inst)))
-      if (!isa<SCEVCouldNotCompute>(Scev)) {
-        if (const SCEVUnknown *Unknown = dyn_cast<SCEVUnknown>(Scev)) {
-          if (Unknown->getValue() != Inst)
-            return true;
-        } else {
-          return true;
-        }
-      }
+    if (const SCEV *Scev = SE.getSCEV(const_cast<Instruction *>(Inst)))
+      if (!isa<SCEVCouldNotCompute>(Scev))
+        return !hasScalarDepsInsideRegion(Scev,
+                                          &Statement.getParent()->getRegion());
 
   return false;
 }

Modified: polly/trunk/lib/Support/SCEVValidator.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Support/SCEVValidator.cpp?rev=177313&r1=177312&r2=177313&view=diff
==============================================================================
--- polly/trunk/lib/Support/SCEVValidator.cpp (original)
+++ polly/trunk/lib/Support/SCEVValidator.cpp Mon Mar 18 15:21:13 2013
@@ -1,5 +1,6 @@
 
 #include "polly/Support/SCEVValidator.h"
+#include "polly/ScopInfo.h"
 
 #define DEBUG_TYPE "polly-scev-validator"
 #include "llvm/Support/Debug.h"
@@ -336,10 +337,113 @@ public:
   }
 };
 
+/// @brief Check whether a SCEV refers to an SSA name defined inside a region.
+///
+struct SCEVInRegionDependences :
+    public SCEVVisitor<SCEVInRegionDependences, bool> {
+public:
+
+  /// Returns true when the SCEV has SSA names defined in region R.
+  static bool hasDependences(const SCEV *S, const Region *R) {
+    SCEVInRegionDependences Ignore(R);
+    return Ignore.visit(S);
+  }
+
+  SCEVInRegionDependences(const Region *R) : R(R) {}
+
+  bool visit(const SCEV *Expr) {
+    return SCEVVisitor<SCEVInRegionDependences, bool>::visit(Expr);
+  }
+
+  bool visitConstant(const SCEVConstant *Constant) { return false; }
+
+  bool visitTruncateExpr(const SCEVTruncateExpr *Expr) {
+    return visit(Expr->getOperand());
+  }
+
+  bool visitZeroExtendExpr(const SCEVZeroExtendExpr *Expr) {
+    return visit(Expr->getOperand());
+  }
+
+  bool visitSignExtendExpr(const SCEVSignExtendExpr *Expr) {
+    return visit(Expr->getOperand());
+  }
+
+  bool visitAddExpr(const SCEVAddExpr *Expr) {
+    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+      if (visit(Expr->getOperand(i)))
+        return true;
+
+    return false;
+  }
+
+  bool visitMulExpr(const SCEVMulExpr *Expr) {
+    for (int i = 0, e = Expr->getNumOperands(); i < e; ++i)
+      if (visit(Expr->getOperand(i)))
+        return true;
+
+    return false;
+  }
+
+  bool visitUDivExpr(const SCEVUDivExpr *Expr) {
+    if (visit(Expr->getLHS()))
+      return true;
+
+    if (visit(Expr->getRHS()))
+      return true;
+
+    return false;
+  }
+
+  bool visitAddRecExpr(const SCEVAddRecExpr *Expr) {
+    if (visit(Expr->getStart()))
+      return true;
+
+    for (size_t i = 0; i < Expr->getNumOperands(); ++i)
+      if (visit(Expr->getOperand(i)))
+        return true;
+
+    return false;
+  }
+
+  bool visitSMaxExpr(const SCEVSMaxExpr *Expr) {
+    for (size_t i = 0; i < Expr->getNumOperands(); ++i)
+      if (visit(Expr->getOperand(i)))
+        return true;
+
+    return false;
+  }
+
+  bool visitUMaxExpr(const SCEVUMaxExpr *Expr) {
+    for (size_t i = 0; i < Expr->getNumOperands(); ++i)
+      if (visit(Expr->getOperand(i)))
+        return true;
+
+    return false;
+  }
+
+  bool visitUnknown(const SCEVUnknown *Expr) {
+    Instruction *Inst = dyn_cast<Instruction>(Expr->getValue());
+
+    // Return true when Inst is defined inside the region R.
+    if (Inst && R->contains(Inst))
+      return true;
+
+    return false;
+  }
+
+private:
+  const Region *R;
+};
+
 namespace polly {
-bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
-                  const Value *BaseAddress) {
-  if (isa<SCEVCouldNotCompute>(Expr))
+  bool hasScalarDepsInsideRegion(const SCEV *Expr, const Region *R) {
+    return SCEVInRegionDependences::hasDependences(Expr, R);
+  }
+
+  bool isAffineExpr(const Region *R, const SCEV *Expr, ScalarEvolution &SE,
+                    const Value *BaseAddress) {
+    if (isa<SCEVCouldNotCompute>(Expr))
     return false;
 
   SCEVValidator Validator(R, SE, BaseAddress);

Added: polly/trunk/test/Isl/Ast/single_loop_strip_mine.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/Ast/single_loop_strip_mine.ll?rev=177313&view=auto
==============================================================================
--- polly/trunk/test/Isl/Ast/single_loop_strip_mine.ll (added)
+++ polly/trunk/test/Isl/Ast/single_loop_strip_mine.ll Mon Mar 18 15:21:13 2013
@@ -0,0 +1,41 @@
+; RUN: opt %loadPolly -basicaa -polly-ast -analyze < %s | FileCheck %s
+; RUN: opt %loadPolly -polly-import-jscop-dir=%S -basicaa -polly-import-jscop -polly-ast -polly-ast-detect-parallel -analyze < %s | FileCheck %s -check-prefix=CHECK-VECTOR
+
+; for (i = 0; i < 1024; i++)
+;   A[i] = B[i];
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @single_loop_strip_mine(i16* noalias %A, i16* noalias %B) {
+entry:
+  br label %for.cond
+
+for.cond:                                         ; preds = %for.body, %entry
+  %indvar = phi i64 [ 0, %entry ], [ %inc, %for.body ]
+  %cmp = icmp slt i64 %indvar, 1024
+  br i1 %cmp, label %for.body, label %for.end
+
+for.body:                                         ; preds = %for.cond
+  %arrayidx = getelementptr inbounds i16* %B, i64 0
+  %load = load i16* %arrayidx
+  %add10 = add nsw i16 %load, 1
+  %arrayidx13 = getelementptr inbounds i16* %A, i64 %indvar
+  store i16 %add10, i16* %arrayidx13, align 2
+  %inc = add nsw i64 %indvar, 1
+  br label %for.cond
+
+for.end:                                          ; preds = %for.cond
+  ret void
+}
+
+; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1)
+; CHECK:     Stmt_for_body(c1);
+
+; CHECK-VECTOR: #pragma omp parallel for
+; CHECK-VECTOR: for (int c0 = 0; c0 <= 1023; c0 += 4)
+; CHECK-VECTOR:     #pragma simd
+; CHECK-VECTOR:     for (int c1 = c0; c1 <= c0 + 3; c1 += 1)
+; CHECK-VECTOR:           Stmt_for_body(c1);
+
+

Added: polly/trunk/test/Isl/Ast/single_loop_strip_mine___%for.cond---%for.end.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/Ast/single_loop_strip_mine___%25for.cond---%25for.end.jscop?rev=177313&view=auto
==============================================================================
--- polly/trunk/test/Isl/Ast/single_loop_strip_mine___%for.cond---%for.end.jscop (added)
+++ polly/trunk/test/Isl/Ast/single_loop_strip_mine___%for.cond---%for.end.jscop Mon Mar 18 15:21:13 2013
@@ -0,0 +1,21 @@
+{
+   "context" : "{  :  }",
+   "name" : "for.cond => for.end",
+   "statements" : [
+      {
+         "accesses" : [
+            {
+               "kind" : "read",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_B[0] }"
+            },
+            {
+               "kind" : "write",
+               "relation" : "{ Stmt_for_body[i0] -> MemRef_A[i0] }"
+            }
+         ],
+         "domain" : "{ Stmt_for_body[i0] : i0 >= 0 and i0 <= 1023 }",
+         "name" : "Stmt_for_body",
+         "schedule" : "{ Stmt_for_body[i0] -> [o0, i0] : exists (e0 = [(o0)/4]: 4e0 = o0 and o0 <= i0 and o0 >= -3 + i0 and i0 >= 0 and i0 <= 1023) }"
+      }
+   ]
+}





More information about the llvm-commits mailing list