Index: lib/Analysis/ScopBuilder.cpp =================================================================== --- lib/Analysis/ScopBuilder.cpp +++ lib/Analysis/ScopBuilder.cpp @@ -626,6 +626,12 @@ if (!isa(&Inst) && !isIgnoredIntrinsic(&Inst) && !canSynthesize(&Inst, *scop, &SE, L)) Instructions.push_back(&Inst); + if (Inst.getMetadata("polly_split_after")) { + Loop *SurroundingLoop = LI.getLoopFor(I->getNodeAs()); + scop->addScopStmt(I->getNodeAs(), SurroundingLoop, + Instructions); + Instructions.clear(); + } } Loop *SurroundingLoop = LI.getLoopFor(I->getNodeAs()); scop->addScopStmt(I->getNodeAs(), SurroundingLoop, Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -1279,6 +1279,10 @@ void ScopStmt::addAccess(MemoryAccess *Access, bool Prepend) { Instruction *AccessInst = Access->getAccessInstruction(); + if (std::find(Instructions.begin(), Instructions.end(), AccessInst) == + Instructions.end()) + return; + if (Access->isArrayKind()) { MemoryAccessList &MAL = InstructionToAccess[AccessInst]; MAL.emplace_front(Access); @@ -5010,8 +5014,6 @@ auto StmtMapIt = StmtMap.find(BB); if (StmtMapIt == StmtMap.end()) return {}; - assert(StmtMapIt->second.size() == 1 && - "Each statement corresponds to exactly one BB."); return StmtMapIt->second; } Index: test/Isl/CodeGen/stmt_split_no_dependence.ll =================================================================== --- /dev/null +++ test/Isl/CodeGen/stmt_split_no_dependence.ll @@ -0,0 +1,41 @@ +; RUN: opt %loadPolly -polly-codegen -polly-print-instructions < %s + +; void func(int *A, int *B){ +; for (int i = 0; i < 1024; i+=1) { +; Stmt: +; A[i] = i; +; B[i] = i; +; } +; } +; +; Function Attrs: noinline nounwind uwtable +define void @func(i32* %A, i32* %B) #0 { +entry: + br label %for.cond + +for.cond: ; preds = %for.inc, %entry + %i.0 = phi i32 [ 0, %entry ], [ %add, %for.inc ] + %cmp = icmp slt i32 %i.0, 1024 + br i1 %cmp, label %for.body, label %for.end + +for.body: ; preds = %for.cond + br label %Stmt + +Stmt: ; preds = %for.body + %idxprom = sext i32 %i.0 to i64 + %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom + store i32 %i.0, i32* %arrayidx, align 4, !polly_split_after !0 + %idxprom1 = sext i32 %i.0 to i64 + %arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %idxprom1 + store i32 %i.0, i32* %arrayidx2, align 4 + br label %for.inc + +for.inc: ; preds = %Stmt + %add = add nsw i32 %i.0, 1 + br label %for.cond + +for.end: ; preds = %for.cond + ret void +} + +!0 = !{!"polly_split_after"} Index: test/ScopInfo/statement.ll =================================================================== --- test/ScopInfo/statement.ll +++ test/ScopInfo/statement.ll @@ -7,11 +7,17 @@ ; B[i] = i; ; } ; } - -; CHECK: Instructions { -; CHECK-NEXT: store i32 %i.0, i32* %arrayidx, align 4 +; +; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT { Stmt_Stmt[i0] -> MemRef_A[i0] }; +; CHECK-NEXT: Instructions { +; CHECK-NEXT: store i32 %i.0, i32* %arrayidx, align 4, !polly_split_after !0 +; CHECK-NEXT: } +; CHECK: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0] +; CHECK-NEXT: { Stmt_Stmt[i0] -> MemRef_B[i0] }; +; CHECK-NEXT: Instructions { ; CHECK-NEXT: store i32 %i.0, i32* %arrayidx2, align 4 -; CHECK-NEXT: } +; CHECK-NEXT: } ; Function Attrs: noinline nounwind uwtable define void @func(i32* %A, i32* %B) #0 { @@ -29,7 +35,7 @@ Stmt: ; preds = %for.body %idxprom = sext i32 %i.0 to i64 %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom - store i32 %i.0, i32* %arrayidx, align 4 + store i32 %i.0, i32* %arrayidx, align 4, !polly_split_after !0 %idxprom1 = sext i32 %i.0 to i64 %arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %idxprom1 store i32 %i.0, i32* %arrayidx2, align 4 @@ -42,3 +48,5 @@ for.end: ; preds = %for.cond ret void } + +!0 = !{!"polly_split_after"}