Skip to content
Snippets Groups Projects
Commit 3a3a52de authored by Dan Gohman's avatar Dan Gohman
Browse files

Optimize ScheduleDAGRRList's topological sort to use one pass instead

of two, and to not need a scratch std::vector. Also, compute the ordering
immediately in the result array, instead of in another scratch std::vector
that is copied to the result array.

llvm-svn: 55421
parent 9cbdedcb
No related branches found
No related tags found
No related merge requests found
...@@ -448,18 +448,19 @@ inline void ScheduleDAGRRList::Allocate(int n, int index) { ...@@ -448,18 +448,19 @@ inline void ScheduleDAGRRList::Allocate(int n, int index) {
/// immediately after X in Index2Node. /// immediately after X in Index2Node.
void ScheduleDAGRRList::InitDAGTopologicalSorting() { void ScheduleDAGRRList::InitDAGTopologicalSorting() {
unsigned DAGSize = SUnits.size(); unsigned DAGSize = SUnits.size();
std::vector<unsigned> InDegree(DAGSize);
std::vector<SUnit*> WorkList; std::vector<SUnit*> WorkList;
WorkList.reserve(DAGSize); WorkList.reserve(DAGSize);
std::vector<SUnit*> TopOrder;
TopOrder.reserve(DAGSize); Index2Node.resize(DAGSize);
Node2Index.resize(DAGSize);
// Initialize the data structures. // Initialize the data structures.
for (unsigned i = 0, e = DAGSize; i != e; ++i) { for (unsigned i = 0, e = DAGSize; i != e; ++i) {
SUnit *SU = &SUnits[i]; SUnit *SU = &SUnits[i];
int NodeNum = SU->NodeNum; int NodeNum = SU->NodeNum;
unsigned Degree = SU->Succs.size(); unsigned Degree = SU->Succs.size();
InDegree[NodeNum] = Degree; // Temporarily use the Node2Index array as scratch space for degree counts.
Node2Index[NodeNum] = Degree;
// Is it a node without dependencies? // Is it a node without dependencies?
if (Degree == 0) { if (Degree == 0) {
...@@ -469,35 +470,23 @@ void ScheduleDAGRRList::InitDAGTopologicalSorting() { ...@@ -469,35 +470,23 @@ void ScheduleDAGRRList::InitDAGTopologicalSorting() {
} }
} }
int Id = DAGSize;
while (!WorkList.empty()) { while (!WorkList.empty()) {
SUnit *SU = WorkList.back(); SUnit *SU = WorkList.back();
WorkList.pop_back(); WorkList.pop_back();
TopOrder.push_back(SU); Allocate(SU->NodeNum, --Id);
for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); for (SUnit::const_pred_iterator I = SU->Preds.begin(), E = SU->Preds.end();
I != E; ++I) { I != E; ++I) {
SUnit *SU = I->Dep; SUnit *SU = I->Dep;
if (!--InDegree[SU->NodeNum]) if (!--Node2Index[SU->NodeNum])
// If all dependencies of the node are processed already, // If all dependencies of the node are processed already,
// then the node can be computed now. // then the node can be computed now.
WorkList.push_back(SU); WorkList.push_back(SU);
} }
} }
// Second pass, assign the actual topological order as node ids.
int Id = 0;
Index2Node.clear();
Node2Index.clear();
Index2Node.resize(DAGSize);
Node2Index.resize(DAGSize);
Visited.resize(DAGSize); Visited.resize(DAGSize);
for (std::vector<SUnit*>::reverse_iterator TI = TopOrder.rbegin(),
TE = TopOrder.rend();TI != TE; ++TI) {
Allocate((*TI)->NodeNum, Id);
Id++;
}
#ifndef NDEBUG #ifndef NDEBUG
// Check correctness of the ordering // Check correctness of the ordering
for (unsigned i = 0, e = DAGSize; i != e; ++i) { for (unsigned i = 0, e = DAGSize; i != e; ++i) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment