[polly] r212796 - DeadCodeElim: Compute correct liveout for non-affine accesses
Tobias Grosser
tobias at grosser.es
Fri Jul 11 00:12:11 PDT 2014
Author: grosser
Date: Fri Jul 11 02:12:10 2014
New Revision: 212796
URL: http://llvm.org/viewvc/llvm-project?rev=212796&view=rev
Log:
DeadCodeElim: Compute correct liveout for non-affine accesses
Thanks to Johannes Doerfert for narrowing down the bug.
Reported-by: Chris Jenneisch <chrisj at codeaurora.org>
Added:
polly/trunk/test/DeadCodeElimination/non-affine-affine-mix.ll
polly/trunk/test/DeadCodeElimination/non-affine.ll
Modified:
polly/trunk/include/polly/ScopInfo.h
polly/trunk/lib/Analysis/ScopInfo.cpp
polly/trunk/lib/Transform/DeadCodeElimination.cpp
Modified: polly/trunk/include/polly/ScopInfo.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/ScopInfo.h?rev=212796&r1=212795&r2=212796&view=diff
==============================================================================
--- polly/trunk/include/polly/ScopInfo.h (original)
+++ polly/trunk/include/polly/ScopInfo.h Fri Jul 11 02:12:10 2014
@@ -702,6 +702,12 @@ public:
/// @brief Get a union set containing the iteration domains of all statements.
__isl_give isl_union_set *getDomains();
+ /// @brief Get a union map of all may-writes performed in the SCoP.
+ __isl_give isl_union_map *getMayWrites();
+
+ /// @brief Get a union map of all must-writes performed in the SCoP.
+ __isl_give isl_union_map *getMustWrites();
+
/// @brief Get a union map of all writes performed in the SCoP.
__isl_give isl_union_map *getWrites();
Modified: polly/trunk/lib/Analysis/ScopInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Analysis/ScopInfo.cpp?rev=212796&r1=212795&r2=212796&view=diff
==============================================================================
--- polly/trunk/lib/Analysis/ScopInfo.cpp (original)
+++ polly/trunk/lib/Analysis/ScopInfo.cpp Fri Jul 11 02:12:10 2014
@@ -1269,6 +1269,40 @@ __isl_give isl_union_set *Scop::getDomai
return Domain;
}
+__isl_give isl_union_map *Scop::getMustWrites() {
+ isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
+
+ for (ScopStmt *Stmt : *this) {
+ for (MemoryAccess *MA : *Stmt) {
+ if (!MA->isMustWrite())
+ continue;
+
+ isl_set *Domain = Stmt->getDomain();
+ isl_map *AccessDomain = MA->getAccessRelation();
+ AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
+ Write = isl_union_map_add_map(Write, AccessDomain);
+ }
+ }
+ return isl_union_map_coalesce(Write);
+}
+
+__isl_give isl_union_map *Scop::getMayWrites() {
+ isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
+
+ for (ScopStmt *Stmt : *this) {
+ for (MemoryAccess *MA : *Stmt) {
+ if (!MA->isMayWrite())
+ continue;
+
+ isl_set *Domain = Stmt->getDomain();
+ isl_map *AccessDomain = MA->getAccessRelation();
+ AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
+ Write = isl_union_map_add_map(Write, AccessDomain);
+ }
+ }
+ return isl_union_map_coalesce(Write);
+}
+
__isl_give isl_union_map *Scop::getWrites() {
isl_union_map *Write = isl_union_map_empty(this->getParamSpace());
Modified: polly/trunk/lib/Transform/DeadCodeElimination.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Transform/DeadCodeElimination.cpp?rev=212796&r1=212795&r2=212796&view=diff
==============================================================================
--- polly/trunk/lib/Transform/DeadCodeElimination.cpp (original)
+++ polly/trunk/lib/Transform/DeadCodeElimination.cpp Fri Jul 11 02:12:10 2014
@@ -36,6 +36,7 @@
#include "polly/LinkAllPasses.h"
#include "polly/ScopInfo.h"
#include "llvm/Support/CommandLine.h"
+#include "isl/flow.h"
#include "isl/set.h"
#include "isl/map.h"
#include "isl/union_map.h"
@@ -63,26 +64,35 @@ public:
void getAnalysisUsage(AnalysisUsage &AU) const;
private:
- isl_union_set *getLastWrites(isl_union_map *Writes, isl_union_map *Schedule);
+ /// @brief Return the set of live iterations.
+ ///
+ /// The set of live iterations are all iterations that write to memory and for
+ /// which we can not prove that there will be a later write that _must_
+ /// overwrite the same memory location and is consequently the only one that
+ /// is visible after the execution of the SCoP.
+ ///
+ isl_union_set *getLiveOut(Scop &S);
bool eliminateDeadCode(Scop &S, int PreciseSteps);
};
}
char DeadCodeElim::ID = 0;
-/// Return the set of iterations that contains the last write for each location.
-isl_union_set *DeadCodeElim::getLastWrites(__isl_take isl_union_map *Writes,
- __isl_take isl_union_map *Schedule) {
- isl_union_map *WriteIterations = isl_union_map_reverse(Writes);
- isl_union_map *WriteTimes =
- isl_union_map_apply_range(WriteIterations, isl_union_map_copy(Schedule));
-
- isl_union_map *LastWriteTimes = isl_union_map_lexmax(WriteTimes);
- isl_union_map *LastWriteIterations = isl_union_map_apply_range(
- LastWriteTimes, isl_union_map_reverse(Schedule));
-
- isl_union_set *Live = isl_union_map_range(LastWriteIterations);
- return isl_union_set_coalesce(Live);
+// To compute the live outs, we first assume all must and may-writes are exposed
+// and then subtract the set of statements that are definitely overwritten.
+isl_union_set *DeadCodeElim::getLiveOut(Scop &S) {
+ __isl_take isl_union_map *Kills = S.getMustWrites();
+ __isl_take isl_union_map *Empty = isl_union_map_empty(S.getParamSpace());
+
+ isl_union_map *Covering;
+ isl_union_map *Writes = S.getWrites();
+ isl_union_map_compute_flow(Kills, Empty, isl_union_map_copy(Writes),
+ S.getSchedule(), NULL, &Covering, NULL, NULL);
+
+ isl_union_map *Exposed = Writes;
+ Exposed =
+ isl_union_map_subtract_domain(Exposed, isl_union_map_domain(Covering));
+ return isl_union_map_domain(Exposed);
}
/// Performs polyhedral dead iteration elimination by:
@@ -99,7 +109,7 @@ bool DeadCodeElim::eliminateDeadCode(Sco
if (!D->hasValidDependences())
return false;
- isl_union_set *Live = this->getLastWrites(S.getWrites(), S.getSchedule());
+ isl_union_set *Live = getLiveOut(S);
isl_union_map *Dep =
D->getDependences(Dependences::TYPE_RAW | Dependences::TYPE_RED);
Dep = isl_union_map_reverse(Dep);
Added: polly/trunk/test/DeadCodeElimination/non-affine-affine-mix.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DeadCodeElimination/non-affine-affine-mix.ll?rev=212796&view=auto
==============================================================================
--- polly/trunk/test/DeadCodeElimination/non-affine-affine-mix.ll (added)
+++ polly/trunk/test/DeadCodeElimination/non-affine-affine-mix.ll Fri Jul 11 02:12:10 2014
@@ -0,0 +1,53 @@
+; RUN: opt %loadPolly -polly-allow-nonaffine -polly-dce -polly-ast -analyze < %s | FileCheck %s
+;
+; void f(int *A) {
+; for (int i = 0; i < 1024; i++)
+; S1: A[i % 2] = i;
+; for (int i = 0; i < 1024; i++)
+; S2: A[i2] = i;
+; }
+
+; CHECK-NOT: Stmt_S1
+
+; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1)
+; CHECK: Stmt_S2(c1);
+
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %A) {
+entry:
+ br label %for.cond
+
+for.cond:
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %i.0, 1024
+ br i1 %exitcond, label %S1, label %for.cond.2
+
+S1:
+ %rem = srem i32 %i.0, 2
+ %arrayidx = getelementptr inbounds i32* %A, i32 %rem
+ store i32 %i.0, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc:
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.cond.2:
+ %i.2 = phi i32 [ 0, %for.cond ], [ %inc.2, %for.inc.2 ]
+ %exitcond.2 = icmp ne i32 %i.2, 1024
+ br i1 %exitcond.2, label %S2, label %for.end
+
+S2:
+ %arrayidx.2 = getelementptr inbounds i32* %A, i32 %i.2
+ store i32 %i.2, i32* %arrayidx.2, align 4
+ br label %for.inc.2
+
+for.inc.2:
+ %inc.2 = add nsw i32 %i.2, 1
+ br label %for.cond.2
+
+for.end:
+ ret void
+}
+
Added: polly/trunk/test/DeadCodeElimination/non-affine.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/DeadCodeElimination/non-affine.ll?rev=212796&view=auto
==============================================================================
--- polly/trunk/test/DeadCodeElimination/non-affine.ll (added)
+++ polly/trunk/test/DeadCodeElimination/non-affine.ll Fri Jul 11 02:12:10 2014
@@ -0,0 +1,34 @@
+; RUN: opt %loadPolly -polly-allow-nonaffine -polly-dce -polly-ast -analyze < %s | FileCheck %s
+;
+; CHECK: for (int c1 = 0; c1 <= 1023; c1 += 1)
+;
+; void f(int *A) {
+; for (int i = 0; i < 1024; i++)
+; A[i % 2] = i;
+; }
+;
+target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-n32-S64"
+
+define void @f(i32* %A) {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ]
+ %exitcond = icmp ne i32 %i.0, 1024
+ br i1 %exitcond, label %for.body, label %for.end
+
+for.body: ; preds = %for.cond
+ %rem = srem i32 %i.0, 2
+ %arrayidx = getelementptr inbounds i32* %A, i32 %rem
+ store i32 %i.0, i32* %arrayidx, align 4
+ br label %for.inc
+
+for.inc: ; preds = %for.body
+ %inc = add nsw i32 %i.0, 1
+ br label %for.cond
+
+for.end: ; preds = %for.cond
+ ret void
+}
+
More information about the llvm-commits
mailing list