Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -1903,14 +1903,15 @@ /// @brief Analyze and extract the cross-BB scalar dependences (or, /// dataflow dependencies) of an instruction. /// - /// @param Inst The instruction to be analyzed - /// @param R The SCoP region - /// @param NonAffineSubRegion The non affine sub-region @p Inst is in. + /// @param Inst The instruction to be analyzed. + void buildScalarDependences(Instruction *Inst); + + /// @brief Search for uses of the llvm::Value defined by @p Inst that are not + /// within the SCoP. If there is such use, add a SCALAR WRITE such that + /// it is available after the SCoP as escaping value. /// - /// @return True if the Instruction is used in other BB and a scalar write - /// Access is required. - bool buildScalarDependences(Instruction *Inst, Region *R, - Region *NonAffineSubRegio); + /// @param Inst The instruction to be analyzed. + void buildEscapingDependences(Instruction *Inst); /// @brief Create MemoryAccesses for the given PHI node in the given region. /// Index: include/polly/Support/ScopHelper.h =================================================================== --- include/polly/Support/ScopHelper.h +++ include/polly/Support/ScopHelper.h @@ -312,5 +312,14 @@ /// otherwise return false. bool canSynthesize(const llvm::Value *V, const llvm::LoopInfo *LI, llvm::ScalarEvolution *SE, const llvm::Region *R); + +/// @brief Return the block in which a value is used. +/// +/// For normal instructions, this is the instruction's parent block. For PHI +/// nodes, this is the incoming block of that use, because this is where the +/// operand must be defined (i.e. its definition dominates this block). +/// Non-instructions do not use operands at a specific point such that in this +/// case this function returns nullptr. +llvm::BasicBlock *getUseBlock(llvm::Use &U); } #endif Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -3562,25 +3562,6 @@ continue; OnlyNonAffineSubRegionOperands = false; - - if (!R.contains(OpBB)) - continue; - - Instruction *OpI = dyn_cast(Op); - if (OpI) { - BasicBlock *OpIBB = OpI->getParent(); - // As we pretend there is a use (or more precise a write) of OpI in OpBB - // we have to insert a scalar dependence from the definition of OpI to - // OpBB if the definition is not in OpBB. - if (scop->getStmtForBasicBlock(OpIBB) != - scop->getStmtForBasicBlock(OpBB)) { - ensureValueRead(OpI, OpBB); - ensureValueWrite(OpI); - } - } else if (ModelReadOnlyScalars && !isa(Op)) { - ensureValueRead(Op, OpBB); - } - ensurePHIWrite(PHI, OpBB, Op, IsExitBlock); } @@ -3589,115 +3570,41 @@ } } -bool ScopInfo::buildScalarDependences(Instruction *Inst, Region *R, - Region *NonAffineSubRegion) { - bool canSynthesizeInst = canSynthesize(Inst, LI, SE, R); - if (isIgnoredIntrinsic(Inst)) - return false; - - bool AnyCrossStmtUse = false; - BasicBlock *ParentBB = Inst->getParent(); - - for (User *U : Inst->users()) { - Instruction *UI = dyn_cast(U); - - // Ignore the strange user - if (UI == 0) - continue; - - BasicBlock *UseParent = UI->getParent(); - - // Ignore basic block local uses. A value that is defined in a scop, but - // used in a PHI node in the same basic block does not count as basic block - // local, as for such cases a control flow edge is passed between definition - // and use. - if (UseParent == ParentBB && !isa(UI)) - continue; - - // Uses by PHI nodes in the entry node count as external uses in case the - // use is through an incoming block that is itself not contained in the - // region. - if (R->getEntry() == UseParent) { - if (auto *PHI = dyn_cast(UI)) { - bool ExternalUse = false; - for (unsigned i = 0; i < PHI->getNumIncomingValues(); i++) { - if (PHI->getIncomingValue(i) == Inst && - !R->contains(PHI->getIncomingBlock(i))) { - ExternalUse = true; - break; - } - } - - if (ExternalUse) { - AnyCrossStmtUse = true; - continue; - } - } - } - - // Do not build scalar dependences inside a non-affine subregion. - if (NonAffineSubRegion && NonAffineSubRegion->contains(UseParent)) - continue; - - // Check for PHI nodes in the region exit and skip them, if they will be - // modeled as PHI nodes. - // - // PHI nodes in the region exit that have more than two incoming edges need - // to be modeled as PHI-Nodes to correctly model the fact that depending on - // the control flow a different value will be assigned to the PHI node. In - // case this is the case, there is no need to create an additional normal - // scalar dependence. Hence, bail out before we register an "out-of-region" - // use for this definition. - if (isa(UI) && UI->getParent() == R->getExit() && - !R->getExitingBlock()) - continue; - - // Check whether or not the use is in the SCoP. - if (!R->contains(UseParent)) { - AnyCrossStmtUse = true; - continue; - } +void ScopInfo::buildScalarDependences(Instruction *Inst) { + assert(!isa(Inst)); - // If the instruction can be synthesized and the user is in the region - // we do not need to add scalar dependences. - if (canSynthesizeInst) - continue; + // Pull-in required operands. + for (Use &Op : Inst->operands()) + ensureValueRead(Op.get(), Inst->getParent()); +} - // No need to translate these scalar dependences into polyhedral form, - // because synthesizable scalars can be generated by the code generator. - if (canSynthesize(UI, LI, SE, R)) - continue; +void ScopInfo::buildEscapingDependences(Instruction *Inst) { + Region *R = &scop->getRegion(); - // Skip PHI nodes in the region as they handle their operands on their own. - if (isa(UI)) + // Check for uses of this instruction outside the scop. Because we do not + // iterate over such instructions and therefore did not "ensure" the existence + // of a write, we must determine such use here. + for (Use &U : Inst->uses()) { + Instruction *UI = dyn_cast(U.getUser()); + if (!UI) continue; - // Now U is used in another statement. - AnyCrossStmtUse = true; - - // Do not build a read access that is not in the current SCoP - // Use the def instruction as base address of the MemoryAccess, so that it - // will become the name of the scalar access in the polyhedral form. - ensureValueRead(Inst, UI->getParent()); - } - - if (ModelReadOnlyScalars && !isa(Inst)) { - for (Value *Op : Inst->operands()) { - if (canSynthesize(Op, LI, SE, R)) - continue; - - if (Instruction *OpInst = dyn_cast(Op)) - if (R->contains(OpInst)) - continue; - - if (isa(Op)) - continue; - - ensureValueRead(Op, Inst->getParent()); + BasicBlock *UseParent = getUseBlock(U); + BasicBlock *UserParent = UI->getParent(); + + // An escaping value is either used by an instruction not within the scop, + // or (when the scop region's exit needs to be simplified) by a PHI in the + // scop's exit block. This is because region simplification before code + // generation inserts new basic blocks before the PHI such that its incoming + // blocks are not in the scop anymore. + if (!R->contains(UseParent) || + (isa(UI) && UserParent == R->getExit() && + R->getExitingBlock())) { + // At least one escaping use found. + ensureValueWrite(Inst); + break; } } - - return AnyCrossStmtUse; } extern MapInsnToMemAcc InsnToMemAcc; @@ -3854,10 +3761,8 @@ // The set of loads that are required to be invariant. auto &ScopRIL = *SD->getRequiredInvariantLoads(&R); - for (BasicBlock::iterator I = BB.begin(), E = --BB.end(); I != E; ++I) { - Instruction *Inst = &*I; - - PHINode *PHI = dyn_cast(Inst); + for (Instruction &Inst : BB) { + PHINode *PHI = dyn_cast(&Inst); if (PHI) buildPHIAccesses(PHI, R, NonAffineSubRegion, IsExitBlock); @@ -3872,18 +3777,18 @@ if (auto MemInst = MemAccInst::dyn_cast(Inst)) buildMemoryAccess(MemInst, L, &R, BoxedLoops, ScopRIL); - if (isIgnoredIntrinsic(Inst)) + if (isIgnoredIntrinsic(&Inst)) continue; // Do not build scalar dependences for required invariant loads as we will // hoist them later on anyway or drop the SCoP if we cannot. - if (ScopRIL.count(dyn_cast(Inst))) + if (ScopRIL.count(dyn_cast(&Inst))) continue; - if (buildScalarDependences(Inst, &R, NonAffineSubRegion)) { - if (!isa(Inst)) - ensureValueWrite(Inst); - } + if (!PHI) + buildScalarDependences(&Inst); + if (!IsExitBlock) + buildEscapingDependences(&Inst); } } @@ -3963,18 +3868,37 @@ } void ScopInfo::ensureValueRead(Value *Value, BasicBlock *UserBB) { + // There cannot be an "access" for constants. + if (isa(Value) || isa(Value)) + return; + // If the instruction can be synthesized and the user is in the region we do // not need to add a value dependences. Region &ScopRegion = scop->getRegion(); if (canSynthesize(Value, LI, SE, &ScopRegion)) return; + // Determine the ScopStmt containing the value's definition and use. There is + // no defining ScopStmt if the value is a function argument, a global value, + // or defined outside the SCoP. + Instruction *ValueInst = dyn_cast(Value); + ScopStmt *ValueStmt = + ValueInst ? scop->getStmtForBasicBlock(ValueInst->getParent()) : nullptr; + ScopStmt *UserStmt = scop->getStmtForBasicBlock(UserBB); // We do not model uses outside the scop. if (!UserStmt) return; + // Add MemoryAccess for invariant values only if requested. + if (!ModelReadOnlyScalars && !ValueStmt) + return; + + // Ignore use-def chains within the same ScopStmt. + if (ValueStmt == UserStmt) + return; + // Do not create another MemoryAccess for reloading the value if one already // exists. if (UserStmt->lookupValueReadOf(Value)) @@ -3983,10 +3907,21 @@ addMemoryAccess(UserBB, nullptr, MemoryAccess::READ, Value, 1, true, Value, ArrayRef(), ArrayRef(), ScopArrayInfo::MK_Value); + if (ValueInst) + ensureValueWrite(ValueInst); } void ScopInfo::ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock, Value *IncomingValue, bool IsExitBlock) { ScopStmt *IncomingStmt = scop->getStmtForBasicBlock(IncomingBlock); + if (!IncomingStmt) + return; + + // Take care for the incoming value being available in the incoming block. + // This must be done before the check for multiple PHI writes because multiple + // exiting edges from subregion each can be the effective written value of the + // subregion. As such, all of them must be made available in the subregion + // statement. + ensureValueRead(IncomingValue, IncomingBlock); // Do not add more than one MemoryAccess per PHINode and ScopStmt. if (MemoryAccess *Acc = IncomingStmt->lookupPHIWriteOf(PHI)) { Index: lib/Support/ScopHelper.cpp =================================================================== --- lib/Support/ScopHelper.cpp +++ lib/Support/ScopHelper.cpp @@ -442,3 +442,14 @@ return false; } + +llvm::BasicBlock *polly::getUseBlock(llvm::Use &U) { + Instruction *UI = dyn_cast(U.getUser()); + if (!UI) + return nullptr; + + if (PHINode *PHI = dyn_cast(UI)) + return PHI->getIncomingBlock(U); + + return UI->getParent(); +} Index: test/Isl/CodeGen/MemAccess/update_access_functions.ll =================================================================== --- test/Isl/CodeGen/MemAccess/update_access_functions.ll +++ test/Isl/CodeGen/MemAccess/update_access_functions.ll @@ -8,8 +8,8 @@ ; CHECK: polly.stmt.loop3: ; CHECK-NEXT: %val.s2a.reload = load double, double* %val.s2a -; CHECK-NEXT: %polly.access.A20 = getelementptr double, double* %A, i64 42 -; CHECK-NEXT: store double %val.s2a.reload, double* %polly.access.A20 +; CHECK-NEXT: %scevgep[[R21:[0-9]*]] = getelementptr double, double* %scevgep{{[0-9]*}}, i64 %polly.indvar16 +; CHECK-NEXT: store double %val.s2a.reload, double* %scevgep[[R21]] target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopInfo/invariant-loads-leave-read-only-statements.ll =================================================================== --- test/ScopInfo/invariant-loads-leave-read-only-statements.ll +++ test/ScopInfo/invariant-loads-leave-read-only-statements.ll @@ -8,24 +8,36 @@ ; CHECK-NEXT: Schedule := ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_top_split[] -> [0, 0, 0, 0] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_top_split[] -> MemRef_25[] }; -; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_top_split[] -> MemRef_26[] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_top_split[] -> MemRef_25[] }; ; CHECK-NEXT: Stmt_L_4 ; CHECK-NEXT: Domain := ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] : 0 <= i0 < p_0 and 0 <= i1 < p_0 and 0 <= i2 < p_0 }; ; CHECK-NEXT: Schedule := ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> [1, i0, i1, i2] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_25[] }; +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_22[] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_19[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_19[i1, i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_8[] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_5[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_5[i2, i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_15[] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_12[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_12[i2, i1] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_19[i1, i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [p_0, p_1, p_2] -> { Stmt_L_4[i0, i1, i2] -> MemRef_25[] }; ; CHECK-NEXT: } target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopInfo/long-sequence-of-error-blocks.ll =================================================================== --- test/ScopInfo/long-sequence-of-error-blocks.ll +++ test/ScopInfo/long-sequence-of-error-blocks.ll @@ -28,6 +28,8 @@ ; CHECK-NEXT: [tmp17, tmp21, tmp27, tmp31] -> { Stmt_bb19[] : tmp17 < 0 or tmp17 > 0 }; ; CHECK-NEXT: Schedule := ; CHECK-NEXT: [tmp17, tmp21, tmp27, tmp31] -> { Stmt_bb19[] -> [1] : tmp17 < 0 or tmp17 > 0 }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [tmp17, tmp21, tmp27, tmp31] -> { Stmt_bb19[] -> MemRef_tmp[] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [tmp17, tmp21, tmp27, tmp31] -> { Stmt_bb19[] -> MemRef_A[0] }; ; CHECK-NEXT: Stmt_bb24 @@ -42,6 +44,8 @@ ; CHECK-NEXT: [tmp17, tmp21, tmp27, tmp31] -> { Stmt_bb29[] : tmp27 = 3 }; ; CHECK-NEXT: Schedule := ; CHECK-NEXT: [tmp17, tmp21, tmp27, tmp31] -> { Stmt_bb29[] -> [3] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [tmp17, tmp21, tmp27, tmp31] -> { Stmt_bb29[] -> MemRef_tmp25[] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [tmp17, tmp21, tmp27, tmp31] -> { Stmt_bb29[] -> MemRef_A[0] }; ; CHECK-NEXT: } Index: test/ScopInfo/many-scalar-dependences.ll =================================================================== --- test/ScopInfo/many-scalar-dependences.ll +++ test/ScopInfo/many-scalar-dependences.ll @@ -92,12 +92,12 @@ ; CHECK-NEXT: { Stmt_bb12[i0, i1, i2] -> [i0, 2, i1, 2, i2, 3] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: { Stmt_bb12[i0, i1, i2] -> MemRef_x_3__phi[] }; -; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: { Stmt_bb12[i0, i1, i2] -> MemRef_x_3[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: { Stmt_bb12[i0, i1, i2] -> MemRef_a[i0, i1] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: { Stmt_bb12[i0, i1, i2] -> MemRef_a[i0, i1] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: { Stmt_bb12[i0, i1, i2] -> MemRef_x_3[] }; ; CHECK-NEXT: Stmt_bb16 ; CHECK-NEXT: Domain := ; CHECK-NEXT: { Stmt_bb16[i0, i1, i2] : 0 <= i0 <= 99 and 0 <= i1 <= 99 and 0 <= i2 <= 99 }; Index: test/ScopInfo/multidim_fortran_srem.ll =================================================================== --- test/ScopInfo/multidim_fortran_srem.ll +++ test/ScopInfo/multidim_fortran_srem.ll @@ -18,10 +18,10 @@ ; CHECK-NEXT: [tmp180, tmp177, tmp183, tmp162, tmp157, tmp150, tmp146, tmp140, tmp] -> { Stmt_bb203[i0, i1, i2] -> [i0, 1, i1, i2] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: [tmp180, tmp177, tmp183, tmp162, tmp157, tmp150, tmp146, tmp140, tmp] -> { Stmt_bb203[i0, i1, i2] -> MemRef_tmp192[] }; -; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [tmp180, tmp177, tmp183, tmp162, tmp157, tmp150, tmp146, tmp140, tmp] -> { Stmt_bb203[i0, i1, i2] -> MemRef_tmp194[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [tmp180, tmp177, tmp183, tmp162, tmp157, tmp150, tmp146, tmp140, tmp] -> { Stmt_bb203[i0, i1, i2] -> MemRef_tmp173[o0, 1 + i1, 1 + i2] : 3*floor((-i0 + o0)/3) = -i0 + o0 and 0 <= o0 <= 2 }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [tmp180, tmp177, tmp183, tmp162, tmp157, tmp150, tmp146, tmp140, tmp] -> { Stmt_bb203[i0, i1, i2] -> MemRef_tmp194[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [tmp180, tmp177, tmp183, tmp162, tmp157, tmp150, tmp146, tmp140, tmp] -> { Stmt_bb203[i0, i1, i2] -> MemRef_tmp173[o0, 1 + i1, 1 + i2] : 3*floor((-2 - i0 + o0)/3) = -2 - i0 + o0 and 0 <= o0 <= 2 }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] Index: test/ScopInfo/non_affine_region_4.ll =================================================================== --- test/ScopInfo/non_affine_region_4.ll +++ test/ScopInfo/non_affine_region_4.ll @@ -16,14 +16,14 @@ ; ; CHECK: Arrays { ; CHECK-NEXT: i32 MemRef_A[*]; // Element size 4 -; CHECK-NEXT: i32 MemRef_x; [BasePtrOrigin: MemRef_A] // Element size 4 ; CHECK-NEXT: i32 MemRef_y__phi; // Element size 4 +; CHECK-NEXT: i32 MemRef_x; [BasePtrOrigin: MemRef_A] // Element size 4 ; CHECK-NEXT: } ; ; CHECK: Arrays (Bounds as pw_affs) { ; CHECK-NEXT: i32 MemRef_A[*]; // Element size 4 -; CHECK-NEXT: i32 MemRef_x; [BasePtrOrigin: MemRef_A] // Element size 4 ; CHECK-NEXT: i32 MemRef_y__phi; // Element size 4 +; CHECK-NEXT: i32 MemRef_x; [BasePtrOrigin: MemRef_A] // Element size 4 ; CHECK-NEXT: } ; ; CHECK: Statements { @@ -35,18 +35,18 @@ ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: { Stmt_bb2__TO__bb7[i0] -> MemRef_A[i0] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: { Stmt_bb2__TO__bb7[i0] -> MemRef_x[] }; -; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: { Stmt_bb2__TO__bb7[i0] -> MemRef_y__phi[] }; +; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: { Stmt_bb2__TO__bb7[i0] -> MemRef_x[] }; ; CHECK-NEXT: Stmt_bb7 ; CHECK-NEXT: Domain := ; CHECK-NEXT: { Stmt_bb7[i0] : 0 <= i0 <= 1023 }; ; CHECK-NEXT: Schedule := ; CHECK-NEXT: { Stmt_bb7[i0] -> [i0, 1] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: { Stmt_bb7[i0] -> MemRef_x[] }; -; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: { Stmt_bb7[i0] -> MemRef_y__phi[] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: { Stmt_bb7[i0] -> MemRef_x[] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: { Stmt_bb7[i0] -> MemRef_A[i0] }; ; CHECK-NEXT: } Index: test/ScopInfo/phi_condition_modeling_2.ll =================================================================== --- test/ScopInfo/phi_condition_modeling_2.ll +++ test/ScopInfo/phi_condition_modeling_2.ll @@ -40,10 +40,10 @@ ; CHECK-NEXT: [N, c] -> { Stmt_bb8b[i0] : 0 <= i0 < N }; ; CHECK-NEXT: Schedule := ; CHECK-NEXT: [N, c] -> { Stmt_bb8b[i0] -> [i0, 3] }; -; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [N, c] -> { Stmt_bb8b[i0] -> MemRef_tmp_0[] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [N, c] -> { Stmt_bb8b[i0] -> MemRef_A[i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [N, c] -> { Stmt_bb8b[i0] -> MemRef_tmp_0[] }; ; CHECK-NEXT: } target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopInfo/phi_loop_carried_float.ll =================================================================== --- test/ScopInfo/phi_loop_carried_float.ll +++ test/ScopInfo/phi_loop_carried_float.ll @@ -23,10 +23,10 @@ ; CHECK-NEXT: [N] -> { Stmt_bb4[i0] -> [i0, 1] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: [N] -> { Stmt_bb4[i0] -> MemRef_tmp_0__phi[] }; -; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [N] -> { Stmt_bb4[i0] -> MemRef_tmp_0[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [N] -> { Stmt_bb4[i0] -> MemRef_A[i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [N] -> { Stmt_bb4[i0] -> MemRef_tmp_0[] }; ; CHECK-NEXT: } target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" Index: test/ScopInfo/phi_scalar_simple_1.ll =================================================================== --- test/ScopInfo/phi_scalar_simple_1.ll +++ test/ScopInfo/phi_scalar_simple_1.ll @@ -51,10 +51,10 @@ ; CHECK-NEXT: [N] -> { Stmt_for_inc[i0, i1] -> [i0, 2, i1, 1] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: [N] -> { Stmt_for_inc[i0, i1] -> MemRef_x_addr_1__phi[] }; -; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [N] -> { Stmt_for_inc[i0, i1] -> MemRef_x_addr_1[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [N] -> { Stmt_for_inc[i0, i1] -> MemRef_A[1 + i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [N] -> { Stmt_for_inc[i0, i1] -> MemRef_x_addr_1[] }; ; CHECK-NEXT: Stmt_for_end ; CHECK-NEXT: Domain := ; CHECK-NEXT: [N] -> { Stmt_for_end[i0] : N >= 3 and 0 <= i0 <= -2 + N }; Index: test/ScopInfo/phi_scalar_simple_2.ll =================================================================== --- test/ScopInfo/phi_scalar_simple_2.ll +++ test/ScopInfo/phi_scalar_simple_2.ll @@ -52,10 +52,10 @@ ; CHECK-NEXT: [N, c] -> { Stmt_if_then[i0, i1] : 0 <= i0 < c and i0 < N and 0 <= i1 < N }; ; CHECK-NEXT: Schedule := ; CHECK-NEXT: [N, c] -> { Stmt_if_then[i0, i1] -> [i0, 2, i1, 2] }; -; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [N, c] -> { Stmt_if_then[i0, i1] -> MemRef_x_addr_1[] }; ; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [N, c] -> { Stmt_if_then[i0, i1] -> MemRef_A[i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [N, c] -> { Stmt_if_then[i0, i1] -> MemRef_x_addr_1[] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1] ; CHECK-NEXT: [N, c] -> { Stmt_if_then[i0, i1] -> MemRef_x_addr_2__phi[] }; ; CHECK-NEXT: Stmt_if_end Index: test/ScopInfo/scalar.ll =================================================================== --- test/ScopInfo/scalar.ll +++ test/ScopInfo/scalar.ll @@ -55,8 +55,8 @@ ; CHECK-NEXT: [N] -> { Stmt_S2[i0] : 0 <= i0 < N }; ; CHECK-NEXT: Schedule := ; CHECK-NEXT: [N] -> { Stmt_S2[i0] -> [i0, 1] }; -; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [N] -> { Stmt_S2[i0] -> MemRef_val[] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [N] -> { Stmt_S2[i0] -> MemRef_a[i0] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [N] -> { Stmt_S2[i0] -> MemRef_val[] }; ; CHECK-NEXT: } Index: test/ScopInfo/tempscop-printing.ll =================================================================== --- test/ScopInfo/tempscop-printing.ll +++ test/ScopInfo/tempscop-printing.ll @@ -33,10 +33,10 @@ ; CHECK-NEXT: [N] -> { Stmt_for_j[i0, i1] : 0 <= i0 < N and 0 <= i1 < N }; ; CHECK-NEXT: Schedule := ; CHECK-NEXT: [N] -> { Stmt_for_j[i0, i1] -> [i0, i1] }; -; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] -; CHECK-NEXT: [N] -> { Stmt_for_j[i0, i1] -> MemRef_init[] }; ; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] ; CHECK-NEXT: [N] -> { Stmt_for_j[i0, i1] -> MemRef_A[i1] }; +; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1] +; CHECK-NEXT: [N] -> { Stmt_for_j[i0, i1] -> MemRef_init[] }; ; CHECK-NEXT: } target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"