[DeLICM] Properly handle PHI writes becoming empty partial writes.
authorMichael Kruse <llvm@meinersbur.de>
Tue, 8 Aug 2017 11:27:12 +0000 (11:27 +0000)
committerMichael Kruse <llvm@meinersbur.de>
Tue, 8 Aug 2017 11:27:12 +0000 (11:27 +0000)
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.

llvm-svn: 310348

polly/lib/Transform/DeLICM.cpp
polly/test/DeLICM/reduction_looprotate_alwaystaken.ll [new file with mode: 0644]

index 4747a7b..8a47d21 100644 (file)
@@ -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.
diff --git a/polly/test/DeLICM/reduction_looprotate_alwaystaken.ll b/polly/test/DeLICM/reduction_looprotate_alwaystaken.ll
new file mode 100644 (file)
index 0000000..fbb20e1
--- /dev/null
@@ -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: }