[polly] r310311 - [ZoneAlgo] Allow two writes that write identical values into same array slot
Tobias Grosser via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 7 15:01:29 PDT 2017
Author: grosser
Date: Mon Aug 7 15:01:29 2017
New Revision: 310311
URL: http://llvm.org/viewvc/llvm-project?rev=310311&view=rev
Log:
[ZoneAlgo] Allow two writes that write identical values into same array slot
Two write statements which write into the very same array slot generally are
conflicting. However, in case the value that is written is identical, this
does not cause any problem. Hence, allow such write pairs in this specific
situation.
Added:
polly/trunk/test/ForwardOpTree/forward_load_double_write.ll
Modified:
polly/trunk/lib/Transform/ZoneAlgo.cpp
Modified: polly/trunk/lib/Transform/ZoneAlgo.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/Transform/ZoneAlgo.cpp?rev=310311&r1=310310&r2=310311&view=diff
==============================================================================
--- polly/trunk/lib/Transform/ZoneAlgo.cpp (original)
+++ polly/trunk/lib/Transform/ZoneAlgo.cpp Mon Aug 7 15:01:29 2017
@@ -284,6 +284,29 @@ ZoneAlgorithm::ZoneAlgorithm(const char
ScatterSpace = getScatterSpace(Schedule);
}
+/// Check if all stores in @p Stmt store the very same value.
+///
+/// TODO: In the future we may want to extent this to make the checks
+/// specific to different memory locations.
+static bool onlySameValueWrites(ScopStmt *Stmt) {
+ Value *V = nullptr;
+
+ for (auto *MA : *Stmt) {
+ if (!MA->isLatestArrayKind() || !MA->isMustWrite() ||
+ !MA->isOriginalArrayKind())
+ continue;
+
+ if (!V) {
+ V = MA->getAccessValue();
+ continue;
+ }
+
+ if (V != MA->getAccessValue())
+ return false;
+ }
+ return true;
+}
+
bool ZoneAlgorithm::isCompatibleStmt(ScopStmt *Stmt) {
auto Stores = makeEmptyUnionMap();
auto Loads = makeEmptyUnionMap();
@@ -338,11 +361,13 @@ bool ZoneAlgorithm::isCompatibleStmt(Sco
if (!isl_union_map_is_disjoint(Stores.keep(), AccRel.keep())) {
OptimizationRemarkMissed R(PassName, "StoreAfterStore",
MA->getAccessInstruction());
- R << "store after store of same element in same statement";
- R << " (previous stores: " << Stores;
- R << ", storing: " << AccRel << ")";
- S->getFunction().getContext().diagnose(R);
- return false;
+ if (!onlySameValueWrites(Stmt)) {
+ R << "store after store of same element in same statement";
+ R << " (previous stores: " << Stores;
+ R << ", storing: " << AccRel << ")";
+ S->getFunction().getContext().diagnose(R);
+ return false;
+ }
}
Stores = give(isl_union_map_union(Stores.take(), AccRel.take()));
Added: polly/trunk/test/ForwardOpTree/forward_load_double_write.ll
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/ForwardOpTree/forward_load_double_write.ll?rev=310311&view=auto
==============================================================================
--- polly/trunk/test/ForwardOpTree/forward_load_double_write.ll (added)
+++ polly/trunk/test/ForwardOpTree/forward_load_double_write.ll Mon Aug 7 15:01:29 2017
@@ -0,0 +1,56 @@
+; RUN: opt %loadPolly -polly-optree -analyze < %s | FileCheck %s -match-full-lines
+;
+; Rematerialize a load even in case two writes of identical values are in
+; one scop statement.
+;
+define void @func(i32 %n, double* noalias nonnull %A, double* noalias nonnull %B) {
+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:
+ %B_idx = getelementptr inbounds double, double* %B, i32 %j
+ %val = load double, double* %B_idx
+ br label %bodyB
+
+ bodyB:
+ %A_idx = getelementptr inbounds double, double* %A, i32 %j
+ store double %val, double* %A_idx
+ store double %val, double* %A_idx
+ 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: Known loads forwarded: 1
+; CHECK: Operand trees forwarded: 1
+; CHECK: Statements with forwarded operand trees: 1
+; CHECK: }
+
+; CHECK: Stmt_bodyB
+; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT: null;
+; CHECK-NEXT: new: [n] -> { Stmt_bodyB[i0] -> MemRef_B[i0] };
+; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
+; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
+; CHECK-NEXT: [n] -> { Stmt_bodyB[i0] -> MemRef_A[i0] };
+; CHECK-NEXT: Instructions {
+; CHECK-NEXT: %val = load double, double* %B_idx
+; CHECK-NEXT: store double %val, double* %A_idx
+; CHECK-NEXT: store double %val, double* %A_idx
+; CHECK-NEXT: }
More information about the llvm-commits
mailing list