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:
Tobias Grosser 2015-09-24 20:59:59 +00:00
parent 4405d5d889
commit da95a4a7c7
3 changed files with 96 additions and 1 deletions

View File

@ -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;

View File

@ -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
}

View File

@ -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
}