Use value semantics for list of ScopStmt(s) instead of std::owningptr

David Blaike suggested this as an alternative to the use of owningptr(s) for our
memory management, as value semantics allow to avoid the additional interface
complexity caused by owningptr while still providing similar memory consistency
guarantees. We could also have used a std::vector, but the use of std::vector
would yield possibly changing pointers which currently causes problems as for
example the memory accesses carry pointers to their parent statements. Such
pointers should not change.

Reviewer: jblaikie, jdoerfert

Differential Revision: http://reviews.llvm.org/D10041

llvm-svn: 238290
This commit is contained in:
Tobias Grosser 2015-05-27 05:16:57 +00:00
parent aa9fa35555
commit 7c3bad52dd
7 changed files with 89 additions and 97 deletions

View File

@ -26,6 +26,7 @@
#include "isl/ctx.h"
#include <forward_list>
#include <deque>
using namespace llvm;
@ -416,10 +417,20 @@ public:
/// @brief List to hold all (scalar) memory accesses mapped to an instruction.
using MemoryAccessList = std::forward_list<MemoryAccess>;
private:
ScopStmt(const ScopStmt &) = delete;
const ScopStmt &operator=(const ScopStmt &) = delete;
/// Create the ScopStmt from a BasicBlock.
ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
BasicBlock &bb, SmallVectorImpl<Loop *> &NestLoops,
SmallVectorImpl<unsigned> &ScheduleVec);
/// Create an overapproximating ScopStmt for the region @p R.
ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion, Region &R,
SmallVectorImpl<Loop *> &NestLoops,
SmallVectorImpl<unsigned> &ScheduleVec);
private:
/// Polyhedral description
//@{
@ -573,18 +584,6 @@ private:
/// @brief Scan @p Block and derive assumptions about parameter values.
void deriveAssumptions(BasicBlock *Block);
/// Create the ScopStmt from a BasicBlock.
ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion,
BasicBlock &bb, SmallVectorImpl<Loop *> &NestLoops,
SmallVectorImpl<unsigned> &ScheduleVec);
/// Create an overapproximating ScopStmt for the region @p R.
ScopStmt(Scop &parent, TempScop &tempScop, const Region &CurRegion, Region &R,
SmallVectorImpl<Loop *> &NestLoops,
SmallVectorImpl<unsigned> &ScheduleVec);
friend class Scop;
public:
~ScopStmt();
@ -766,7 +765,7 @@ private:
/// Max loop depth.
unsigned MaxLoopDepth;
typedef std::vector<std::unique_ptr<ScopStmt>> StmtSet;
typedef std::deque<ScopStmt> StmtSet;
/// The statements in this Scop.
StmtSet Stmts;
@ -945,8 +944,8 @@ public:
inline unsigned getScheduleDim() const {
unsigned maxScheduleDim = 0;
for (const_iterator SI = begin(), SE = end(); SI != SE; ++SI)
maxScheduleDim = std::max(maxScheduleDim, (*SI)->getNumSchedule());
for (const ScopStmt &Stmt : *this)
maxScheduleDim = std::max(maxScheduleDim, Stmt.getNumSchedule());
return maxScheduleDim;
}

View File

@ -79,14 +79,14 @@ static void collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write,
*StmtSchedule = isl_union_map_empty(Space);
SmallPtrSet<const Value *, 8> ReductionBaseValues;
for (auto &Stmt : S)
for (MemoryAccess *MA : *Stmt)
for (ScopStmt &Stmt : S)
for (MemoryAccess *MA : Stmt)
if (MA->isReductionLike())
ReductionBaseValues.insert(MA->getBaseAddr());
for (auto &Stmt : S) {
for (MemoryAccess *MA : *Stmt) {
isl_set *domcp = Stmt->getDomain();
for (ScopStmt &Stmt : S) {
for (MemoryAccess *MA : Stmt) {
isl_set *domcp = Stmt.getDomain();
isl_map *accdom = MA->getAccessRelation();
accdom = isl_map_intersect_domain(accdom, domcp);
@ -104,7 +104,7 @@ static void collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write,
// but as we transformed the access domain we need the schedule
// to match the new access domains, thus we need
// [Stmt[i0, i1] -> MemAcc_A[i0 + i1]] -> [0, i0, 2, i1, 0]
isl_map *Schedule = Stmt->getSchedule();
isl_map *Schedule = Stmt.getSchedule();
Schedule = isl_map_apply_domain(
Schedule,
isl_map_reverse(isl_map_domain_map(isl_map_copy(accdom))));
@ -117,7 +117,7 @@ static void collectInfo(Scop &S, isl_union_map **Read, isl_union_map **Write,
else
*Write = isl_union_map_add_map(*Write, accdom);
}
*StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt->getSchedule());
*StmtSchedule = isl_union_map_add_map(*StmtSchedule, Stmt.getSchedule());
}
*StmtSchedule =
@ -361,8 +361,8 @@ void Dependences::calculateDependences(Scop &S) {
// Step 1)
RED = isl_union_map_empty(isl_union_map_get_space(RAW));
for (auto &Stmt : S) {
for (MemoryAccess *MA : *Stmt) {
for (ScopStmt &Stmt : S) {
for (MemoryAccess *MA : Stmt) {
if (!MA->isReductionLike())
continue;
isl_set *AccDomW = isl_map_wrap(MA->getAccessRelation());
@ -404,8 +404,8 @@ void Dependences::calculateDependences(Scop &S) {
// We then move this portion of reduction dependences back to the statement ->
// statement space and add a mapping from the memory access to these
// dependences.
for (auto &Stmt : S) {
for (MemoryAccess *MA : *Stmt) {
for (ScopStmt &Stmt : S) {
for (MemoryAccess *MA : Stmt) {
if (!MA->isReductionLike())
continue;
@ -476,13 +476,13 @@ bool Dependences::isValidSchedule(Scop &S,
isl_space *ScheduleSpace = nullptr;
for (auto &Stmt : S) {
for (ScopStmt &Stmt : S) {
isl_map *StmtScat;
if (NewSchedule->find(&*Stmt) == NewSchedule->end())
StmtScat = Stmt->getSchedule();
if (NewSchedule->find(&Stmt) == NewSchedule->end())
StmtScat = Stmt.getSchedule();
else
StmtScat = isl_map_copy((*NewSchedule)[&*Stmt]);
StmtScat = isl_map_copy((*NewSchedule)[&Stmt]);
if (!ScheduleSpace)
ScheduleSpace = isl_space_range(isl_map_get_space(StmtScat));

View File

@ -1349,8 +1349,8 @@ void Scop::realignParams() {
// Align the parameters of all data structures to the model.
Context = isl_set_align_params(Context, Space);
for (auto &Stmt : *this)
Stmt->realignParams();
for (ScopStmt &Stmt : *this)
Stmt.realignParams();
}
void Scop::simplifyAssumedContext() {
@ -1476,16 +1476,16 @@ bool Scop::buildAliasGroups(AliasAnalysis &AA) {
DenseMap<Value *, MemoryAccess *> PtrToAcc;
DenseSet<Value *> HasWriteAccess;
for (auto &Stmt : *this) {
for (ScopStmt &Stmt : *this) {
// Skip statements with an empty domain as they will never be executed.
isl_set *StmtDomain = Stmt->getDomain();
isl_set *StmtDomain = Stmt.getDomain();
bool StmtDomainEmpty = isl_set_is_empty(StmtDomain);
isl_set_free(StmtDomain);
if (StmtDomainEmpty)
continue;
for (MemoryAccess *MA : *Stmt) {
for (MemoryAccess *MA : Stmt) {
if (MA->isScalar())
continue;
if (!MA->isRead())
@ -1666,10 +1666,10 @@ void Scop::dropConstantScheduleDims() {
isl_val_free(FixedVal);
}
for (auto &S : *this) {
isl_map *Schedule = S->getSchedule();
for (ScopStmt &Stmt : *this) {
isl_map *Schedule = Stmt.getSchedule();
Schedule = isl_map_apply_range(Schedule, isl_map_copy(DropDimMap));
S->setSchedule(Schedule);
Stmt.setSchedule(Schedule);
}
isl_set_free(ScheduleSpace);
isl_map_free(DropDimMap);
@ -1806,8 +1806,8 @@ void Scop::printAliasAssumptions(raw_ostream &OS) const {
void Scop::printStatements(raw_ostream &OS) const {
OS << "Statements {\n";
for (auto &Stmt : *this)
OS.indent(4) << *Stmt;
for (const ScopStmt &Stmt : *this)
OS.indent(4) << Stmt;
OS.indent(4) << "}\n";
}
@ -1839,8 +1839,8 @@ isl_ctx *Scop::getIslCtx() const { return IslCtx; }
__isl_give isl_union_set *Scop::getDomains() {
isl_union_set *Domain = isl_union_set_empty(getParamSpace());
for (auto &Stmt : *this)
Domain = isl_union_set_add_set(Domain, Stmt->getDomain());
for (ScopStmt &Stmt : *this)
Domain = isl_union_set_add_set(Domain, Stmt.getDomain());
return Domain;
}
@ -1848,12 +1848,12 @@ __isl_give isl_union_set *Scop::getDomains() {
__isl_give isl_union_map *Scop::getMustWrites() {
isl_union_map *Write = isl_union_map_empty(getParamSpace());
for (auto &Stmt : *this) {
for (MemoryAccess *MA : *Stmt) {
for (ScopStmt &Stmt : *this) {
for (MemoryAccess *MA : Stmt) {
if (!MA->isMustWrite())
continue;
isl_set *Domain = Stmt->getDomain();
isl_set *Domain = Stmt.getDomain();
isl_map *AccessDomain = MA->getAccessRelation();
AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
Write = isl_union_map_add_map(Write, AccessDomain);
@ -1865,12 +1865,12 @@ __isl_give isl_union_map *Scop::getMustWrites() {
__isl_give isl_union_map *Scop::getMayWrites() {
isl_union_map *Write = isl_union_map_empty(getParamSpace());
for (auto &Stmt : *this) {
for (MemoryAccess *MA : *Stmt) {
for (ScopStmt &Stmt : *this) {
for (MemoryAccess *MA : Stmt) {
if (!MA->isMayWrite())
continue;
isl_set *Domain = Stmt->getDomain();
isl_set *Domain = Stmt.getDomain();
isl_map *AccessDomain = MA->getAccessRelation();
AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
Write = isl_union_map_add_map(Write, AccessDomain);
@ -1882,12 +1882,12 @@ __isl_give isl_union_map *Scop::getMayWrites() {
__isl_give isl_union_map *Scop::getWrites() {
isl_union_map *Write = isl_union_map_empty(getParamSpace());
for (auto &Stmt : *this) {
for (MemoryAccess *MA : *Stmt) {
for (ScopStmt &Stmt : *this) {
for (MemoryAccess *MA : Stmt) {
if (!MA->isWrite())
continue;
isl_set *Domain = Stmt->getDomain();
isl_set *Domain = Stmt.getDomain();
isl_map *AccessDomain = MA->getAccessRelation();
AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
Write = isl_union_map_add_map(Write, AccessDomain);
@ -1899,12 +1899,12 @@ __isl_give isl_union_map *Scop::getWrites() {
__isl_give isl_union_map *Scop::getReads() {
isl_union_map *Read = isl_union_map_empty(getParamSpace());
for (auto &Stmt : *this) {
for (MemoryAccess *MA : *Stmt) {
for (ScopStmt &Stmt : *this) {
for (MemoryAccess *MA : Stmt) {
if (!MA->isRead())
continue;
isl_set *Domain = Stmt->getDomain();
isl_set *Domain = Stmt.getDomain();
isl_map *AccessDomain = MA->getAccessRelation();
AccessDomain = isl_map_intersect_domain(AccessDomain, Domain);
@ -1917,16 +1917,16 @@ __isl_give isl_union_map *Scop::getReads() {
__isl_give isl_union_map *Scop::getSchedule() {
isl_union_map *Schedule = isl_union_map_empty(getParamSpace());
for (auto &Stmt : *this)
Schedule = isl_union_map_add_map(Schedule, Stmt->getSchedule());
for (ScopStmt &Stmt : *this)
Schedule = isl_union_map_add_map(Schedule, Stmt.getSchedule());
return isl_union_map_coalesce(Schedule);
}
bool Scop::restrictDomains(__isl_take isl_union_set *Domain) {
bool Changed = false;
for (auto &Stmt : *this) {
isl_union_set *StmtDomain = isl_union_set_from_set(Stmt->getDomain());
for (ScopStmt &Stmt : *this) {
isl_union_set *StmtDomain = isl_union_set_from_set(Stmt.getDomain());
isl_union_set *NewStmtDomain = isl_union_set_intersect(
isl_union_set_copy(StmtDomain), isl_union_set_copy(Domain));
@ -1942,10 +1942,10 @@ bool Scop::restrictDomains(__isl_take isl_union_set *Domain) {
NewStmtDomain = isl_union_set_coalesce(NewStmtDomain);
if (isl_union_set_is_empty(NewStmtDomain)) {
Stmt->restrictDomain(isl_set_empty(Stmt->getDomainSpace()));
Stmt.restrictDomain(isl_set_empty(Stmt.getDomainSpace()));
isl_union_set_free(NewStmtDomain);
} else
Stmt->restrictDomain(isl_set_from_union_set(NewStmtDomain));
Stmt.restrictDomain(isl_set_from_union_set(NewStmtDomain));
}
isl_union_set_free(Domain);
return Changed;
@ -1964,24 +1964,17 @@ void Scop::addScopStmt(BasicBlock *BB, Region *R, TempScop &tempScop,
const Region &CurRegion,
SmallVectorImpl<Loop *> &NestLoops,
SmallVectorImpl<unsigned> &ScheduleVec) {
std::unique_ptr<ScopStmt> Stmt;
if (BB) {
Stmt = std::unique_ptr<ScopStmt>(
new ScopStmt(*this, tempScop, CurRegion, *BB, NestLoops, ScheduleVec));
StmtMap[BB] = &*Stmt;
Stmts.emplace_back(*this, tempScop, CurRegion, *BB, NestLoops, ScheduleVec);
StmtMap[BB] = &Stmts.back();
} else {
assert(R && "Either a basic block or a region is needed to "
"create a new SCoP stmt.");
Stmt = std::unique_ptr<ScopStmt>(
new ScopStmt(*this, tempScop, CurRegion, *R, NestLoops, ScheduleVec));
assert(R && "Either basic block or a region expected.");
Stmts.emplace_back(*this, tempScop, CurRegion, *R, NestLoops, ScheduleVec);
auto *Ptr = &Stmts.back();
for (BasicBlock *BB : R->blocks())
StmtMap[BB] = &*Stmt;
StmtMap[BB] = Ptr;
}
// Insert all statements into the statement map and the statement vector.
Stmts.push_back(std::move(Stmt));
// Increasing the Schedule function is OK for the moment, because
// we are using a depth first iterator and the program is well structured.
++ScheduleVec[NestLoops.size()];
@ -2028,7 +2021,7 @@ void Scop::buildScop(TempScop &tempScop, const Region &CurRegion,
}
ScopStmt *Scop::getStmtForBasicBlock(BasicBlock *BB) const {
const auto &StmtMapIt = StmtMap.find(BB);
const auto StmtMapIt = StmtMap.find(BB);
if (StmtMapIt == StmtMap.end())
return nullptr;
return StmtMapIt->second;

View File

@ -59,8 +59,8 @@ void ScopAnnotator::buildAliasScopes(Scop &S) {
OtherAliasScopeListMap.clear();
SetVector<Value *> BasePtrs;
for (auto &Stmt : S)
for (MemoryAccess *MA : *Stmt)
for (ScopStmt &Stmt : S)
for (MemoryAccess *MA : Stmt)
BasePtrs.insert(MA->getBaseAddr());
std::string AliasScopeStr = "polly.alias.scope.";

View File

@ -37,9 +37,9 @@ BasicBlock *polly::executeScopConditionally(Scop &S, Pass *P, Value *RTC) {
std::string OldName = OldBlock->getName();
// Update ScopInfo.
for (auto &Stmt : S)
if (Stmt->getBasicBlock() == OldBlock) {
Stmt->setBasicBlock(NewBlock);
for (ScopStmt &Stmt : S)
if (Stmt.getBasicBlock() == OldBlock) {
Stmt.setBasicBlock(NewBlock);
break;
}

View File

@ -102,15 +102,15 @@ Json::Value JSONExporter::getJSON(Scop &S) const {
root["location"] = Location;
root["statements"];
for (auto &Stmt : S) {
for (ScopStmt &Stmt : S) {
Json::Value statement;
statement["name"] = Stmt->getBaseName();
statement["domain"] = Stmt->getDomainStr();
statement["schedule"] = Stmt->getScheduleStr();
statement["name"] = Stmt.getBaseName();
statement["domain"] = Stmt.getDomainStr();
statement["schedule"] = Stmt.getScheduleStr();
statement["accesses"];
for (MemoryAccess *MA : *Stmt) {
for (MemoryAccess *MA : Stmt) {
Json::Value access;
access["kind"] = MA->isRead() ? "read" : "write";
@ -232,10 +232,10 @@ bool JSONImporter::runOnScop(Scop &S) {
int index = 0;
for (auto &Stmt : S) {
for (ScopStmt &Stmt : S) {
Json::Value schedule = jscop["statements"][index]["schedule"];
isl_map *m = isl_map_read_from_str(S.getIslCtx(), schedule.asCString());
isl_space *Space = Stmt->getDomainSpace();
isl_space *Space = Stmt.getDomainSpace();
// Copy the old tuple id. This is necessary to retain the user pointer,
// that stores the reference to the ScopStmt this schedule belongs to.
@ -246,7 +246,7 @@ bool JSONImporter::runOnScop(Scop &S) {
m = isl_map_set_dim_id(m, isl_dim_param, i, id);
}
isl_space_free(Space);
NewSchedule[&*Stmt] = m;
NewSchedule[&Stmt] = m;
index++;
}
@ -260,15 +260,15 @@ bool JSONImporter::runOnScop(Scop &S) {
return false;
}
for (auto &Stmt : S) {
if (NewSchedule.find(&*Stmt) != NewSchedule.end())
Stmt->setSchedule(NewSchedule[&*Stmt]);
for (ScopStmt &Stmt : S) {
if (NewSchedule.find(&Stmt) != NewSchedule.end())
Stmt.setSchedule(NewSchedule[&Stmt]);
}
int statementIdx = 0;
for (auto &Stmt : S) {
for (ScopStmt &Stmt : S) {
int memoryAccessIdx = 0;
for (MemoryAccess *MA : *Stmt) {
for (MemoryAccess *MA : Stmt) {
Json::Value accesses = jscop["statements"][statementIdx]["accesses"]
[memoryAccessIdx]["relation"];
isl_map *newAccessMap =

View File

@ -467,21 +467,21 @@ bool IslScheduleOptimizer::runOnScop(Scop &S) {
S.markAsOptimized();
for (auto &Stmt : S) {
for (ScopStmt &Stmt : S) {
isl_map *StmtSchedule;
isl_set *Domain = Stmt->getDomain();
isl_set *Domain = Stmt.getDomain();
isl_union_map *StmtBand;
StmtBand = isl_union_map_intersect_domain(isl_union_map_copy(NewSchedule),
isl_union_set_from_set(Domain));
if (isl_union_map_is_empty(StmtBand)) {
StmtSchedule = isl_map_from_domain(isl_set_empty(Stmt->getDomainSpace()));
StmtSchedule = isl_map_from_domain(isl_set_empty(Stmt.getDomainSpace()));
isl_union_map_free(StmtBand);
} else {
assert(isl_union_map_n_map(StmtBand) == 1);
StmtSchedule = isl_map_from_union_map(StmtBand);
}
Stmt->setSchedule(StmtSchedule);
Stmt.setSchedule(StmtSchedule);
}
isl_schedule_free(Schedule);