[polly] r310348 - [DeLICM] Properly handle PHI writes becoming empty partial writes.

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 8 04:27:13 PDT 2017


Author: meinersbur
Date: Tue Aug  8 04:27:12 2017
New Revision: 310348

URL: http://llvm.org/viewvc/llvm-project?rev=310348&view=rev
Log:
[DeLICM] Properly handle PHI writes becoming empty partial writes.

It is possible that partial writes are empty (write is never executed).
In this case, when in PHINode's incoming edge is never taken such that
the incoming write becomes an empty partial write, if enabled. The
issue is that when converting the union_map to an map, it's space
cannot be derived from the union_map itself. Rather, we need to
determine its space independently.

This fixes test-suite's MultiSource/Benchmarks/ASC_Sequoia/CrystalMk.

Added:
    polly/trunk/test/DeLICM/reduction_looprotate_alwaystaken.ll
Modified:
    polly/trunk/lib/Transform/DeLICM.cpp

Modified: polly/trunk/lib/Transform/DeLICM.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Transform/DeLICM.cpp?rev=310348&r1=310347&r2=310348&view=diff
==============================================================================
--- polly/trunk/lib/Transform/DeLICM.cpp (original)
+++ polly/trunk/lib/Transform/DeLICM.cpp Tue Aug  8 04:27:12 2017
@@ -1048,6 +1048,9 @@ private:
   void mapPHI(const ScopArrayInfo *SAI, isl::map ReadTarget,
               isl::union_map WriteTarget, isl::map Lifetime,
               Knowledge Proposed) {
+    // { Element[] }
+    isl::space ElementSpace = ReadTarget.get_space().range();
+
     // Redirect the PHI incoming writes.
     for (auto *MA : S->getPHIIncomings(SAI)) {
       // { DomainWrite[] }
@@ -1055,11 +1058,13 @@ private:
 
       // { DomainWrite[] -> Element[] }
       auto NewAccRel = give(isl_union_map_intersect_domain(
-          WriteTarget.copy(), isl_union_set_from_set(Domain.take())));
+          WriteTarget.copy(), isl_union_set_from_set(Domain.copy())));
       simplify(NewAccRel);
 
-      assert(isl_union_map_n_map(NewAccRel.keep()) == 1);
-      MA->setNewAccessRelation(isl::map::from_union_map(NewAccRel));
+      isl::space NewAccRelSpace =
+          Domain.get_space().map_from_domain_and_range(ElementSpace);
+      isl::map NewAccRelMap = singleton(NewAccRel, NewAccRelSpace);
+      MA->setNewAccessRelation(NewAccRelMap);
     }
 
     // Redirect the PHI read.

Added: polly/trunk/test/DeLICM/reduction_looprotate_alwaystaken.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DeLICM/reduction_looprotate_alwaystaken.ll?rev=310348&view=auto
==============================================================================
--- polly/trunk/test/DeLICM/reduction_looprotate_alwaystaken.ll (added)
+++ polly/trunk/test/DeLICM/reduction_looprotate_alwaystaken.ll Tue Aug  8 04:27:12 2017
@@ -0,0 +1,80 @@
+; RUN: opt %loadPolly -polly-flatten-schedule -polly-delicm-overapproximate-writes=true -polly-delicm-compute-known=true -polly-delicm -analyze < %s | FileCheck %s
+;
+; Verify that delicm can cope with never taken PHI incoming edges.
+; The edge %body -> %body_phi is never taken, hence the access MemoryKind::PHI,
+; WRITE in %body for %phi is never used.
+; When mapping %phi, the write's access relation is the empty set.
+;
+;    void func(double *A) {
+;      for (int j = 0; j < 2; j += 1) { /* outer */
+;        for (int i = 0; i < 4; i += 1) { /* reduction */
+;          double phi = 21.0;
+;          if (j < 10) // Tautology, since 0<=j<2
+;            phi = 42.0;
+;        }
+;        A[j] = phi;
+;      }
+;    }
+;
+define void @func(double* noalias nonnull %A, double* noalias nonnull %dummy) {
+entry:
+  br label %outer.preheader
+
+outer.preheader:
+  br label %outer.for
+
+outer.for:
+  %j = phi i32 [0, %outer.preheader], [%j.inc, %outer.inc]
+  %j.cmp = icmp slt i32 %j, 2
+  br i1 %j.cmp, label %reduction.preheader, label %outer.exit
+
+
+    reduction.preheader:
+      %A_idx = getelementptr inbounds double, double* %A, i32 %j
+      br label %reduction.for
+
+    reduction.for:
+      %i = phi i32 [0, %reduction.preheader], [%i.inc, %reduction.inc]
+      br label %body
+
+
+
+        body:
+          %cond = icmp slt i32 %j, 10
+          br i1 %cond, label %alwaystaken, label %body_phi
+
+        alwaystaken:
+          store double 0.0, double* %dummy
+          br label %body_phi
+
+        body_phi:
+          %phi = phi double [21.0, %body], [42.0, %alwaystaken]
+          br label %reduction.inc
+
+
+
+    reduction.inc:
+      %i.inc = add nuw nsw i32 %i, 1
+      %i.cmp = icmp slt i32 %i.inc, 4
+      br i1 %i.cmp, label %reduction.for, label %reduction.exit
+
+    reduction.exit:
+      store double %phi, double* %A_idx
+      br label %outer.inc
+
+
+outer.inc:
+  %j.inc = add nuw nsw i32 %j, 1
+  br label %outer.for
+
+outer.exit:
+  br label %return
+
+return:
+  ret void
+}
+
+
+; CHECK: Statistics {
+; CHECK:     PHI scalars mapped:    1
+; CHECK: }




More information about the llvm-commits mailing list