[polly] r228847 - Model scalar writes with uses outside the SCoP

Johannes Doerfert doerfert at cs.uni-saarland.de
Wed Feb 11 09:02:53 PST 2015


Author: jdoerfert
Date: Wed Feb 11 11:02:52 2015
New Revision: 228847

URL: http://llvm.org/viewvc/llvm-project?rev=228847&view=rev
Log:
Model scalar writes with uses outside the SCoP

  These write are important as they will force the scheduling and code
  generation of an otherwise trivial statement and also impose an order of
  execution needed to guarantee the correct final value for a scalar in a loop.

  Added test case modeled after ClamAV/clamscan.

Added:
    polly/trunk/test/ScopInfo/escaping_empty_scop.ll
Modified:
    polly/trunk/lib/Analysis/TempScopInfo.cpp

Modified: polly/trunk/lib/Analysis/TempScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/TempScopInfo.cpp?rev=228847&r1=228846&r2=228847&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/TempScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/TempScopInfo.cpp Wed Feb 11 11:02:52 2015
@@ -141,10 +141,7 @@ void TempScopInfo::buildPHIAccesses(PHIN
 }
 
 bool TempScopInfo::buildScalarDependences(Instruction *Inst, Region *R) {
-  // No need to translate these scalar dependences into polyhedral form, because
-  // synthesizable scalars can be generated by the code generator.
-  if (canSynthesize(Inst, LI, SE, R))
-    return false;
+  bool canSynthesizeInst = canSynthesize(Inst, LI, SE, R);
   if (isIgnoredIntrinsic(Inst))
     return false;
 
@@ -170,12 +167,23 @@ bool TempScopInfo::buildScalarDependence
     if (UseParent == ParentBB)
       continue;
 
+    // Check whether or not the use is in the SCoP.
+    if (!R->contains(UseParent)) {
+      AnyCrossStmtUse = true;
+      continue;
+    }
+
+    // If the instruction can be synthesized and the user is in the region
+    // we do not need to add scalar dependences.
+    if (canSynthesizeInst)
+      continue;
+
     // No need to translate these scalar dependences into polyhedral form,
     // because synthesizable scalars can be generated by the code generator.
     if (canSynthesize(UI, LI, SE, R))
       continue;
 
-    // Skip PHI nodes as they handle their operands on their own.
+    // Skip PHI nodes in the region as they handle their operands on their own.
     if (isa<PHINode>(UI))
       continue;
 
@@ -183,9 +191,6 @@ bool TempScopInfo::buildScalarDependence
     AnyCrossStmtUse = true;
 
     // Do not build a read access that is not in the current SCoP
-    if (!R->contains(UseParent))
-      continue;
-
     // Use the def instruction as base address of the IRAccess, so that it will
     // become the name of the scalar access in the polyhedral form.
     IRAccess ScalarAccess(IRAccess::READ, Inst, ZeroOffset, 1, true);

Added: polly/trunk/test/ScopInfo/escaping_empty_scop.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ScopInfo/escaping_empty_scop.ll?rev=228847&view=auto
==============================================================================
--- polly/trunk/test/ScopInfo/escaping_empty_scop.ll (added)
+++ polly/trunk/test/ScopInfo/escaping_empty_scop.ll Wed Feb 11 11:02:52 2015
@@ -0,0 +1,58 @@
+; RUN: opt %loadPolly -polly-scops -disable-polly-intra-scop-scalar-to-array -polly-model-phi-nodes -analyze < %s | FileCheck %s
+;
+;    void g();
+;    int f(int *A) {
+;      int a0 = 0, a1 = 0, a2 = 0;
+;      for (int i = 0; i < 1000; i++) {
+;        a0 = 2 * i;
+;        // split
+;        A[0] = i;
+;        a1 = 2 * i;
+;        // split
+;        a2 = 2 * i;
+;      }
+;      g();
+;      return a1 + a2;
+;    }
+;
+; CHECK:      Stmt_bb1
+; CHECK:            MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
+; CHECK:                { Stmt_bb1[i0] -> MemRef_a_0[] };
+; CHECK:      Stmt_bb2
+; CHECK:            MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
+; CHECK:                { Stmt_bb2[i0] -> MemRef_a_1[] };
+; CHECK:      Stmt_bb3
+; CHECK:            MustWriteAccess :=  [Reduction Type: NONE] [Scalar: 1]
+; CHECK:                { Stmt_bb3[i0] -> MemRef_a_2[] };
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+
+define i32 @f(i32* %A) {
+bb:
+  br label %bb1
+
+bb1:                                              ; preds = %bb3, %bb
+  %i.0 = phi i32 [ 0, %bb ], [ %tmp4, %bb3 ]
+  %a.0 = mul i32 %i.0, 2
+  br label %bb2
+
+bb2:                                              ; preds = %bb1
+  %a.1 = mul i32 %i.0, 2
+  store i32 %i.0, i32 *%A, align 4
+  br label %bb3
+
+bb3:                                              ; preds = %bb2
+  %tmp = shl nsw i32 %i.0, 1
+  %tmp4 = add nuw nsw i32 %i.0, 1
+  %a.2 = mul i32 %i.0, 2
+  %exitcond = icmp ne i32 %i.0, 1000
+  br i1 %exitcond, label %bb1, label %bb5
+
+bb5:                                              ; preds = %bb1
+  call void (...)* @g() #2
+  %add = add i32 %a.0, %a.1
+  %add2 = add i32 %add, %a.2
+  ret i32 %add2
+}
+
+declare void @g(...) #1





More information about the llvm-commits mailing list