forked from OSchip/llvm-project
[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. llvm-svn: 310311
This commit is contained in:
parent
bd57cea6e4
commit
2ef378120d
|
@ -284,6 +284,29 @@ ZoneAlgorithm::ZoneAlgorithm(const char *PassName, Scop *S, LoopInfo *LI)
|
|||
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(ScopStmt *Stmt) {
|
|||
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()));
|
||||
|
|
|
@ -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: }
|
Loading…
Reference in New Issue