mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-17 03:30:28 +00:00
Optimize SelectionDAG's topological sort to use one pass instead
of two, and to not need a scratch std::vector. Also, use the SelectionDAG's topological sort in LegalizeDAG instead of having a separate implementation. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@55389 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
763d89343b
commit
3200d92947
@ -270,45 +270,6 @@ SelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag)
|
|||||||
"Too many value types for ValueTypeActions to hold!");
|
"Too many value types for ValueTypeActions to hold!");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// ComputeTopDownOrdering - Compute a top-down ordering of the dag, where Order
|
|
||||||
/// contains all of a nodes operands before it contains the node.
|
|
||||||
static void ComputeTopDownOrdering(SelectionDAG &DAG,
|
|
||||||
SmallVector<SDNode*, 64> &Order) {
|
|
||||||
|
|
||||||
DenseMap<SDNode*, unsigned> Visited;
|
|
||||||
std::vector<SDNode*> Worklist;
|
|
||||||
Worklist.reserve(128);
|
|
||||||
|
|
||||||
// Compute ordering from all of the leaves in the graphs, those (like the
|
|
||||||
// entry node) that have no operands.
|
|
||||||
for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
|
|
||||||
E = DAG.allnodes_end(); I != E; ++I) {
|
|
||||||
if (I->getNumOperands() == 0) {
|
|
||||||
Visited[I] = 0 - 1U;
|
|
||||||
Worklist.push_back(I);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!Worklist.empty()) {
|
|
||||||
SDNode *N = Worklist.back();
|
|
||||||
Worklist.pop_back();
|
|
||||||
|
|
||||||
if (++Visited[N] != N->getNumOperands())
|
|
||||||
continue; // Haven't visited all operands yet
|
|
||||||
|
|
||||||
Order.push_back(N);
|
|
||||||
|
|
||||||
// Now that we have N in, add anything that uses it if all of their operands
|
|
||||||
// are now done.
|
|
||||||
Worklist.insert(Worklist.end(), N->use_begin(), N->use_end());
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(Order.size() == Visited.size() &&
|
|
||||||
Order.size() == DAG.allnodes_size() &&
|
|
||||||
"Error: DAG is cyclic!");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void SelectionDAGLegalize::LegalizeDAG() {
|
void SelectionDAGLegalize::LegalizeDAG() {
|
||||||
LastCALLSEQ_END = DAG.getEntryNode();
|
LastCALLSEQ_END = DAG.getEntryNode();
|
||||||
IsLegalizingCall = false;
|
IsLegalizingCall = false;
|
||||||
@ -319,11 +280,11 @@ void SelectionDAGLegalize::LegalizeDAG() {
|
|||||||
// practice however, this causes us to run out of stack space on large basic
|
// practice however, this causes us to run out of stack space on large basic
|
||||||
// blocks. To avoid this problem, compute an ordering of the nodes where each
|
// blocks. To avoid this problem, compute an ordering of the nodes where each
|
||||||
// node is only legalized after all of its operands are legalized.
|
// node is only legalized after all of its operands are legalized.
|
||||||
SmallVector<SDNode*, 64> Order;
|
std::vector<SDNode *> TopOrder;
|
||||||
ComputeTopDownOrdering(DAG, Order);
|
unsigned N = DAG.AssignTopologicalOrder(TopOrder);
|
||||||
|
for (unsigned i = N; i != 0; --i)
|
||||||
for (unsigned i = 0, e = Order.size(); i != e; ++i)
|
HandleOp(SDValue(TopOrder[i-1], 0));
|
||||||
HandleOp(SDValue(Order[i], 0));
|
TopOrder.clear();
|
||||||
|
|
||||||
// Finally, it's possible the root changed. Get the new root.
|
// Finally, it's possible the root changed. Get the new root.
|
||||||
SDValue OldRoot = DAG.getRoot();
|
SDValue OldRoot = DAG.getRoot();
|
||||||
|
@ -4427,40 +4427,35 @@ void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From,
|
|||||||
/// of the SDNodes* in assigned order by reference.
|
/// of the SDNodes* in assigned order by reference.
|
||||||
unsigned SelectionDAG::AssignTopologicalOrder(std::vector<SDNode*> &TopOrder) {
|
unsigned SelectionDAG::AssignTopologicalOrder(std::vector<SDNode*> &TopOrder) {
|
||||||
unsigned DAGSize = AllNodes.size();
|
unsigned DAGSize = AllNodes.size();
|
||||||
std::vector<unsigned> InDegree(DAGSize);
|
|
||||||
std::vector<SDNode*> Sources;
|
std::vector<SDNode*> Sources;
|
||||||
|
|
||||||
// Use a two pass approach to avoid using a std::map which is slow.
|
|
||||||
unsigned Id = 0;
|
|
||||||
for (allnodes_iterator I = allnodes_begin(),E = allnodes_end(); I != E; ++I){
|
for (allnodes_iterator I = allnodes_begin(),E = allnodes_end(); I != E; ++I){
|
||||||
SDNode *N = I;
|
SDNode *N = I;
|
||||||
N->setNodeId(Id++);
|
|
||||||
unsigned Degree = N->use_size();
|
unsigned Degree = N->use_size();
|
||||||
InDegree[N->getNodeId()] = Degree;
|
// Temporarily use the Node Id as scratch space for the degree count.
|
||||||
|
N->setNodeId(Degree);
|
||||||
if (Degree == 0)
|
if (Degree == 0)
|
||||||
Sources.push_back(N);
|
Sources.push_back(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
TopOrder.clear();
|
TopOrder.clear();
|
||||||
TopOrder.reserve(DAGSize);
|
TopOrder.reserve(DAGSize);
|
||||||
|
int Id = 0;
|
||||||
while (!Sources.empty()) {
|
while (!Sources.empty()) {
|
||||||
SDNode *N = Sources.back();
|
SDNode *N = Sources.back();
|
||||||
Sources.pop_back();
|
Sources.pop_back();
|
||||||
TopOrder.push_back(N);
|
TopOrder.push_back(N);
|
||||||
|
N->setNodeId(Id++);
|
||||||
for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
|
for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) {
|
||||||
SDNode *P = I->getVal();
|
SDNode *P = I->getVal();
|
||||||
unsigned Degree = --InDegree[P->getNodeId()];
|
unsigned Degree = P->getNodeId();
|
||||||
|
--Degree;
|
||||||
|
P->setNodeId(Degree);
|
||||||
if (Degree == 0)
|
if (Degree == 0)
|
||||||
Sources.push_back(P);
|
Sources.push_back(P);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Second pass, assign the actual topological order as node ids.
|
|
||||||
Id = 0;
|
|
||||||
for (std::vector<SDNode*>::iterator TI = TopOrder.begin(),TE = TopOrder.end();
|
|
||||||
TI != TE; ++TI)
|
|
||||||
(*TI)->setNodeId(Id++);
|
|
||||||
|
|
||||||
return Id;
|
return Id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user