[ScopBuilder] Introduce metadata for splitting scop statement.

This patch allows annotating of metadata in ir instruction
(with "polly_split_after"), which specifies where to split a particular
scop statement.

Contributed-by: Nandini Singhal <cs15mtech01004@iith.ac.in>

Differential Revision: https://reviews.llvm.org/D36402

llvm-svn: 312107
This commit is contained in:
Michael Kruse 2017-08-30 10:11:06 +00:00
parent b150d24d7a
commit 591255183b
11 changed files with 430 additions and 25 deletions

View File

@ -229,8 +229,8 @@ class ScopBuilder {
/// access any memory and thus have no effect.
void buildStmts(Region &SR);
/// Build the access functions for the basic block @p BB in or represented by
/// @p Stmt.
/// Build the access functions for the statement @p Stmt in or represented by
/// @p BB.
///
/// @param Stmt Statement to add MemoryAccesses to.
/// @param BB A basic block in @p R.

View File

@ -1192,7 +1192,7 @@ class ScopStmt {
public:
/// Create the ScopStmt from a BasicBlock.
ScopStmt(Scop &parent, BasicBlock &bb, Loop *SurroundingLoop,
std::vector<Instruction *> Instructions);
std::vector<Instruction *> Instructions, int Count);
/// Create an overapproximating ScopStmt for the region @p R.
ScopStmt(Scop &parent, Region &R, Loop *SurroundingLoop);
@ -2203,8 +2203,9 @@ private:
/// @param BB The basic block we build the statement for.
/// @param SurroundingLoop The loop the created statement is contained in.
/// @param Instructions The instructions in the statement.
/// @param Count The index of the created statement in @p BB.
void addScopStmt(BasicBlock *BB, Loop *SurroundingLoop,
std::vector<Instruction *> Instructions);
std::vector<Instruction *> Instructions, int Count);
/// Create a new SCoP statement for @p R.
///

View File

@ -658,16 +658,24 @@ void ScopBuilder::buildStmts(Region &SR) {
if (I->isSubRegion())
buildStmts(*I->getNodeAs<Region>());
else {
int Count = 0;
std::vector<Instruction *> Instructions;
for (Instruction &Inst : *I->getNodeAs<BasicBlock>()) {
Loop *L = LI.getLoopFor(Inst.getParent());
if (!isa<TerminatorInst>(&Inst) && !isIgnoredIntrinsic(&Inst) &&
!canSynthesize(&Inst, *scop, &SE, L))
Instructions.push_back(&Inst);
if (Inst.getMetadata("polly_split_after")) {
Loop *SurroundingLoop = LI.getLoopFor(I->getNodeAs<BasicBlock>());
scop->addScopStmt(I->getNodeAs<BasicBlock>(), SurroundingLoop,
Instructions, Count);
Count++;
Instructions.clear();
}
}
Loop *SurroundingLoop = LI.getLoopFor(I->getNodeAs<BasicBlock>());
scop->addScopStmt(I->getNodeAs<BasicBlock>(), SurroundingLoop,
Instructions);
Instructions, Count);
}
}
@ -684,7 +692,19 @@ void ScopBuilder::buildAccessFunctions(ScopStmt *Stmt, BasicBlock &BB,
if (isErrorBlock(BB, scop->getRegion(), LI, DT) && !IsExitBlock)
return;
int Count = 0;
bool Split = false;
for (Instruction &Inst : BB) {
if (Split) {
Split = false;
Count++;
}
if (Inst.getMetadata("polly_split_after"))
Split = true;
if (Stmt && Stmt->isBlockStmt() && Stmt != scop->getStmtListFor(&BB)[Count])
continue;
PHINode *PHI = dyn_cast<PHINode>(&Inst);
if (PHI)
buildPHIAccesses(Stmt, PHI, NonAffineSubRegion, IsExitBlock);

View File

@ -1764,11 +1764,14 @@ ScopStmt::ScopStmt(Scop &parent, Region &R, Loop *SurroundingLoop)
}
ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb, Loop *SurroundingLoop,
std::vector<Instruction *> Instructions)
std::vector<Instruction *> Instructions, int Count)
: Parent(parent), InvalidDomain(nullptr), Domain(nullptr), BB(&bb),
Build(nullptr), SurroundingLoop(SurroundingLoop),
Instructions(Instructions) {
BaseName = getIslCompatibleName("Stmt", &bb, parent.getNextStmtIdx(), "",
std::string S = "";
if (Count != 0)
S += std::to_string(Count);
BaseName = getIslCompatibleName("Stmt", &bb, parent.getNextStmtIdx(), S,
UseInstructionNames);
}
@ -4880,9 +4883,9 @@ static isl::multi_union_pw_aff mapToDimension(isl::union_set USet, int N) {
}
void Scop::addScopStmt(BasicBlock *BB, Loop *SurroundingLoop,
std::vector<Instruction *> Instructions) {
std::vector<Instruction *> Instructions, int Count) {
assert(BB && "Unexpected nullptr!");
Stmts.emplace_back(*this, *BB, SurroundingLoop, Instructions);
Stmts.emplace_back(*this, *BB, SurroundingLoop, Instructions, Count);
auto *Stmt = &Stmts.back();
StmtMap[BB].push_back(Stmt);
for (Instruction *Inst : Instructions) {
@ -5049,8 +5052,6 @@ ArrayRef<ScopStmt *> Scop::getStmtListFor(BasicBlock *BB) const {
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;
}

View File

@ -1,5 +1,8 @@
; RUN: opt %loadPolly -polly-scops -analyze -polly-print-instructions < %s | FileCheck %s
; RUN: opt %loadPolly -polly-codegen -S < %s | FileCheck %s
;
; CHECK: store i32 %8, i32* %scevgep, align 4, !alias.scope !1, !noalias !3
; CHECK: store i32 %9, i32* %scevgep4, align 4, !alias.scope !4, !noalias !5
;
; void func(int *A, int *B){
; for (int i = 0; i < 1024; i+=1) {
; Stmt:
@ -7,38 +10,35 @@
; B[i] = i;
; }
; }
; CHECK: Instructions {
; CHECK-NEXT: store i32 %i.0, i32* %arrayidx, align 4
; CHECK-NEXT: store i32 %i.0, i32* %arrayidx2, align 4
; CHECK-NEXT: }
;
; Function Attrs: noinline nounwind uwtable
define void @func(i32* %A, i32* %B) #0 {
entry:
br label %for.cond
for.cond: ; preds = %for.inc, %entry
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
for.body: ; preds = %for.cond
br label %Stmt
Stmt: ; preds = %for.body
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
br label %for.inc
for.inc: ; preds = %Stmt
for.inc: ; preds = %Stmt
%add = add nsw i32 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
for.end: ; preds = %for.cond
ret void
}
!0 = !{!"polly_split_after"}

View File

@ -0,0 +1,71 @@
; RUN: opt %loadPolly -polly-scops -analyze -polly-print-instructions < %s | FileCheck %s
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_Region__TO__Stmt
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Region__TO__Stmt[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Region__TO__Stmt[i0] -> [i0, 0] };
; CHECK-NEXT: MayWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_Region__TO__Stmt[i0] -> MemRef_C[0] };
; CHECK-NEXT: Stmt_Stmt
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt[i0] -> [i0, 1] };
; CHECK-NEXT: 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-NEXT: Stmt_Stmt1
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt1[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt1[i0] -> [i0, 2] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_Stmt1[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, double* %C) {
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 %Region
Region: ; preds = %for.body
%cond = fcmp oeq double 2.100000e+01, 2.100000e+01
br i1 %cond, label %Region_true, label %Stmt
Region_true: ; preds = %Region
store double 0.000000e+00, double* %C
br label %Stmt
Stmt: ; preds = %Region_true, %Region
%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"}

View File

@ -0,0 +1,64 @@
; RUN: opt %loadPolly -polly-scops -analyze -polly-print-instructions < %s | FileCheck %s
; void func(int *A, int *B){
; for (int i = 0; i < 1024; i+=1) {
; Stmt:
; A[i] = i;
; B[i] = i;
; }
; }
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_Stmt
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt[i0] -> [i0, 0] };
; CHECK-NEXT: 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-NEXT: Stmt_Stmt1
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt1[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt1[i0] -> [i0, 1] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_Stmt1[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 {
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"}

View File

@ -0,0 +1,56 @@
; RUN: opt %loadPolly -polly-scops -analyze -polly-print-instructions < %s | FileCheck %s
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_Stmt
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt[i0] -> [i0, 0] };
; CHECK-NEXT: 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
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_Stmt1
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt1[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt1[i0] -> [i0, 1] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_Stmt1[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, double* %C) #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:
%idxprom = sext i32 %i.0 to i64
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
store i32 %i.0, i32* %arrayidx, align 4
%idxprom1 = sext i32 %i.0 to i64, !polly_split_after !0
%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"}

View File

@ -0,0 +1,57 @@
; RUN: opt %loadPolly -polly-scops -analyze -polly-print-instructions < %s | FileCheck %s
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_Stmt
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt[i0] -> [i0, 0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_Stmt[i0] -> MemRef_A[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: store i32 %phi, i32* %arrayidx, align 4, !polly_split_after !0
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_Stmt1
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt1[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt1[i0] -> [i0, 1] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_Stmt1[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 {
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:
%phi = phi i32 [0, %for.body]
%idxprom = sext i32 %i.0 to i64
%arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom
store i32 %phi, 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"}

View File

@ -0,0 +1,75 @@
; RUN: opt %loadPolly -polly-scops -analyze -polly-print-instructions < %s | FileCheck %s
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_Stmt
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt[i0] -> [i0, 0] };
; CHECK-NEXT: 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-NEXT: Stmt_Stmt1
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt1[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt1[i0] -> [i0, 1] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_Stmt1[i0] -> MemRef_B[i0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_Stmt1[i0] -> MemRef_phi__phi[] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %d = fadd double 2.100000e+01, 2.100000e+01
; CHECK-NEXT: store i32 %i.0, i32* %arrayidx2, align 4
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_for_inc
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_for_inc[i0] : 0 <= i0 <= 1023 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_for_inc[i0] -> [i0, 2] };
; CHECK-NEXT: ReadAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: { Stmt_for_inc[i0] -> MemRef_phi__phi[] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_for_inc[i0] -> MemRef_C[0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: %phi = phi double [ %d, %Stmt ]
; CHECK-NEXT: store double %phi, double* %C
; CHECK-NEXT: }
; CHECK-NEXT: }
;
; Function Attrs: noinline nounwind uwtable
define void @func(i32* %A, i32* %B, double* %C) #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:
%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
%d = fadd double 21.0, 21.0
%arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %idxprom1
store i32 %i.0, i32* %arrayidx2, align 4
br label %for.inc
for.inc: ; preds = %Stmt
%phi = phi double [%d, %Stmt]
store double %phi, double* %C
%add = add nsw i32 %i.0, 1
br label %for.cond
for.end: ; preds = %for.cond
ret void
}
!0 = !{!"polly_split_after"}

View File

@ -0,0 +1,60 @@
; RUN: opt %loadPolly -polly-scops -analyze -polly-print-instructions < %s | FileCheck %s
;
; CHECK: Statements {
; CHECK-NEXT: Stmt_Stmt
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt[i0, i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 512 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt[i0, i1] -> [i0, i1, 0] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_Stmt[i0, i1] -> MemRef_A[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: store i32 %i.0, i32* %arrayidx, align 4, !polly_split_after !0
; CHECK-NEXT: }
; CHECK-NEXT: Stmt_Stmt1
; CHECK-NEXT: Domain :=
; CHECK-NEXT: { Stmt_Stmt1[i0, i1] : 0 <= i0 <= 1023 and 0 <= i1 <= 512 };
; CHECK-NEXT: Schedule :=
; CHECK-NEXT: { Stmt_Stmt1[i0, i1] -> [i0, i1, 1] };
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 0]
; CHECK-NEXT: { Stmt_Stmt1[i0, i1] -> MemRef_B[i0] };
; CHECK-NEXT: Instructions {
; CHECK-NEXT: store i32 %i.0, i32* %arrayidx2, align 4
; CHECK-NEXT: %cond = icmp slt i32 %j, 512
; CHECK-NEXT: }
; CHECK-NEXT: }
;
; Function Attrs: noinline nounwind uwtable
define void @func(i32* %A, i32* %B, double* %C) #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:
%j = phi i32 [ 0, %for.body ], [ %inc, %Stmt ]
%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
%inc = add nsw i32 %j, 1
%cond = icmp slt i32 %j, 512
br i1 %cond, label %Stmt, 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"}