Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -1141,7 +1141,8 @@ const ScopStmt &operator=(const ScopStmt &) = delete; /// Create the ScopStmt from a BasicBlock. - ScopStmt(Scop &parent, BasicBlock &bb, Loop *SurroundingLoop); + ScopStmt(Scop &parent, BasicBlock &bb, Loop *SurroundingLoop, + std::vector bbInst); /// Create an overapproximating ScopStmt for the region @p R. ScopStmt(Scop &parent, Region &R, Loop *SurroundingLoop); @@ -1248,6 +1249,9 @@ /// The closest loop that contains this statement. Loop *SurroundingLoop; + /// Vector for Instructions in a BB. + std::vector bbInst; + /// Build the statement. //@{ void buildDomain(); @@ -1532,6 +1536,9 @@ /// /// @param OS The output stream the ScopStmt is printed to. void print(raw_ostream &OS) const; + /// Print the instructions in ScopStmt. + /// + void printInstructions(raw_ostream &OS) const; /// Print the ScopStmt to stderr. void dump() const; @@ -2019,7 +2026,8 @@ /// /// @param BB The basic block we build the statement for. /// @param SurroundingLoop The loop the created statement is contained in. - void addScopStmt(BasicBlock *BB, Loop *SurroundingLoop); + void addScopStmt(BasicBlock *BB, Loop *SurroundingLoop, + std::vector bbInst); /// Create a new SCoP statement for @p R. /// Index: lib/Analysis/ScopBuilder.cpp =================================================================== --- lib/Analysis/ScopBuilder.cpp +++ lib/Analysis/ScopBuilder.cpp @@ -632,8 +632,11 @@ if (I->isSubRegion()) buildStmts(*I->getNodeAs()); else { + std::vector bbInst; + for (Instruction &Inst : *I->getNodeAs()) + bbInst.push_back(&Inst); Loop *SurroundingLoop = LI.getLoopFor(I->getNodeAs()); - scop->addScopStmt(I->getNodeAs(), SurroundingLoop); + scop->addScopStmt(I->getNodeAs(), SurroundingLoop, bbInst); } } Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -1647,9 +1647,11 @@ "Stmt", R.getNameStr(), parent.getNextStmtIdx(), "", UseInstructionNames); } -ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb, Loop *SurroundingLoop) +ScopStmt::ScopStmt(Scop &parent, BasicBlock &bb, Loop *SurroundingLoop, + std::vector bbInst) : Parent(parent), InvalidDomain(nullptr), Domain(nullptr), BB(&bb), - R(nullptr), Build(nullptr), SurroundingLoop(SurroundingLoop) { + R(nullptr), Build(nullptr), SurroundingLoop(SurroundingLoop), + bbInst(bbInst) { BaseName = getIslCompatibleName("Stmt", &bb, parent.getNextStmtIdx(), "", UseInstructionNames); @@ -1863,6 +1865,15 @@ isl_set_free(InvalidDomain); } +void ScopStmt::printInstructions(raw_ostream &OS) const { + OS << "Instructions {\n"; + + for (Instruction *Inst : bbInst) + OS.indent(4) << *Inst << "\n"; + + OS.indent(4) << "}\n"; +} + void ScopStmt::print(raw_ostream &OS) const { OS << "\t" << getBaseName() << "\n"; OS.indent(12) << "Domain :=\n"; @@ -1881,6 +1892,8 @@ for (MemoryAccess *Access : MemAccs) Access->print(OS); + + printInstructions(OS.indent(12)); } void ScopStmt::dump() const { print(dbgs()); } @@ -4644,9 +4657,10 @@ return isl_multi_union_pw_aff_from_union_pw_multi_aff(Data.Res); } -void Scop::addScopStmt(BasicBlock *BB, Loop *SurroundingLoop) { +void Scop::addScopStmt(BasicBlock *BB, Loop *SurroundingLoop, + std::vector bbInst) { assert(BB && "Unexpected nullptr!"); - Stmts.emplace_back(*this, *BB, SurroundingLoop); + Stmts.emplace_back(*this, *BB, SurroundingLoop, bbInst); auto *Stmt = &Stmts.back(); StmtMap[BB] = Stmt; } Index: test/ScopInfo/statement.ll =================================================================== --- /dev/null +++ test/ScopInfo/statement.ll @@ -0,0 +1,53 @@ +; RUN: opt %loadPolly -polly-scops -analyze < %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: Instructions { +; CHECK-NEXT: %i.0 = phi i32 [ 0, %entry ], [ %add, %for.inc ] +; CHECK-NEXT: %cmp = icmp slt i32 %i.0, 1024 +; CHECK-NEXT: br i1 %cmp, label %for.body, label %for.end +; CHECK-NEXT: br label %Stmt +; CHECK-NEXT: %idxprom = sext i32 %i.0 to i64 +; CHECK-NEXT: %arrayidx = getelementptr inbounds i32, i32* %A, i64 %idxprom +; CHECK-NEXT: store i32 %i.0, i32* %arrayidx, align 4 +; CHECK-NEXT: %idxprom1 = sext i32 %i.0 to i64 +; CHECK-NEXT: %arrayidx2 = getelementptr inbounds i32, i32* %B, i64 %idxprom1 +; CHECK-NEXT: store i32 %i.0, i32* %arrayidx2, align 4 +; CHECK-NEXT: br label %for.inc +; 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 + %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 +}