Index: polly/trunk/include/polly/ScopInfo.h =================================================================== --- polly/trunk/include/polly/ScopInfo.h +++ polly/trunk/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()); } @@ -1748,6 +1751,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; @@ -2697,10 +2703,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; @@ -2724,7 +2726,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: polly/trunk/lib/Analysis/ScopInfo.cpp =================================================================== --- polly/trunk/lib/Analysis/ScopInfo.cpp +++ polly/trunk/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; @@ -3768,10 +3767,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) { @@ -4090,11 +4095,13 @@ 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; - } + // If there exists a statement in the scop which has a memory access for + // @p LI, then mark this scop as infeasible for optimization. + for (ScopStmt &Stmt : Stmts) + if (Stmt.getArrayAccessOrNULLFor(LI)) { + invalidate(INVARIANTLOAD, LI->getDebugLoc(), LI->getParent()); + return; + } } } @@ -4837,14 +4844,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, @@ -4989,14 +5007,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: polly/trunk/lib/Transform/ForwardOpTree.cpp =================================================================== --- polly/trunk/lib/Transform/ForwardOpTree.cpp +++ polly/trunk/lib/Transform/ForwardOpTree.cpp @@ -666,9 +666,12 @@ case VirtualUse::Inter: Instruction *Inst = cast(UseVal); - if (!DefStmt) + if (!DefStmt) { DefStmt = S->getStmtFor(Inst); - assert(DefStmt && "Value must be defined somewhere"); + if (!DefStmt) + return FD_CannotForward; + } + DefLoop = LI->getLoopFor(Inst->getParent()); if (DefToTarget.is_null() && !Known.is_null()) {