diff options
author | Valery Pykhtin <Valery.Pykhtin@amd.com> | 2017-03-28 05:12:31 +0000 |
---|---|---|
committer | Valery Pykhtin <Valery.Pykhtin@amd.com> | 2017-03-28 05:12:31 +0000 |
commit | 910da13a07a4bf2d3a15ddeb23ff2dced95581fe (patch) | |
tree | 3934a5ef0b52a606399b3f059d63eed6de926ced /llvm/lib/CodeGen/ScheduleDAG.cpp | |
parent | c7479ba86a6daf19e408610204fb55d79d37abc9 (diff) | |
download | bcm5719-llvm-910da13a07a4bf2d3a15ddeb23ff2dced95581fe.tar.gz bcm5719-llvm-910da13a07a4bf2d3a15ddeb23ff2dced95581fe.zip |
MachineScheduler/ScheduleDAG: Add support for GetSubGraph
Patch by Axel Davy (axel.davy@normalesup.org)
Differential revision: https://reviews.llvm.org/D30626
llvm-svn: 298896
Diffstat (limited to 'llvm/lib/CodeGen/ScheduleDAG.cpp')
-rw-r--r-- | llvm/lib/CodeGen/ScheduleDAG.cpp | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/llvm/lib/CodeGen/ScheduleDAG.cpp b/llvm/lib/CodeGen/ScheduleDAG.cpp index 7c8051de540..dc72ac07325 100644 --- a/llvm/lib/CodeGen/ScheduleDAG.cpp +++ b/llvm/lib/CodeGen/ScheduleDAG.cpp @@ -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; |