Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -829,6 +829,10 @@ /// @brief Mapping from instructions to (scalar) memory accesses. DenseMap InstructionToAccess; + /// @brief The set of values defined in this ScopStmt that are required + /// elsewhere, mapped to their MK_Value WRITE MemoryAccesses. + DenseMap ValueWrites; + //@} /// @brief A SCoP statement represents either a basic block (affine/precise @@ -987,6 +991,14 @@ return It->getSecond()->empty() ? nullptr : It->getSecond()->front(); } + /// @brief Return the MemoryAccess that writes the value of an instruction + /// defined in this statement, or nullptr if not (yet) added. + MemoryAccess *lookupValueWriteOf(Instruction *Inst) const { + assert((isRegionStmt() && R->contains(Inst)) || + (!isRegionStmt() && Inst->getParent() == BB)); + return ValueWrites.lookup(Inst); + } + void setBasicBlock(BasicBlock *Block) { // TODO: Handle the case where the statement is a region statement, thus // the entry block was split and needs to be changed in the region R. @@ -1907,7 +1919,7 @@ /// @param Value The value to be written. /// @see addValueReadAccess() /// @see ScopArrayInfo::MemoryKind - void addValueWriteAccess(Instruction *Value); + void ensureValueStore(Instruction *Value); /// @brief Create a MemoryAccess for reloading an llvm::Value. /// Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -904,6 +904,12 @@ if (!MAL) MAL = new MemoryAccessList(); MAL->emplace_front(Access); + } else if (Access->isValueKind() && Access->isWrite()) { + Instruction *AccessVal = cast(Access->getAccessValue()); + assert(Parent.getStmtForBasicBlock(AccessVal->getParent()) == this); + assert(!ValueWrites.lookup(cast(AccessVal))); + + ValueWrites[AccessVal] = Access; } MemAccs.push_back(Access); @@ -3546,7 +3552,7 @@ if (scop->getStmtForBasicBlock(OpIBB) != scop->getStmtForBasicBlock(OpBB)) { addValueReadAccess(OpI, PHI, OpBB); - addValueWriteAccess(OpI); + ensureValueStore(OpI); } } else if (ModelReadOnlyScalars && !isa(Op)) { addValueReadAccess(Op, PHI, OpBB); @@ -3865,7 +3871,7 @@ if (buildScalarDependences(Inst, &R, NonAffineSubRegion)) { if (!isa(Inst)) - addValueWriteAccess(Inst); + ensureValueStore(Inst); } } } @@ -3923,11 +3929,23 @@ ElemBytes, IsAffine, AccessValue, Subscripts, Sizes, ScopArrayInfo::MK_Array); } -void ScopInfo::addValueWriteAccess(Instruction *Value) { + +void ScopInfo::ensureValueStore(Instruction *Value) { + ScopStmt *Stmt = scop->getStmtForBasicBlock(Value->getParent()); + + // Value not defined within this SCoP. + if (!Stmt) + return; + + // Do not process further if the value is already written. + if (Stmt->lookupValueWriteOf(Value)) + return; + addMemoryAccess(Value->getParent(), Value, MemoryAccess::MUST_WRITE, Value, 1, true, Value, ArrayRef(), ArrayRef(), ScopArrayInfo::MK_Value); } + void ScopInfo::addValueReadAccess(Value *Value, Instruction *User) { assert(!isa(User)); addMemoryAccess(User->getParent(), User, MemoryAccess::READ, Value, 1, true, Index: test/ScopInfo/phi_scalar_simple_1.ll =================================================================== --- test/ScopInfo/phi_scalar_simple_1.ll +++ test/ScopInfo/phi_scalar_simple_1.ll @@ -29,9 +29,6 @@ ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK: [N] -> { Stmt_for_cond[i0] -> MemRef_x_addr_0[] }; ; CHECK-NOT: Access -; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: [N] -> { Stmt_for_cond[i0] -> MemRef_x_addr_0[] }; -; CHECK-NOT: Access %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc4 ], [ 1, %entry ] %x.addr.0 = phi i32 [ %x, %entry ], [ %x.addr.1.lcssa, %for.inc4 ] %cmp = icmp slt i64 %indvars.iv, %tmp Index: test/ScopInfo/phi_scalar_simple_2.ll =================================================================== --- test/ScopInfo/phi_scalar_simple_2.ll +++ test/ScopInfo/phi_scalar_simple_2.ll @@ -28,9 +28,6 @@ ; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK: [N, c] -> { Stmt_for_cond[i0] -> MemRef_A[i0] }; ; CHECK-NOT: Access -; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: [N, c] -> { Stmt_for_cond[i0] -> MemRef_x_addr_0[] }; -; CHECK-NOT: Access %indvars.iv = phi i64 [ %indvars.iv.next, %for.inc5 ], [ 0, %entry ] %x.addr.0 = phi i32 [ %x, %entry ], [ %x.addr.1, %for.inc5 ] %arrayidx2 = getelementptr inbounds i32, i32* %A, i64 %indvars.iv @@ -58,12 +55,6 @@ ; CHECK: ReadAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK: [N, c] -> { Stmt_for_cond1[i0, i1] -> MemRef_x_addr_1__phi[] }; ; CHECK-NOT: Access -; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: [N, c] -> { Stmt_for_cond1[i0, i1] -> MemRef_x_addr_1[] }; -; CHECK-NOT: Access -; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK: [N, c] -> { Stmt_for_cond1[i0, i1] -> MemRef_x_addr_1[] }; -; CHECK-NOT: Access %x.addr.1 = phi i32 [ %x.addr.0, %for.body ], [ %x.addr.2, %for.inc ] %j.0 = phi i32 [ 0, %for.body ], [ %inc, %for.inc ] %exitcond = icmp ne i32 %j.0, %N