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());
}
/// vector comprises only of a single statement.
DenseMap<BasicBlock *, std::vector<ScopStmt *>> StmtMap;
+ /// A map from instructions to SCoP statements.
+ DenseMap<Instruction *, ScopStmt *> InstStmtMap;
+
/// A map from basic blocks to their domains.
DenseMap<BasicBlock *, isl::set> DomainMap;
/// 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<ScopStmt *> getStmtListFor(BasicBlock *BB) const;
/// 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.
MAL.emplace_front(Access);
} else if (Access->isValueKind() && Access->isWrite()) {
Instruction *AccessVal = cast<Instruction>(Access->getAccessValue());
- assert(Parent.getStmtFor(AccessVal) == this);
assert(!ValueWrites.lookup(AccessVal));
ValueWrites[AccessVal] = Access;
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<bool(ScopStmt &)> ShouldDelete) {
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;
+ }
}
}
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,
}
}
-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<ScopStmt *> Scop::getStmtListFor(BasicBlock *BB) const {
auto StmtMapIt = StmtMap.find(BB);
if (StmtMapIt == StmtMap.end())