Index: polly/trunk/include/polly/ScopInfo.h =================================================================== --- polly/trunk/include/polly/ScopInfo.h +++ polly/trunk/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 Instructions); /// 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 Instructions; + /// Build the statement. //@{ void buildDomain(); @@ -1533,6 +1537,10 @@ /// @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 +2027,9 @@ /// /// @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); + /// @param Instructions The instructions in the basic block. + void addScopStmt(BasicBlock *BB, Loop *SurroundingLoop, + std::vector Instructions); /// Create a new SCoP statement for @p R. /// Index: polly/trunk/lib/Analysis/ScopBuilder.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopBuilder.cpp +++ polly/trunk/lib/Analysis/ScopBuilder.cpp @@ -632,8 +632,12 @@ if (I->isSubRegion()) buildStmts(*I->getNodeAs()); else { + std::vector Instructions; + for (Instruction &Inst : *I->getNodeAs()) + Instructions.push_back(&Inst); Loop *SurroundingLoop = LI.getLoopFor(I->getNodeAs()); - scop->addScopStmt(I->getNodeAs(), SurroundingLoop); + scop->addScopStmt(I->getNodeAs(), SurroundingLoop, + Instructions); } } Index: polly/trunk/lib/Analysis/ScopInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopInfo.cpp +++ polly/trunk/lib/Analysis/ScopInfo.cpp @@ -168,6 +168,10 @@ cl::location(UseInstructionNames), cl::Hidden, cl::init(false), cl::ZeroOrMore, cl::cat(PollyCategory)); +static cl::opt PollyPrintInstructions( + "polly-print-instructions", cl::desc("Output instructions per ScopStmt"), + cl::Hidden, cl::Optional, cl::init(false), cl::cat(PollyCategory)); + //===----------------------------------------------------------------------===// // Create a sequence of two schedules. Either argument may be null and is @@ -1647,9 +1651,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 Instructions) : Parent(parent), InvalidDomain(nullptr), Domain(nullptr), BB(&bb), - R(nullptr), Build(nullptr), SurroundingLoop(SurroundingLoop) { + R(nullptr), Build(nullptr), SurroundingLoop(SurroundingLoop), + Instructions(Instructions) { BaseName = getIslCompatibleName("Stmt", &bb, parent.getNextStmtIdx(), "", UseInstructionNames); @@ -1863,6 +1869,15 @@ isl_set_free(InvalidDomain); } +void ScopStmt::printInstructions(raw_ostream &OS) const { + OS << "Instructions {\n"; + + for (Instruction *Inst : Instructions) + OS.indent(16) << *Inst << "\n"; + + OS.indent(16) << "}\n"; +} + void ScopStmt::print(raw_ostream &OS) const { OS << "\t" << getBaseName() << "\n"; OS.indent(12) << "Domain :=\n"; @@ -1881,6 +1896,9 @@ for (MemoryAccess *Access : MemAccs) Access->print(OS); + + if (PollyPrintInstructions) + printInstructions(OS.indent(12)); } void ScopStmt::dump() const { print(dbgs()); } @@ -4616,9 +4634,10 @@ return isl::multi_union_pw_aff(isl::union_pw_multi_aff(Result)); } -void Scop::addScopStmt(BasicBlock *BB, Loop *SurroundingLoop) { +void Scop::addScopStmt(BasicBlock *BB, Loop *SurroundingLoop, + std::vector Instructions) { assert(BB && "Unexpected nullptr!"); - Stmts.emplace_back(*this, *BB, SurroundingLoop); + Stmts.emplace_back(*this, *BB, SurroundingLoop, Instructions); auto *Stmt = &Stmts.back(); StmtMap[BB] = Stmt; } Index: polly/trunk/test/ScopInfo/statement.ll =================================================================== --- polly/trunk/test/ScopInfo/statement.ll +++ polly/trunk/test/ScopInfo/statement.ll @@ -0,0 +1,49 @@ +; 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: Instructions { +; 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 +}