MachineScheduler/ScheduleDAG: Add support for GetSubGraph

Patch by Axel Davy (axel.davy@normalesup.org)

Differential revision: https://reviews.llvm.org/D30626

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298896 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Valery Pykhtin 2017-03-28 05:12:31 +00:00
parent c0fa0b7573
commit 217a56948a
2 changed files with 89 additions and 0 deletions

View File

@ -715,6 +715,14 @@ class TargetRegisterInfo;
/// Creates the initial topological ordering from the DAG to be scheduled.
void InitDAGTopologicalSorting();
/// Returns an array of SUs that are both in the successor
/// subtree of StartSU and in the predecessor subtree of TargetSU.
/// StartSU and TargetSU are not in the array.
/// Success is false if TargetSU is not in the successor subtree of
/// StartSU, else it is true.
std::vector<int> GetSubGraph(const SUnit &StartSU, const SUnit &TargetSU,
bool &Success);
/// Checks if \p SU is reachable from \p TargetSU.
bool IsReachable(const SUnit *SU, const SUnit *TargetSU);

View File

@ -548,6 +548,87 @@ void ScheduleDAGTopologicalSort::DFS(const SUnit *SU, int UpperBound,
} while (!WorkList.empty());
}
std::vector<int> ScheduleDAGTopologicalSort::GetSubGraph(const SUnit &StartSU,
const SUnit &TargetSU,
bool &Success) {
std::vector<const SUnit*> WorkList;
int LowerBound = Node2Index[StartSU.NodeNum];
int UpperBound = Node2Index[TargetSU.NodeNum];
bool Found = false;
BitVector VisitedBack;
std::vector<int> Nodes;
if (LowerBound > UpperBound) {
Success = false;
return Nodes;
}
WorkList.reserve(SUnits.size());
Visited.reset();
// Starting from StartSU, visit all successors up
// to UpperBound.
WorkList.push_back(&StartSU);
do {
const SUnit *SU = WorkList.back();
WorkList.pop_back();
for (int I = SU->Succs.size()-1; I >= 0; --I) {
const SUnit *Succ = SU->Succs[I].getSUnit();
unsigned s = Succ->NodeNum;
// Edges to non-SUnits are allowed but ignored (e.g. ExitSU).
if (Succ->isBoundaryNode())
continue;
if (Node2Index[s] == UpperBound) {
Found = true;
continue;
}
// Visit successors if not already and in affected region.
if (!Visited.test(s) && Node2Index[s] < UpperBound) {
Visited.set(s);
WorkList.push_back(Succ);
}
}
} while (!WorkList.empty());
if (!Found) {
Success = false;
return Nodes;
}
WorkList.clear();
VisitedBack.resize(SUnits.size());
Found = false;
// Starting from TargetSU, visit all predecessors up
// to LowerBound. SUs that are visited by the two
// passes are added to Nodes.
WorkList.push_back(&TargetSU);
do {
const SUnit *SU = WorkList.back();
WorkList.pop_back();
for (int I = SU->Preds.size()-1; I >= 0; --I) {
const SUnit *Pred = SU->Preds[I].getSUnit();
unsigned s = Pred->NodeNum;
// Edges to non-SUnits are allowed but ignored (e.g. EntrySU).
if (Pred->isBoundaryNode())
continue;
if (Node2Index[s] == LowerBound) {
Found = true;
continue;
}
if (!VisitedBack.test(s) && Visited.test(s)) {
VisitedBack.set(s);
WorkList.push_back(Pred);
Nodes.push_back(s);
}
}
} while (!WorkList.empty());
assert(Found && "Error in SUnit Graph!");
Success = true;
return Nodes;
}
void ScheduleDAGTopologicalSort::Shift(BitVector& Visited, int LowerBound,
int UpperBound) {
std::vector<int> L;