Define buildScheduleRec on RegionNodes and pull out the tree traversal [NFC]

This change clarifies that for Not-NonAffine-SubRegions we actually iterate over
the subnodes and for both NonAffine-SubRegions and BasicBlocks, we perform the
schedule construction. As a result, the tree traversal becomes trivial, the
special case for a scop consisting just of a single non-affine region
disappears and the indentation of the code is reduced.

No functional change intended.

llvm-svn: 256940
This commit is contained in:
Tobias Grosser 2016-01-06 15:30:06 +00:00
parent 8f9d180f09
commit 8362c26113
2 changed files with 55 additions and 68 deletions

View File

@ -1408,12 +1408,12 @@ private:
///
void buildSchedule();
/// @brief Build Schedule for the region @p R.
/// @brief Build Schedule for the region @p RN.
///
/// @param R The current region traversed.
/// @param RN The current region traversed.
/// @param LoopSchedules Map from loops to their schedule and progress.
void buildSchedule(
Region *R,
RegionNode *RN,
DenseMap<Loop *, std::pair<isl_schedule *, unsigned>> &LoopSchedules);
/// @brief Collect all memory access relations of a given type.

View File

@ -3428,84 +3428,71 @@ void Scop::addScopStmt(BasicBlock *BB, Region *R) {
}
void Scop::buildSchedule() {
// Special case for SCoPs that consist only of one non-affine region.
if (SD.isNonAffineSubRegion(&getRegion(), &getRegion())) {
ScopStmt *Stmt = getStmtForBasicBlock(getRegion().getEntry());
isl_set *Domain = Stmt->getDomain();
Schedule = isl_schedule_from_domain(isl_union_set_from_set(Domain));
return;
}
// For general SCoPs invoke the recursive schedule generation.
DenseMap<Loop *, std::pair<isl_schedule *, unsigned>> LoopSchedules;
Loop *L = getLoopSurroundingRegion(getRegion(), LI);
LoopSchedules[L];
buildSchedule(&getRegion(), LoopSchedules);
buildSchedule(getRegion().getNode(), LoopSchedules);
Schedule = LoopSchedules[L].first;
}
void Scop::buildSchedule(
Region *R,
RegionNode *RN,
DenseMap<Loop *, std::pair<isl_schedule *, unsigned>> &LoopSchedules) {
ReversePostOrderTraversal<Region *> RTraversal(R);
for (auto *RN : RTraversal) {
if (RN->isSubRegion()) {
auto *LocalRegion = RN->getNodeAs<Region>();
if (!SD.isNonAffineSubRegion(LocalRegion, &getRegion())) {
ReversePostOrderTraversal<Region *> RTraversal(LocalRegion);
for (auto *Child : RTraversal)
buildSchedule(Child, LoopSchedules);
return;
}
}
if (RN->isSubRegion()) {
Region *SubRegion = RN->getNodeAs<Region>();
if (!SD.isNonAffineSubRegion(SubRegion, &getRegion())) {
buildSchedule(SubRegion, LoopSchedules);
continue;
}
Loop *L = getRegionNodeLoop(RN, LI);
if (!getRegion().contains(L))
L = getLoopSurroundingRegion(getRegion(), LI);
int LD = getRelativeLoopDepth(L);
auto &LSchedulePair = LoopSchedules[L];
LSchedulePair.second += getNumBlocksInRegionNode(RN);
ScopStmt *Stmt = getStmtForRegionNode(RN);
if (Stmt) {
auto *UDomain = isl_union_set_from_set(Stmt->getDomain());
auto *StmtSchedule = isl_schedule_from_domain(UDomain);
LSchedulePair.first = combineInSequence(LSchedulePair.first, StmtSchedule);
}
isl_schedule *LSchedule = LSchedulePair.first;
unsigned NumVisited = LSchedulePair.second;
while (L && NumVisited == L->getNumBlocks()) {
auto *PL = L->getParentLoop();
// Either we have a proper loop and we also build a schedule for the
// parent loop or we have a infinite loop that does not have a proper
// parent loop. In the former case this conditional will be skipped, in
// the latter case however we will break here as we do not build a domain
// nor a schedule for a infinite loop.
assert(LoopSchedules.count(PL) || LSchedule == nullptr);
if (!LoopSchedules.count(PL))
break;
auto &PSchedulePair = LoopSchedules[PL];
if (LSchedule) {
auto *LDomain = isl_schedule_get_domain(LSchedule);
auto *MUPA = mapToDimension(LDomain, LD + 1);
LSchedule = isl_schedule_insert_partial_schedule(LSchedule, MUPA);
PSchedulePair.first = combineInSequence(PSchedulePair.first, LSchedule);
}
Loop *L = getRegionNodeLoop(RN, LI);
if (!getRegion().contains(L))
L = getLoopSurroundingRegion(getRegion(), LI);
PSchedulePair.second += NumVisited;
int LD = getRelativeLoopDepth(L);
auto &LSchedulePair = LoopSchedules[L];
LSchedulePair.second += getNumBlocksInRegionNode(RN);
ScopStmt *Stmt = getStmtForRegionNode(RN);
if (Stmt) {
auto *UDomain = isl_union_set_from_set(Stmt->getDomain());
auto *StmtSchedule = isl_schedule_from_domain(UDomain);
LSchedulePair.first =
combineInSequence(LSchedulePair.first, StmtSchedule);
}
isl_schedule *LSchedule = LSchedulePair.first;
unsigned NumVisited = LSchedulePair.second;
while (L && NumVisited == L->getNumBlocks()) {
auto *PL = L->getParentLoop();
// Either we have a proper loop and we also build a schedule for the
// parent loop or we have a infinite loop that does not have a proper
// parent loop. In the former case this conditional will be skipped, in
// the latter case however we will break here as we do not build a domain
// nor a schedule for a infinite loop.
assert(LoopSchedules.count(PL) || LSchedule == nullptr);
if (!LoopSchedules.count(PL))
break;
auto &PSchedulePair = LoopSchedules[PL];
if (LSchedule) {
auto *LDomain = isl_schedule_get_domain(LSchedule);
auto *MUPA = mapToDimension(LDomain, LD + 1);
LSchedule = isl_schedule_insert_partial_schedule(LSchedule, MUPA);
PSchedulePair.first = combineInSequence(PSchedulePair.first, LSchedule);
}
PSchedulePair.second += NumVisited;
L = PL;
LD--;
NumVisited = PSchedulePair.second;
LSchedule = PSchedulePair.first;
}
L = PL;
LD--;
NumVisited = PSchedulePair.second;
LSchedule = PSchedulePair.first;
}
}