summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--polly/lib/Transform/Simplify.cpp42
-rw-r--r--polly/test/Simplify/emptyaccessdomain.ll38
-rw-r--r--polly/test/Simplify/emptyaccessdomain___%for---%return.jscop24
-rw-r--r--polly/test/Simplify/emptyaccessdomain___%for---%return.jscop.transformed24
4 files changed, 126 insertions, 2 deletions
diff --git a/polly/lib/Transform/Simplify.cpp b/polly/lib/Transform/Simplify.cpp
index a97fcef98fc..008503bdbb3 100644
--- a/polly/lib/Transform/Simplify.cpp
+++ b/polly/lib/Transform/Simplify.cpp
@@ -36,6 +36,8 @@ STATISTIC(InBetweenStore, "Number of Load-Store pairs NOT removed because "
STATISTIC(TotalOverwritesRemoved, "Number of removed overwritten writes");
STATISTIC(TotalRedundantWritesRemoved,
"Number of writes of same value removed in any SCoP");
+STATISTIC(TotalEmptyPartialAccessesRemoved,
+ "Number of empty partial accesses removed");
STATISTIC(TotalDeadAccessesRemoved, "Number of dead accesses removed");
STATISTIC(TotalDeadInstructionsRemoved,
"Number of unused instructions removed");
@@ -97,6 +99,9 @@ private:
/// Number of redundant writes removed from this SCoP.
int RedundantWritesRemoved = 0;
+ /// Number of writes with empty access domain removed.
+ int EmptyPartialAccessesRemoved = 0;
+
/// Number of unused accesses removed from this SCoP.
int DeadAccessesRemoved = 0;
@@ -109,8 +114,8 @@ private:
/// Return whether at least one simplification has been applied.
bool isModified() const {
return OverwritesRemoved > 0 || RedundantWritesRemoved > 0 ||
- DeadAccessesRemoved > 0 || DeadInstructionsRemoved > 0 ||
- StmtsRemoved > 0;
+ EmptyPartialAccessesRemoved > 0 || DeadAccessesRemoved > 0 ||
+ DeadInstructionsRemoved > 0 || StmtsRemoved > 0;
}
MemoryAccess *getReadAccessForValue(ScopStmt *Stmt, llvm::Value *Val) {
@@ -319,6 +324,33 @@ private:
TotalStmtsRemoved += StmtsRemoved;
}
+ /// Remove accesses that have an empty domain.
+ void removeEmptyPartialAccesses() {
+ for (ScopStmt &Stmt : *S) {
+ // Defer the actual removal to not invalidate iterators.
+ SmallVector<MemoryAccess *, 8> DeferredRemove;
+
+ for (MemoryAccess *MA : Stmt) {
+ if (!MA->isWrite())
+ continue;
+
+ isl::map AccRel = give(MA->getAccessRelation());
+ if (!AccRel.is_empty().is_true())
+ continue;
+
+ DEBUG(dbgs() << "Removing " << MA
+ << " because it's a partial access that never occurs\n");
+ DeferredRemove.push_back(MA);
+ }
+
+ for (MemoryAccess *MA : DeferredRemove) {
+ Stmt.removeSingleMemoryAccess(MA);
+ EmptyPartialAccessesRemoved++;
+ TotalEmptyPartialAccessesRemoved++;
+ }
+ }
+ }
+
/// Mark all reachable instructions and access, and sweep those that are not
/// reachable.
void markAndSweep(LoopInfo *LI) {
@@ -380,6 +412,8 @@ private:
<< '\n';
OS.indent(Indent + 4) << "Redundant writes removed: "
<< RedundantWritesRemoved << "\n";
+ OS.indent(Indent + 4) << "Access with empty domains removed: "
+ << EmptyPartialAccessesRemoved << "\n";
OS.indent(Indent + 4) << "Dead accesses removed: " << DeadAccessesRemoved
<< '\n';
OS.indent(Indent + 4) << "Dead instructions removed: "
@@ -424,6 +458,9 @@ public:
DEBUG(dbgs() << "Removing redundant writes...\n");
removeRedundantWrites();
+ DEBUG(dbgs() << "Removing partial writes that never happen...\n");
+ removeEmptyPartialAccesses();
+
DEBUG(dbgs() << "Cleanup unused accesses...\n");
LoopInfo *LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
markAndSweep(LI);
@@ -456,6 +493,7 @@ public:
OverwritesRemoved = 0;
RedundantWritesRemoved = 0;
+ EmptyPartialAccessesRemoved = 0;
DeadAccessesRemoved = 0;
DeadInstructionsRemoved = 0;
StmtsRemoved = 0;
diff --git a/polly/test/Simplify/emptyaccessdomain.ll b/polly/test/Simplify/emptyaccessdomain.ll
new file mode 100644
index 00000000000..641d34e9ecc
--- /dev/null
+++ b/polly/test/Simplify/emptyaccessdomain.ll
@@ -0,0 +1,38 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-postfix=transformed -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
+;
+; for (int j = 0; j < n; j += 1) {
+; A[0] = 42.0;
+; }
+;
+define void @emptyaccessdomain(i32 %n, double* noalias nonnull %A) {
+entry:
+ br label %for
+
+for:
+ %j = phi i32 [0, %entry], [%j.inc, %inc]
+ %j.cmp = icmp slt i32 %j, %n
+ br i1 %j.cmp, label %body, label %exit
+
+ body:
+ store double 42.0, double* %A
+ br label %inc
+
+inc:
+ %j.inc = add nuw nsw i32 %j, 1
+ br label %for
+
+exit:
+ br label %return
+
+return:
+ ret void
+}
+
+
+; CHECK: Statistics {
+; CHECK: Overwrites removed: 1
+; CHECK: Stmts removed: 1
+; CHECK: }
+
+; CHECK: After accesses {
+; CHECK-NEXT: }
diff --git a/polly/test/Simplify/emptyaccessdomain___%for---%return.jscop b/polly/test/Simplify/emptyaccessdomain___%for---%return.jscop
new file mode 100644
index 00000000000..a0472bc116b
--- /dev/null
+++ b/polly/test/Simplify/emptyaccessdomain___%for---%return.jscop
@@ -0,0 +1,24 @@
+{
+ "arrays" : [
+ {
+ "name" : "MemRef_A",
+ "sizes" : [ "*" ],
+ "type" : "double"
+ }
+ ],
+ "context" : "[n] -> { : -2147483648 <= n <= 2147483647 }",
+ "name" : "%for---%return",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_body[i0] -> MemRef_A[0] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_body",
+ "schedule" : "[n] -> { Stmt_body[i0] -> [i0] }"
+ }
+ ]
+}
diff --git a/polly/test/Simplify/emptyaccessdomain___%for---%return.jscop.transformed b/polly/test/Simplify/emptyaccessdomain___%for---%return.jscop.transformed
new file mode 100644
index 00000000000..e881f7e1232
--- /dev/null
+++ b/polly/test/Simplify/emptyaccessdomain___%for---%return.jscop.transformed
@@ -0,0 +1,24 @@
+{
+ "arrays" : [
+ {
+ "name" : "MemRef_A",
+ "sizes" : [ "*" ],
+ "type" : "double"
+ }
+ ],
+ "context" : "[n] -> { : -2147483648 <= n <= 2147483647 }",
+ "name" : "%for---%return",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_body[i0] -> MemRef_A[0] : 1 = 0 }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_body",
+ "schedule" : "[n] -> { Stmt_body[i0] -> [i0] }"
+ }
+ ]
+}
OpenPOWER on IntegriCloud