Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -2610,6 +2610,9 @@ /// none. ScopStmt *getStmtFor(BasicBlock *BB) const; + /// Return the list of ScopStmts that represent the given @p BB. + ArrayRef getStmtListFor(BasicBlock *BB) const; + /// Return the last statement representing @p BB. /// /// Of the sequence of statements that represent a @p BB, this is the last one Index: lib/Analysis/ScopBuilder.cpp =================================================================== --- lib/Analysis/ScopBuilder.cpp +++ lib/Analysis/ScopBuilder.cpp @@ -880,38 +880,36 @@ /// happened yet, such that virtual and physical uses are equivalent. static void verifyUses(Scop *S, LoopInfo &LI, DominatorTree &DT) { for (auto *BB : S->getRegion().blocks()) { - auto *Stmt = S->getStmtFor(BB); - if (!Stmt) - continue; - - for (auto &Inst : *BB) { - if (isIgnoredIntrinsic(&Inst)) - continue; - - // Branch conditions are encoded in the statement domains. - if (isa(&Inst) && Stmt->isBlockStmt()) - continue; - - // Verify all uses. - for (auto &Op : Inst.operands()) - verifyUse(S, Op, LI); - - // Stores do not produce values used by other statements. - if (isa(Inst)) - continue; - - // For every value defined in the block, also check that a use of that - // value in the same statement would not be an inter-statement use. It can - // still be synthesizable or load-hoisted, but these kind of instructions - // are not directly copied in code-generation. - auto VirtDef = - VirtualUse::create(S, Stmt, Stmt->getSurroundingLoop(), &Inst, true); - assert(VirtDef.getKind() == VirtualUse::Synthesizable || - VirtDef.getKind() == VirtualUse::Intra || - VirtDef.getKind() == VirtualUse::Hoisted); + for (auto *Stmt : S->getStmtListFor(BB)) { + + for (auto &Inst : *BB) { + if (isIgnoredIntrinsic(&Inst)) + continue; + + // Branch conditions are encoded in the statement domains. + if (isa(&Inst) && Stmt->isBlockStmt()) + continue; + + // Verify all uses. + for (auto &Op : Inst.operands()) + verifyUse(S, Op, LI); + + // Stores do not produce values used by other statements. + if (isa(Inst)) + continue; + + // For every value defined in the block, also check that a use of that + // value in the same statement would not be an inter-statement use. It + // can still be synthesizable or load-hoisted, but these kind of + // instructions are not directly copied in code-generation. + auto VirtDef = VirtualUse::create(S, Stmt, Stmt->getSurroundingLoop(), + &Inst, true); + assert(VirtDef.getKind() == VirtualUse::Synthesizable || + VirtDef.getKind() == VirtualUse::Intra || + VirtDef.getKind() == VirtualUse::Hoisted); + } } } - if (S->hasSingleExitEdge()) return; Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -4912,6 +4912,15 @@ return StmtMapIt->second.front(); } +ArrayRef 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; +} + ScopStmt *Scop::getStmtFor(RegionNode *RN) const { if (RN->isSubRegion()) return getStmtFor(RN->getNodeAs());