[polly] r309734 - [Simplify] Rewrite redundant write detection algorithm.
Michael Kruse via llvm-commits
llvm-commits at lists.llvm.org
Tue Aug 1 13:01:34 PDT 2017
Author: meinersbur
Date: Tue Aug 1 13:01:34 2017
New Revision: 309734
URL: http://llvm.org/viewvc/llvm-project?rev=309734&view=rev
Log:
[Simplify] Rewrite redundant write detection algorithm.
The previous algorithm was to search a writes and the sours of its value
operand, and see whether the write just stores the same read value back,
which includes a search whether there is another write access between
them. This is O(n^2) in the max number of accesses in a statement
(+ the complexity of isl comparing the access functions).
The new algorithm is more similar to the one used for searching for
overwrites and coalescable writes. It scans over all accesses in order
of execution while tracking which array elements still have the same
value since it was read. This is O(n), not counting the complexity
within isl. It should be more reliable than trying to catch all
non-conforming cases in the previous approach. It is also less code.
We now also support if the write is a partial write of the read's
domain, and to some extent non-affine subregions.
Differential Revision: https://reviews.llvm.org/D36137
Added:
polly/trunk/test/Simplify/notredundant_region_loop.ll
polly/trunk/test/Simplify/notredundant_region_loop___%for---%return.jscop
polly/trunk/test/Simplify/notredundant_region_loop___%for---%return.jscop.transformed
polly/trunk/test/Simplify/notredundant_region_middle.ll
polly/trunk/test/Simplify/redundant_partialwrite.ll
polly/trunk/test/Simplify/redundant_partialwrite___%for---%return.jscop
polly/trunk/test/Simplify/redundant_partialwrite___%for---%return.jscop.transformed
polly/trunk/test/Simplify/redundant_region.ll
polly/trunk/test/Simplify/redundant_region___%for---%return.jscop
polly/trunk/test/Simplify/redundant_region___%for---%return.jscop.transformed
polly/trunk/test/Simplify/redundant_region_scalar.ll
polly/trunk/test/Simplify/redundant_region_scalar___%for---%return.jscop
polly/trunk/test/Simplify/redundant_region_scalar___%for---%return.jscop.transformed
Modified:
polly/trunk/lib/Transform/Simplify.cpp
polly/trunk/test/Simplify/redundant_differentindex.ll
polly/trunk/test/Simplify/redundant_storebetween.ll
Modified: polly/trunk/lib/Transform/Simplify.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Transform/Simplify.cpp?rev=309734&r1=309733&r2=309734&view=diff
==============================================================================
--- polly/trunk/lib/Transform/Simplify.cpp (original)
+++ polly/trunk/lib/Transform/Simplify.cpp Tue Aug 1 13:01:34 2017
@@ -36,10 +36,6 @@ static int const SimplifyMaxDisjuncts =
STATISTIC(ScopsProcessed, "Number of SCoPs processed");
STATISTIC(ScopsModified, "Number of SCoPs simplified");
-STATISTIC(PairUnequalAccRels, "Number of Load-Store pairs NOT removed because "
- "of different access relations");
-STATISTIC(InBetweenStore, "Number of Load-Store pairs NOT removed because "
- "there is another store between them");
STATISTIC(TotalOverwritesRemoved, "Number of removed overwritten writes");
STATISTIC(TotalWritesCoalesced, "Number of writes coalesced with another");
STATISTIC(TotalRedundantWritesRemoved,
@@ -169,76 +165,6 @@ private:
StmtsRemoved > 0;
}
- MemoryAccess *getReadAccessForValue(ScopStmt *Stmt, llvm::Value *Val) {
- if (!isa<Instruction>(Val))
- return nullptr;
-
- for (auto *MA : *Stmt) {
- if (!MA->isRead())
- continue;
- if (MA->getAccessValue() != Val)
- continue;
-
- return MA;
- }
-
- return nullptr;
- }
-
- /// Return a write access that occurs between @p From and @p To.
- ///
- /// In region statements the order is ignored because we cannot predict it.
- ///
- /// @param Stmt Statement of both writes.
- /// @param From Start looking after this access.
- /// @param To Stop looking at this access, with the access itself.
- /// @param Targets Look for an access that may wrote to one of these elements.
- ///
- /// @return A write access between @p From and @p To that writes to at least
- /// one element in @p Targets.
- MemoryAccess *hasWriteBetween(ScopStmt *Stmt, MemoryAccess *From,
- MemoryAccess *To, isl::map Targets) {
- auto TargetsSpace = Targets.get_space();
-
- bool Started = Stmt->isRegionStmt();
- auto Accesses = getAccessesInOrder(*Stmt);
- for (auto *Acc : Accesses) {
- if (Acc->isLatestScalarKind())
- continue;
-
- if (Stmt->isBlockStmt() && From == Acc) {
- assert(!Started);
- Started = true;
- continue;
- }
- if (Stmt->isBlockStmt() && To == Acc) {
- assert(Started);
- return nullptr;
- }
- if (!Started)
- continue;
-
- if (!Acc->isWrite())
- continue;
-
- isl::map AccRel = Acc->getAccessRelation();
- auto AccRelSpace = AccRel.get_space();
-
- // Spaces being different means that they access different arrays.
- if (!TargetsSpace.has_equal_tuples(AccRelSpace))
- continue;
-
- AccRel = AccRel.intersect_domain(give(Acc->getStatement()->getDomain()));
- AccRel = AccRel.intersect_params(give(S->getContext()));
- auto CommonElt = Targets.intersect(AccRel);
- if (!CommonElt.is_empty())
- return Acc;
- }
- assert(Stmt->isRegionStmt() &&
- "To must be encountered in block statements");
- return nullptr;
- }
-
/// Remove writes that are overwritten unconditionally later in the same
/// statement.
///
@@ -484,76 +410,97 @@ private:
/// Remove writes that just write the same value already stored in the
/// element.
void removeRedundantWrites() {
- // Delay actual removal to not invalidate iterators.
- SmallVector<MemoryAccess *, 8> StoresToRemove;
-
for (auto &Stmt : *S) {
- for (auto *WA : Stmt) {
- if (!WA->isMustWrite())
- continue;
- if (!WA->isLatestArrayKind())
- continue;
- if (!isa<StoreInst>(WA->getAccessInstruction()) &&
- !WA->isOriginalScalarKind())
- continue;
+ SmallDenseMap<Value *, isl::set> ValueSets;
+ auto makeValueSet = [&ValueSets, this](Value *V) -> isl::set {
+ assert(V);
+ isl::set &Result = ValueSets[V];
+ if (Result.is_null()) {
+ isl_ctx *Ctx = S->getIslCtx();
+ std::string Name =
+ getIslCompatibleName("Val", V, ValueSets.size() - 1,
+ std::string(), UseInstructionNames);
+ isl::id Id = give(isl_id_alloc(Ctx, Name.c_str(), V));
+ Result = isl::set::universe(
+ isl::space(Ctx, 0, 0).set_tuple_id(isl::dim::set, Id));
+ }
+ return Result;
+ };
- llvm::Value *ReadingValue = WA->tryGetValueStored();
+ isl::set Domain = give(Stmt.getDomain());
+ Domain = Domain.intersect_params(give(S->getContext()));
- if (!ReadingValue)
- continue;
+ // List of element reads that still have the same value while iterating
+ // through the MemoryAccesses.
+ // { [Domain[] -> Element[]] -> Val[] }
+ isl::union_map Known = isl::union_map::empty(give(S->getParamSpace()));
- auto RA = getReadAccessForValue(&Stmt, ReadingValue);
- if (!RA)
- continue;
- if (!RA->isLatestArrayKind())
- continue;
+ SmallVector<MemoryAccess *, 32> Accesses(getAccessesInOrder(Stmt));
+ for (MemoryAccess *MA : Accesses) {
+ // Is the memory access in a defined order relative to the other
+ // accesses? In region statements, only the first and the last accesses
+ // have defined order. Execution of those in the middle may depend on
+ // runtime conditions an therefore cannot be modified.
+ bool IsOrdered =
+ Stmt.isBlockStmt() || MA->isOriginalScalarKind() ||
+ (!S->getBoxedLoops().size() && MA->getAccessInstruction() &&
+ Stmt.getEntryBlock() == MA->getAccessInstruction()->getParent());
- auto WARel = WA->getLatestAccessRelation();
- WARel = WARel.intersect_domain(give(WA->getStatement()->getDomain()));
- WARel = WARel.intersect_params(give(S->getContext()));
- auto RARel = RA->getLatestAccessRelation();
- RARel = RARel.intersect_domain(give(RA->getStatement()->getDomain()));
- RARel = RARel.intersect_params(give(S->getContext()));
-
- if (!RARel.is_equal(WARel)) {
- PairUnequalAccRels++;
- DEBUG(dbgs() << "Not cleaning up " << WA
- << " because of unequal access relations:\n");
- DEBUG(dbgs() << " RA: " << RARel << "\n");
- DEBUG(dbgs() << " WA: " << WARel << "\n");
- continue;
- }
+ isl::map AccRel = MA->getAccessRelation();
+ AccRel = AccRel.intersect_domain(Domain);
+ isl::set AccRelWrapped = AccRel.wrap();
- if (auto *Conflicting = hasWriteBetween(&Stmt, RA, WA, WARel)) {
- (void)Conflicting;
- InBetweenStore++;
- DEBUG(dbgs() << "Not cleaning up " << WA
- << " because there is another store to the same element "
- "between\n");
- DEBUG(Conflicting->print(dbgs()));
- continue;
+ // Determine whether a write is redundant (stores only values that are
+ // already present in the written array elements) and remove it if this
+ // is the case.
+ if (IsOrdered && MA->isMustWrite() &&
+ (isa<StoreInst>(MA->getAccessInstruction()) ||
+ MA->isOriginalScalarKind())) {
+ Value *StoredVal = MA->tryGetValueStored();
+ if (!StoredVal)
+ StoredVal = MA->getAccessValue();
+
+ if (StoredVal) {
+ // Lookup in the set of known values.
+ isl::map AccRelStoredVal = isl::map::from_domain_and_range(
+ AccRelWrapped, makeValueSet(StoredVal));
+ if (isl::union_map(AccRelStoredVal).is_subset(Known)) {
+ DEBUG(dbgs() << "Cleanup of " << MA << ":\n");
+ DEBUG(dbgs() << " Scalar: " << *StoredVal << "\n");
+ DEBUG(dbgs() << " AccRel: " << AccRel << "\n");
+
+ Stmt.removeSingleMemoryAccess(MA);
+
+ RedundantWritesRemoved++;
+ TotalRedundantWritesRemoved++;
+ }
+ }
}
- StoresToRemove.push_back(WA);
+ // Update the know values set.
+ if (MA->isRead()) {
+ // Loaded values are the currently known values of the array element
+ // it was loaded from.
+ Value *LoadedVal = MA->getAccessValue();
+ if (LoadedVal && IsOrdered) {
+ isl::map AccRelVal = isl::map::from_domain_and_range(
+ AccRelWrapped, makeValueSet(LoadedVal));
+
+ Known = Known.add_map(AccRelVal);
+ }
+ } else if (MA->isWrite()) {
+ // Remove (possibly) overwritten values from the known elements set.
+ // We remove all elements of the accessed array to avoid too complex
+ // isl sets.
+ isl::set AccRelUniv = isl::set::universe(AccRelWrapped.get_space());
+ Known = Known.subtract_domain(AccRelUniv);
+
+ // At this point, we could add the written value of must-writes.
+ // However, writing same values is already handled by
+ // coalesceWrites().
+ }
}
}
-
- for (auto *WA : StoresToRemove) {
- auto Stmt = WA->getStatement();
- auto AccRel = WA->getAccessRelation();
- auto AccVal = WA->getAccessValue();
-
- DEBUG(dbgs() << "Cleanup of " << WA << ":\n");
- DEBUG(dbgs() << " Scalar: " << *AccVal << "\n");
- DEBUG(dbgs() << " AccRel: " << AccRel << "\n");
- (void)AccVal;
- (void)AccRel;
-
- Stmt->removeSingleMemoryAccess(WA);
-
- RedundantWritesRemoved++;
- TotalRedundantWritesRemoved++;
- }
}
/// Remove statements without side effects.
Added: polly/trunk/test/Simplify/notredundant_region_loop.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/notredundant_region_loop.ll?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/notredundant_region_loop.ll (added)
+++ polly/trunk/test/Simplify/notredundant_region_loop.ll Tue Aug 1 13:01:34 2017
@@ -0,0 +1,46 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-postfix=transformed -polly-allow-nonaffine-loops -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
+;
+; Do not remove the store in region_entry. It can be executed multiple times
+; due to being part of a non-affine loop.
+;
+define void @notredundant_region_loop(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:
+ %val = fadd double 21.0, 21.0
+ br label %region_entry
+
+ region_entry:
+ store double %val, double* %A
+ %sqr = mul i32 %j, %j
+ %cmp = icmp eq i32 %sqr, 42
+ br i1 %cmp, label %region_true, label %region_exit
+
+ region_true:
+ store double 0.0, double* %A
+ br label %region_entry
+
+ region_exit:
+ br label %inc
+
+
+inc:
+ %j.inc = add nuw nsw i32 %j, 1
+ br label %for
+
+exit:
+ br label %return
+
+return:
+ ret void
+}
+
+
+; CHECK: SCoP could not be simplified
Added: polly/trunk/test/Simplify/notredundant_region_loop___%for---%return.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/notredundant_region_loop___%25for---%25return.jscop?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/notredundant_region_loop___%for---%return.jscop (added)
+++ polly/trunk/test/Simplify/notredundant_region_loop___%for---%return.jscop Tue Aug 1 13:01:34 2017
@@ -0,0 +1,43 @@
+{
+ "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_val[] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_body",
+ "schedule" : "[n] -> { Stmt_body[i0] -> [i0, 0] }"
+ },
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_val[] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_region_entry__TO__region_exit",
+ "schedule" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> [i0, 1] }"
+ }
+ ]
+}
Added: polly/trunk/test/Simplify/notredundant_region_loop___%for---%return.jscop.transformed
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/notredundant_region_loop___%25for---%25return.jscop.transformed?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/notredundant_region_loop___%for---%return.jscop.transformed (added)
+++ polly/trunk/test/Simplify/notredundant_region_loop___%for---%return.jscop.transformed Tue Aug 1 13:01:34 2017
@@ -0,0 +1,43 @@
+{
+ "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, 0] }"
+ },
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_region_entry__TO__region_exit",
+ "schedule" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> [i0, 1] }"
+ }
+ ]
+}
Added: polly/trunk/test/Simplify/notredundant_region_middle.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/notredundant_region_middle.ll?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/notredundant_region_middle.ll (added)
+++ polly/trunk/test/Simplify/notredundant_region_middle.ll Tue Aug 1 13:01:34 2017
@@ -0,0 +1,54 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-postfix=transformed -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
+;
+; Do not remove redundant stores in the middle of region statements.
+; The store in region_true could be removed, but in practice we do try to
+; determine the relative ordering of block in region statements.
+;
+; for (int j = 0; j < n; j += 1) {
+; double val = A[0];
+; if (val == 0.0)
+; A[0] = val;
+; else
+; A[0] = 0.0;
+; }
+;
+define void @notredundant_region(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 %region_entry, label %exit
+
+
+ region_entry:
+ %val = load double, double* %A
+ %cmp = fcmp oeq double %val, 0.0
+ br i1 %cmp, label %region_true, label %region_false
+
+ region_true:
+ store double %val, double* %A
+ br label %region_exit
+
+ region_false:
+ store double 0.0, double* %A
+ br label %region_exit
+
+ region_exit:
+ br label %inc
+
+
+inc:
+ %j.inc = add nuw nsw i32 %j, 1
+ br label %for
+
+exit:
+ br label %return
+
+return:
+ ret void
+}
+
+
+; CHECK: SCoP could not be simplified
Modified: polly/trunk/test/Simplify/redundant_differentindex.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_differentindex.ll?rev=309734&r1=309733&r2=309734&view=diff
==============================================================================
--- polly/trunk/test/Simplify/redundant_differentindex.ll (original)
+++ polly/trunk/test/Simplify/redundant_differentindex.ll Tue Aug 1 13:01:34 2017
@@ -1,6 +1,4 @@
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
-; RUN: opt %loadPolly -polly-simplify -disable-output -stats < %s 2>&1 | FileCheck %s --check-prefix=STATS -match-full-lines
-; REQUIRES: asserts
;
; A store that has a different index than the load it is storing is
; not redundant.
@@ -36,5 +34,3 @@ return:
; CHECK: SCoP could not be simplified
-
-; STATS: 1 polly-simplify - Number of Load-Store pairs NOT removed because of different access relations
Added: polly/trunk/test/Simplify/redundant_partialwrite.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_partialwrite.ll?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/redundant_partialwrite.ll (added)
+++ polly/trunk/test/Simplify/redundant_partialwrite.ll Tue Aug 1 13:01:34 2017
@@ -0,0 +1,40 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-postfix=transformed -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
+;
+; Remove a redundant store, if its partial domain is a subset of the
+; read's domain.
+;
+define void @redundant_partialwrite(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:
+ %val = load double, double* %A
+ store double %val, 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 successful import.
+; CHECK: new: [n] -> { Stmt_body[i0] -> MemRef_A[0] : i0 <= 15 };
+
+; CHECK: Statistics {
+; CHECK: Redundant writes removed: 1
+; CHECK: }
+
+; CHECK: After accesses {
+; CHECK-NEXT: }
Added: polly/trunk/test/Simplify/redundant_partialwrite___%for---%return.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_partialwrite___%25for---%25return.jscop?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/redundant_partialwrite___%for---%return.jscop (added)
+++ polly/trunk/test/Simplify/redundant_partialwrite___%for---%return.jscop Tue Aug 1 13:01:34 2017
@@ -0,0 +1,28 @@
+{
+ "arrays" : [
+ {
+ "name" : "MemRef_A",
+ "sizes" : [ "*" ],
+ "type" : "double"
+ }
+ ],
+ "context" : "[n] -> { : -2147483648 <= n <= 2147483647 }",
+ "name" : "%for---%return",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_body[i0] -> MemRef_A[0] }"
+ },
+ {
+ "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] }"
+ }
+ ]
+}
Added: polly/trunk/test/Simplify/redundant_partialwrite___%for---%return.jscop.transformed
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_partialwrite___%25for---%25return.jscop.transformed?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/redundant_partialwrite___%for---%return.jscop.transformed (added)
+++ polly/trunk/test/Simplify/redundant_partialwrite___%for---%return.jscop.transformed Tue Aug 1 13:01:34 2017
@@ -0,0 +1,28 @@
+{
+ "arrays" : [
+ {
+ "name" : "MemRef_A",
+ "sizes" : [ "*" ],
+ "type" : "double"
+ }
+ ],
+ "context" : "[n] -> { : -2147483648 <= n <= 2147483647 }",
+ "name" : "%for---%return",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_body[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_body[i0] -> MemRef_A[0] : i0 < 16 }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_body",
+ "schedule" : "[n] -> { Stmt_body[i0] -> [i0] }"
+ }
+ ]
+}
Added: polly/trunk/test/Simplify/redundant_region.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_region.ll?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/redundant_region.ll (added)
+++ polly/trunk/test/Simplify/redundant_region.ll Tue Aug 1 13:01:34 2017
@@ -0,0 +1,49 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-postfix=transformed -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
+;
+; Remove redundant store (a store that writes the same value already
+; at the destination) in a region.
+;
+define void @redundant_region(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 %region_entry, label %exit
+
+
+ region_entry:
+ %val = load double, double* %A
+ %cmp = fcmp oeq double %val, 0.0
+ br i1 %cmp, label %region_true, label %region_exit
+
+ region_true:
+ br label %region_exit
+
+ region_exit:
+ br label %body
+
+ body:
+ store double %val, 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: Redundant writes removed: 2
+; CHECK: }
+
+; CHECK: After accesses {
+; CHECK-NEXT: }
Added: polly/trunk/test/Simplify/redundant_region___%for---%return.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_region___%25for---%25return.jscop?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/redundant_region___%for---%return.jscop (added)
+++ polly/trunk/test/Simplify/redundant_region___%for---%return.jscop Tue Aug 1 13:01:34 2017
@@ -0,0 +1,43 @@
+{
+ "arrays" : [
+ {
+ "name" : "MemRef_A",
+ "sizes" : [ "*" ],
+ "type" : "double"
+ }
+ ],
+ "context" : "[n] -> { : -2147483648 <= n <= 2147483647 }",
+ "name" : "%for---%return",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_val[] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_region_entry__TO__region_exit",
+ "schedule" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> [i0, 0] }"
+ },
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_body[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_body[i0] -> MemRef_val[] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_body[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_body",
+ "schedule" : "[n] -> { Stmt_body[i0] -> [i0, 1] }"
+ }
+ ]
+}
Added: polly/trunk/test/Simplify/redundant_region___%for---%return.jscop.transformed
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_region___%25for---%25return.jscop.transformed?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/redundant_region___%for---%return.jscop.transformed (added)
+++ polly/trunk/test/Simplify/redundant_region___%for---%return.jscop.transformed Tue Aug 1 13:01:34 2017
@@ -0,0 +1,43 @@
+{
+ "arrays" : [
+ {
+ "name" : "MemRef_A",
+ "sizes" : [ "*" ],
+ "type" : "double"
+ }
+ ],
+ "context" : "[n] -> { : -2147483648 <= n <= 2147483647 }",
+ "name" : "%for---%return",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_region_entry__TO__region_exit",
+ "schedule" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> [i0, 0] }"
+ },
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_body[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "read",
+ "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, 1] }"
+ }
+ ]
+}
Added: polly/trunk/test/Simplify/redundant_region_scalar.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_region_scalar.ll?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/redundant_region_scalar.ll (added)
+++ polly/trunk/test/Simplify/redundant_region_scalar.ll Tue Aug 1 13:01:34 2017
@@ -0,0 +1,53 @@
+; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-postfix=transformed -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
+;
+; Remove redundant store (a store that writes the same value already
+; at the destination) in a region.
+;
+define void @redundant_region_scalar(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 %bodyA, label %exit
+
+
+ bodyA:
+ %val1 = load double, double* %A
+ br label %region_entry
+
+ region_entry:
+ %val2 = load double, double* %A
+ %cmp = fcmp oeq double %val1, 0.0
+ br i1 %cmp, label %region_true, label %region_exit
+
+ region_true:
+ br label %region_exit
+
+ region_exit:
+ br label %bodyB
+
+ bodyB:
+ store double %val2, 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: Redundant writes removed: 3
+; CHECK: }
+
+; CHECK: After accesses {
+; CHECK-NEXT: }
Added: polly/trunk/test/Simplify/redundant_region_scalar___%for---%return.jscop
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_region_scalar___%25for---%25return.jscop?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/redundant_region_scalar___%for---%return.jscop (added)
+++ polly/trunk/test/Simplify/redundant_region_scalar___%for---%return.jscop Tue Aug 1 13:01:34 2017
@@ -0,0 +1,62 @@
+{
+ "arrays" : [
+ {
+ "name" : "MemRef_A",
+ "sizes" : [ "*" ],
+ "type" : "double"
+ }
+ ],
+ "context" : "[n] -> { : -2147483648 <= n <= 2147483647 }",
+ "name" : "%for---%return",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_bodyA[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_bodyA[i0] -> MemRef_val1[] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_bodyA[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_bodyA",
+ "schedule" : "[n] -> { Stmt_bodyA[i0] -> [i0, 0] }"
+ },
+ {
+ "accesses" : [
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_val1[] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_val2[] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_region_entry__TO__region_exit",
+ "schedule" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> [i0, 1] }"
+ },
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_bodyB[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_bodyB[i0] -> MemRef_val2[] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_bodyB[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_bodyB",
+ "schedule" : "[n] -> { Stmt_bodyB[i0] -> [i0, 2] }"
+ }
+ ]
+}
Added: polly/trunk/test/Simplify/redundant_region_scalar___%for---%return.jscop.transformed
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_region_scalar___%25for---%25return.jscop.transformed?rev=309734&view=auto
==============================================================================
--- polly/trunk/test/Simplify/redundant_region_scalar___%for---%return.jscop.transformed (added)
+++ polly/trunk/test/Simplify/redundant_region_scalar___%for---%return.jscop.transformed Tue Aug 1 13:01:34 2017
@@ -0,0 +1,62 @@
+{
+ "arrays" : [
+ {
+ "name" : "MemRef_A",
+ "sizes" : [ "*" ],
+ "type" : "double"
+ }
+ ],
+ "context" : "[n] -> { : -2147483648 <= n <= 2147483647 }",
+ "name" : "%for---%return",
+ "statements" : [
+ {
+ "accesses" : [
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_bodyA[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_bodyA[i0] -> MemRef_A[0] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_bodyA[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_bodyA",
+ "schedule" : "[n] -> { Stmt_bodyA[i0] -> [i0, 0] }"
+ },
+ {
+ "accesses" : [
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> MemRef_A[0] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_region_entry__TO__region_exit",
+ "schedule" : "[n] -> { Stmt_region_entry__TO__region_exit[i0] -> [i0, 1] }"
+ },
+ {
+ "accesses" : [
+ {
+ "kind" : "write",
+ "relation" : "[n] -> { Stmt_bodyB[i0] -> MemRef_A[0] }"
+ },
+ {
+ "kind" : "read",
+ "relation" : "[n] -> { Stmt_bodyB[i0] -> MemRef_A[0] }"
+ }
+ ],
+ "domain" : "[n] -> { Stmt_bodyB[i0] : 0 <= i0 < n }",
+ "name" : "Stmt_bodyB",
+ "schedule" : "[n] -> { Stmt_bodyB[i0] -> [i0, 2] }"
+ }
+ ]
+}
Modified: polly/trunk/test/Simplify/redundant_storebetween.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Simplify/redundant_storebetween.ll?rev=309734&r1=309733&r2=309734&view=diff
==============================================================================
--- polly/trunk/test/Simplify/redundant_storebetween.ll (original)
+++ polly/trunk/test/Simplify/redundant_storebetween.ll Tue Aug 1 13:01:34 2017
@@ -1,6 +1,4 @@
; RUN: opt %loadPolly -polly-simplify -analyze < %s | FileCheck %s -match-full-lines
-; RUN: opt %loadPolly -polly-simplify -disable-output -stats < %s 2>&1 | FileCheck %s --check-prefix=STATS -match-full-lines
-; REQUIRES: asserts
;
; Don't remove store where there is another store to the same target
; in-between them.
@@ -38,4 +36,3 @@ return:
; CHECK: SCoP could not be simplified
-; STATS: 1 polly-simplify - Number of Load-Store pairs NOT removed because there is another store between them
More information about the llvm-commits
mailing list