forked from OSchip/llvm-project
Handle read-only scalars used in PHI-nodes correctly
This change addresses three issues: - Read only scalars that enter a PHI node through an edge that comes from outside the scop are not modeled any more, as such PHI nodes will always be initialized to this initial value right before the SCoP is entered. - For PHI nodes that depend on a scalar value that is defined outside the scop, but where the scalar values is passed through an edge that itself comes from a BB that is part of the region, we introduce in this basic block a read of the out-of-scop value to ensure it's value is available to write it into the PHI alloc location. - Read only uses of scalars by PHI nodes are ignored in the general read only handling code, as they are taken care of by the general PHI node modeling code. llvm-svn: 248535
This commit is contained in:
parent
4405d5d889
commit
da95a4a7c7
|
@ -2707,6 +2707,8 @@ void ScopInfo::buildPHIAccesses(PHINode *PHI, Region &R,
|
|||
addMemoryAccess(OpIBB, OpI, MemoryAccess::MUST_WRITE, OpI, 1, true,
|
||||
OpI);
|
||||
}
|
||||
} else if (ModelReadOnlyScalars && !isa<Constant>(Op)) {
|
||||
addMemoryAccess(OpBB, PHI, MemoryAccess::READ, Op, 1, true, Op);
|
||||
}
|
||||
|
||||
// Always use the terminator of the incoming basic block as the access
|
||||
|
@ -2779,7 +2781,7 @@ bool ScopInfo::buildScalarDependences(Instruction *Inst, Region *R,
|
|||
addMemoryAccess(UseParent, UI, MemoryAccess::READ, Inst, 1, true, Inst);
|
||||
}
|
||||
|
||||
if (ModelReadOnlyScalars) {
|
||||
if (ModelReadOnlyScalars && !isa<PHINode>(Inst)) {
|
||||
for (Value *Op : Inst->operands()) {
|
||||
if (canSynthesize(Op, LI, SE, R))
|
||||
continue;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
; RUN: opt %loadPolly -polly-scops -analyze -polly-detect-unprofitable \
|
||||
; RUN: < %s | FileCheck %s
|
||||
;
|
||||
; float foo(float sum, float A[]) {
|
||||
;
|
||||
; for (long i = 0; i < 100; i++)
|
||||
; sum += A[i];
|
||||
;
|
||||
; return sum;
|
||||
; }
|
||||
|
||||
; Verify that we do not model the read from %sum. Reads that only happen in
|
||||
; case control flow reaches the PHI node from outside the SCoP are handled
|
||||
; implicitly during code generation.
|
||||
|
||||
; CHECK: Stmt_bb1[i0] -> MemRef_phisum__ph
|
||||
; CHECK-NOT: Stmt_bb1[i0] -> MemRef_sum[]
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define float @foo(float %sum, float* %A) {
|
||||
bb:
|
||||
br label %bb1
|
||||
|
||||
bb1:
|
||||
%i = phi i64 [ 0, %bb ], [ %i.next, %bb1 ]
|
||||
%phisum = phi float [ %sum, %bb ], [ %tmp5, %bb1 ]
|
||||
%tmp = getelementptr inbounds float, float* %A, i64 %i
|
||||
%tmp4 = load float, float* %tmp, align 4
|
||||
%tmp5 = fadd float %phisum, %tmp4
|
||||
%i.next = add nuw nsw i64 %i, 1
|
||||
%exitcond = icmp ne i64 %i, 100
|
||||
br i1 %exitcond, label %bb1, label %bb7
|
||||
|
||||
bb7:
|
||||
ret float %phisum
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
; RUN: opt %loadPolly -analyze -polly-scops -polly-detect-unprofitable \
|
||||
; RUN: < %s | FileCheck %s
|
||||
;
|
||||
; float foo(float sum, float A[]) {
|
||||
;
|
||||
; for (long i = 0; i < 100; i++)
|
||||
; sum += A[i];
|
||||
;
|
||||
; return sum;
|
||||
; }
|
||||
|
||||
; CHECK: Stmt_next
|
||||
; CHECK: Domain :=
|
||||
; CHECK: { Stmt_next[] };
|
||||
; CHECK: Schedule :=
|
||||
; CHECK: { Stmt_next[] -> [0, 0] };
|
||||
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
|
||||
; CHECK: { Stmt_next[] -> MemRef_sum[] };
|
||||
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
|
||||
; CHECK: { Stmt_next[] -> MemRef_phisum__phi[] };
|
||||
; CHECK: Stmt_bb1
|
||||
; CHECK: Domain :=
|
||||
; CHECK: { Stmt_bb1[i0] : i0 <= 100 and i0 >= 0 };
|
||||
; CHECK: Schedule :=
|
||||
; CHECK: { Stmt_bb1[i0] -> [1, i0] };
|
||||
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
|
||||
; CHECK: { Stmt_bb1[i0] -> MemRef_phisum__phi[] };
|
||||
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
|
||||
; CHECK: { Stmt_bb1[i0] -> MemRef_phisum__phi[] };
|
||||
; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
|
||||
; CHECK: { Stmt_bb1[i0] -> MemRef_phisum[] };
|
||||
; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 0]
|
||||
; CHECK: { Stmt_bb1[i0] -> MemRef_A[i0] };
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
|
||||
define float @foo(float %sum, float* %A) {
|
||||
bb:
|
||||
br label %next
|
||||
|
||||
next:
|
||||
br i1 true, label %bb1, label %bb7
|
||||
|
||||
bb1:
|
||||
%i = phi i64 [ 0, %next ], [ %i.next, %bb1 ]
|
||||
%phisum = phi float [ %sum, %next ], [ %tmp5, %bb1 ]
|
||||
%tmp = getelementptr inbounds float, float* %A, i64 %i
|
||||
%tmp4 = load float, float* %tmp, align 4
|
||||
%tmp5 = fadd float %phisum, %tmp4
|
||||
%i.next = add nuw nsw i64 %i, 1
|
||||
%exitcond = icmp ne i64 %i, 100
|
||||
br i1 %exitcond, label %bb1, label %bb7
|
||||
|
||||
bb7:
|
||||
ret float %phisum
|
||||
}
|
Loading…
Reference in New Issue