Index: include/polly/ScopInfo.h =================================================================== --- include/polly/ScopInfo.h +++ include/polly/ScopInfo.h @@ -1400,6 +1400,9 @@ bool contains(Instruction *Inst) const { if (!Inst) return false; + if (isBlockStmt()) + return std::find(Instructions.begin(), Instructions.end(), Inst) != + Instructions.end(); return represents(Inst->getParent()); } @@ -1744,6 +1747,9 @@ /// vector comprises only of a single statement. DenseMap> StmtMap; + /// A map from instructions to SCoP statements. + DenseMap InstStmtMap; + /// A map from basic blocks to their domains. DenseMap DomainMap; @@ -2693,10 +2699,6 @@ /// Get an isl string representing the invalid context. std::string getInvalidContextStr() const; - /// Return the ScopStmt for the given @p BB or nullptr if there is - /// none. - ScopStmt *getStmtFor(BasicBlock *BB) const; - /// Return the list of ScopStmts that represent the given @p BB. ArrayRef getStmtListFor(BasicBlock *BB) const; @@ -2720,7 +2722,7 @@ /// Return the ScopStmt an instruction belongs to, or nullptr if it /// does not belong to any statement in this Scop. ScopStmt *getStmtFor(Instruction *Inst) const { - return getStmtFor(Inst->getParent()); + return InstStmtMap.lookup(Inst); } /// Return the number of statements in the SCoP. Index: lib/Analysis/ScopInfo.cpp =================================================================== --- lib/Analysis/ScopInfo.cpp +++ lib/Analysis/ScopInfo.cpp @@ -1284,7 +1284,6 @@ MAL.emplace_front(Access); } else if (Access->isValueKind() && Access->isWrite()) { Instruction *AccessVal = cast(Access->getAccessValue()); - assert(Parent.getStmtFor(AccessVal) == this); assert(!ValueWrites.lookup(AccessVal)); ValueWrites[AccessVal] = Access; @@ -3764,10 +3763,16 @@ void Scop::removeFromStmtMap(ScopStmt &Stmt) { if (Stmt.isRegionStmt()) - for (BasicBlock *BB : Stmt.getRegion()->blocks()) + for (BasicBlock *BB : Stmt.getRegion()->blocks()) { StmtMap.erase(BB); - else + for (Instruction &Inst : *BB) + InstStmtMap.erase(&Inst); + } + else { StmtMap.erase(Stmt.getBasicBlock()); + for (Instruction *Inst : Stmt.getInstructions()) + InstStmtMap.erase(Inst); + } } void Scop::removeStmts(std::function ShouldDelete) { @@ -4086,11 +4091,11 @@ auto &RIL = getRequiredInvariantLoads(); for (LoadInst *LI : RIL) { assert(LI && contains(LI)); - ScopStmt *Stmt = getStmtFor(LI); - if (Stmt && Stmt->getArrayAccessOrNULLFor(LI)) { - invalidate(INVARIANTLOAD, LI->getDebugLoc(), LI->getParent()); - return; - } + for (ScopStmt &Stmt : Stmts) + if (Stmt.getArrayAccessOrNULLFor(LI)) { + invalidate(INVARIANTLOAD, LI->getDebugLoc(), LI->getParent()); + return; + } } } @@ -4833,14 +4838,25 @@ Stmts.emplace_back(*this, *BB, SurroundingLoop, Instructions); auto *Stmt = &Stmts.back(); StmtMap[BB].push_back(Stmt); + for (Instruction *Inst : Instructions) { + assert(!InstStmtMap.count(Inst) && + "Unexpected statement corresponding to the instruction."); + InstStmtMap[Inst] = Stmt; + } } void Scop::addScopStmt(Region *R, Loop *SurroundingLoop) { assert(R && "Unexpected nullptr!"); Stmts.emplace_back(*this, *R, SurroundingLoop); auto *Stmt = &Stmts.back(); - for (BasicBlock *BB : R->blocks()) + for (BasicBlock *BB : R->blocks()) { StmtMap[BB].push_back(Stmt); + for (Instruction &Inst : *BB) { + assert(!InstStmtMap.count(&Inst) && + "Unexpected statement corresponding to the instruction."); + InstStmtMap[&Inst] = Stmt; + } + } } ScopStmt *Scop::addScopStmt(isl::map SourceRel, isl::map TargetRel, @@ -4985,14 +5001,6 @@ } } -ScopStmt *Scop::getStmtFor(BasicBlock *BB) const { - auto StmtMapIt = StmtMap.find(BB); - if (StmtMapIt == StmtMap.end()) - return nullptr; - assert(StmtMapIt->second.size() == 1); - return StmtMapIt->second.front(); -} - ArrayRef Scop::getStmtListFor(BasicBlock *BB) const { auto StmtMapIt = StmtMap.find(BB); if (StmtMapIt == StmtMap.end()) Index: lib/Transform/ForwardOpTree.cpp =================================================================== --- lib/Transform/ForwardOpTree.cpp +++ lib/Transform/ForwardOpTree.cpp @@ -161,7 +161,7 @@ return FD_NotApplicable; Loop *DefLoop = LI->getLoopFor(UseInst->getParent()); - ScopStmt *DefStmt = S->getStmtFor(UseInst); + ScopStmt *DefStmt = S->getLastStmtFor(UseInst->getParent()); assert(DefStmt && "Value must be defined somewhere"); if (DoIt) {