[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
Chris Lattner
lattner at cs.uiuc.edu
Wed Oct 5 18:20:38 PDT 2005
Changes in directory llvm/lib/CodeGen/SelectionDAG:
LegalizeDAG.cpp updated: 1.192 -> 1.193
---
Log message:
Make the legalizer completely non-recursive
---
Diffs of the changes: (+63 -28)
LegalizeDAG.cpp | 91 ++++++++++++++++++++++++++++++++++++++------------------
1 files changed, 63 insertions(+), 28 deletions(-)
Index: llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.192 llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.193
--- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp:1.192 Wed Oct 5 16:44:10 2005
+++ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp Wed Oct 5 20:20:27 2005
@@ -378,46 +378,74 @@
DAG.getNode(OpToUse, NewOutTy, LegalOp));
}
+/// ComputeTopDownOrdering - Add the specified node to the Order list if it has
+/// not been visited yet and if all of its operands have already been visited.
+static void ComputeTopDownOrdering(SDNode *N, std::vector<SDNode*> &Order,
+ std::map<SDNode*, unsigned> &Visited) {
+ if (++Visited[N] != N->getNumOperands())
+ return; // Haven't visited all operands yet
+
+ Order.push_back(N);
+
+ if (N->hasOneUse()) { // Tail recurse in common case.
+ ComputeTopDownOrdering(*N->use_begin(), Order, Visited);
+ return;
+ }
+
+ // Now that we have N in, add anything that uses it if all of their operands
+ // are now done.
+
+ for (SDNode::use_iterator UI = N->use_begin(), E = N->use_end(); UI != E;++UI)
+ ComputeTopDownOrdering(*UI, Order, Visited);
+}
+
void SelectionDAGLegalize::LegalizeDAG() {
// The legalize process is inherently a bottom-up recursive process (users
// legalize their uses before themselves). Given infinite stack space, we
// could just start legalizing on the root and traverse the whole graph. In
// practice however, this causes us to run out of stack space on large basic
- // blocks. To avoid this problem, legalize the entry node, then all its uses
- // iteratively instead of recursively.
- std::vector<SDOperand> Worklist;
- Worklist.push_back(DAG.getEntryNode());
+ // blocks. To avoid this problem, compute an ordering of the nodes where each
+ // node is only legalized after all of its operands are legalized.
+ std::map<SDNode*, unsigned> Visited;
+ std::vector<SDNode*> Order;
- while (!Worklist.empty()) {
- SDOperand Node = Worklist.back();
- Worklist.pop_back();
-
- if (LegalizedNodes.count(Node)) continue;
-
- for (SDNode::use_iterator UI = Node.Val->use_begin(),
- E = Node.Val->use_end(); UI != E; ++UI) {
- // Scan the values. If this use has a value that is a token chain, add it
- // to the worklist.
- SDNode *User = *UI;
- for (unsigned i = 0, e = User->getNumValues(); i != e; ++i)
- if (User->getValueType(i) == MVT::Other) {
- Worklist.push_back(SDOperand(User, i));
- break;
- }
+ // 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;
+ ComputeTopDownOrdering(*I, Order, Visited);
}
-
- // Finally, legalize this node.
- LegalizeOp(Node);
}
+ assert(Order.size() == Visited.size() && Order.size() == DAG.allnodes_size()&&
+ "Error: DAG is cyclic!");
+ Visited.clear();
- // Finally, legalize from the root up, to make sure we have legalized
- // everything possible.
+ for (unsigned i = 0, e = Order.size(); i != e; ++i) {
+ SDNode *N = Order[i];
+ switch (getTypeAction(N->getValueType(0))) {
+ default: assert(0 && "Bad type action!");
+ case Legal:
+ LegalizeOp(SDOperand(N, 0));
+ break;
+ case Promote:
+ PromoteOp(SDOperand(N, 0));
+ break;
+ case Expand: {
+ SDOperand X, Y;
+ ExpandOp(SDOperand(N, 0), X, Y);
+ break;
+ }
+ }
+ }
+
+ // Finally, it's possible the root changed. Get the new root.
SDOperand OldRoot = DAG.getRoot();
- SDOperand NewRoot = LegalizeOp(OldRoot);
-
- DAG.setRoot(NewRoot);
+ assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?");
+ DAG.setRoot(LegalizedNodes[OldRoot]);
ExpandedNodes.clear();
LegalizedNodes.clear();
@@ -492,9 +520,16 @@
abort();
case ISD::EntryToken:
case ISD::FrameIndex:
+ case ISD::TargetFrameIndex:
+ case ISD::Register:
+ case ISD::TargetConstant:
case ISD::GlobalAddress:
case ISD::ExternalSymbol:
case ISD::ConstantPool: // Nothing to do.
+ case ISD::BasicBlock:
+ case ISD::CONDCODE:
+ case ISD::VALUETYPE:
+ case ISD::SRCVALUE:
assert(isTypeLegal(Node->getValueType(0)) && "This must be legal!");
break;
case ISD::AssertSext:
More information about the llvm-commits
mailing list