forked from OSchip/llvm-project
Make the legalizer completely non-recursive
llvm-svn: 23642
This commit is contained in:
parent
558beb3729
commit
4bbbb9eed7
|
@ -378,46 +378,74 @@ SDOperand SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDOperand LegalOp,
|
||||||
DAG.getNode(OpToUse, NewOutTy, LegalOp));
|
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() {
|
void SelectionDAGLegalize::LegalizeDAG() {
|
||||||
// The legalize process is inherently a bottom-up recursive process (users
|
// The legalize process is inherently a bottom-up recursive process (users
|
||||||
// legalize their uses before themselves). Given infinite stack space, we
|
// legalize their uses before themselves). Given infinite stack space, we
|
||||||
// could just start legalizing on the root and traverse the whole graph. In
|
// 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
|
// 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
|
// blocks. To avoid this problem, compute an ordering of the nodes where each
|
||||||
// iteratively instead of recursively.
|
// node is only legalized after all of its operands are legalized.
|
||||||
std::vector<SDOperand> Worklist;
|
std::map<SDNode*, unsigned> Visited;
|
||||||
Worklist.push_back(DAG.getEntryNode());
|
std::vector<SDNode*> Order;
|
||||||
|
|
||||||
while (!Worklist.empty()) {
|
// Compute ordering from all of the leaves in the graphs, those (like the
|
||||||
SDOperand Node = Worklist.back();
|
// entry node) that have no operands.
|
||||||
Worklist.pop_back();
|
for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(),
|
||||||
|
E = DAG.allnodes_end(); I != E; ++I) {
|
||||||
if (LegalizedNodes.count(Node)) continue;
|
if ((*I)->getNumOperands() == 0) {
|
||||||
|
Visited[*I] = 0 - 1U;
|
||||||
for (SDNode::use_iterator UI = Node.Val->use_begin(),
|
ComputeTopDownOrdering(*I, Order, Visited);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
for (unsigned i = 0, e = Order.size(); i != e; ++i) {
|
||||||
// everything possible.
|
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 OldRoot = DAG.getRoot();
|
||||||
SDOperand NewRoot = LegalizeOp(OldRoot);
|
assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?");
|
||||||
|
DAG.setRoot(LegalizedNodes[OldRoot]);
|
||||||
DAG.setRoot(NewRoot);
|
|
||||||
|
|
||||||
ExpandedNodes.clear();
|
ExpandedNodes.clear();
|
||||||
LegalizedNodes.clear();
|
LegalizedNodes.clear();
|
||||||
|
@ -492,9 +520,16 @@ SDOperand SelectionDAGLegalize::LegalizeOp(SDOperand Op) {
|
||||||
abort();
|
abort();
|
||||||
case ISD::EntryToken:
|
case ISD::EntryToken:
|
||||||
case ISD::FrameIndex:
|
case ISD::FrameIndex:
|
||||||
|
case ISD::TargetFrameIndex:
|
||||||
|
case ISD::Register:
|
||||||
|
case ISD::TargetConstant:
|
||||||
case ISD::GlobalAddress:
|
case ISD::GlobalAddress:
|
||||||
case ISD::ExternalSymbol:
|
case ISD::ExternalSymbol:
|
||||||
case ISD::ConstantPool: // Nothing to do.
|
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!");
|
assert(isTypeLegal(Node->getValueType(0)) && "This must be legal!");
|
||||||
break;
|
break;
|
||||||
case ISD::AssertSext:
|
case ISD::AssertSext:
|
||||||
|
|
Loading…
Reference in New Issue