diff options
author | Chris Lattner <sabre@nondot.org> | 2010-03-02 06:55:04 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2010-03-02 06:55:04 +0000 |
commit | 9732ab6d861d20a1cc739ea875337edb37d88e37 (patch) | |
tree | 610a05ad93728af68c12731b1b1eb2a5ebabce5b /llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | |
parent | 47f2a839ecc1c45cf140381299fde613c447e3f4 (diff) | |
download | bcm5719-llvm-9732ab6d861d20a1cc739ea875337edb37d88e37.tar.gz bcm5719-llvm-9732ab6d861d20a1cc739ea875337edb37d88e37.zip |
factor node morphing out to its own helper method.
llvm-svn: 97558
Diffstat (limited to 'llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp')
-rw-r--r-- | llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 116 |
1 files changed, 62 insertions, 54 deletions
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index b13ef3a02ac..f708ff25832 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1749,6 +1749,66 @@ HandleMergeInputChains(SmallVectorImpl<SDNode*> &ChainNodesMatched, MVT::Other, &InputChains[0], InputChains.size()); } +/// MorphNode - Handle morphing a node in place for the selector. +SDNode *SelectionDAGISel:: +MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTList, + const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo) { + // It is possible we're using MorphNodeTo to replace a node with no + // normal results with one that has a normal result (or we could be + // adding a chain) and the input could have flags and chains as well. + // In this case we need to shifting the operands down. + // FIXME: This is a horrible hack and broken in obscure cases, no worse + // than the old isel though. We should sink this into MorphNodeTo. + int OldFlagResultNo = -1, OldChainResultNo = -1; + + unsigned NTMNumResults = Node->getNumValues(); + if (Node->getValueType(NTMNumResults-1) == MVT::Flag) { + OldFlagResultNo = NTMNumResults-1; + if (NTMNumResults != 1 && + Node->getValueType(NTMNumResults-2) == MVT::Other) + OldChainResultNo = NTMNumResults-2; + } else if (Node->getValueType(NTMNumResults-1) == MVT::Other) + OldChainResultNo = NTMNumResults-1; + + // FIXME: If this matches multiple nodes it will just leave them here + // dead with noone to love them. These dead nodes can block future + // matches (!). + SDNode *Res = CurDAG->MorphNodeTo(Node, ~TargetOpc, VTList, Ops, NumOps); + + // MorphNodeTo can operate in two ways: if an existing node with the + // specified operands exists, it can just return it. Otherwise, it + // updates the node in place to have the requested operands. + if (Res == Node) { + // If we updated the node in place, reset the node ID. To the isel, + // this should be just like a newly allocated machine node. + Res->setNodeId(-1); + } + + unsigned ResNumResults = Res->getNumValues(); + // Move the flag if needed. + if ((EmitNodeInfo & OPFL_FlagOutput) && OldFlagResultNo != -1 && + (unsigned)OldFlagResultNo != ResNumResults-1) + CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldFlagResultNo), + SDValue(Res, ResNumResults-1)); + + if ((EmitNodeInfo & OPFL_FlagOutput) != 0) + --ResNumResults; + + // Move the chain reference if needed. + if ((EmitNodeInfo & OPFL_Chain) && OldChainResultNo != -1 && + (unsigned)OldChainResultNo != ResNumResults-1) + CurDAG->ReplaceAllUsesOfValueWith(SDValue(Node, OldChainResultNo), + SDValue(Res, ResNumResults-1)); + + // Otherwise, no replacement happened because the node already exists. Replace + // Uses of the old node with the new one. + if (Res != Node) + CurDAG->ReplaceAllUsesWith(Node, Res); + + return Res; +} + + struct MatchScope { /// FailIndex - If this match fails, this is the index to continue with. unsigned FailIndex; @@ -2298,60 +2358,8 @@ SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable, } } else { - // It is possible we're using MorphNodeTo to replace a node with no - // normal results with one that has a normal result (or we could be - // adding a chain) and the input could have flags and chains as well. - // In this case we need to shifting the operands down. - // FIXME: This is a horrible hack and broken in obscure cases, no worse - // than the old isel though. We should sink this into MorphNodeTo. - int OldFlagResultNo = -1, OldChainResultNo = -1; - - unsigned NTMNumResults = NodeToMatch->getNumValues(); - if (NodeToMatch->getValueType(NTMNumResults-1) == MVT::Flag) { - OldFlagResultNo = NTMNumResults-1; - if (NTMNumResults != 1 && - NodeToMatch->getValueType(NTMNumResults-2) == MVT::Other) - OldChainResultNo = NTMNumResults-2; - } else if (NodeToMatch->getValueType(NTMNumResults-1) == MVT::Other) - OldChainResultNo = NTMNumResults-1; - - // FIXME: If this matches multiple nodes it will just leave them here - // dead with noone to love them. These dead nodes can block future - // matches (!). - Res = CurDAG->MorphNodeTo(NodeToMatch, ~TargetOpc, VTList, - Ops.data(), Ops.size()); - - // MorphNodeTo can operate in two ways: if an existing node with the - // specified operands exists, it can just return it. Otherwise, it - // updates the node in place to have the requested operands. - if (Res == NodeToMatch) { - // If we updated the node in place, reset the node ID. To the isel, - // this should be just like a newly allocated machine node. - Res->setNodeId(-1); - } - - unsigned ResNumResults = Res->getNumValues(); - // Move the flag if needed. - if ((EmitNodeInfo & OPFL_FlagOutput) && OldFlagResultNo != -1 && - (unsigned)OldFlagResultNo != ResNumResults-1) - CurDAG->ReplaceAllUsesOfValueWith(SDValue(NodeToMatch, - OldFlagResultNo), - SDValue(Res, ResNumResults-1)); - - if ((EmitNodeInfo & OPFL_FlagOutput) != 0) - --ResNumResults; - - // Move the chain reference if needed. - if ((EmitNodeInfo & OPFL_Chain) && OldChainResultNo != -1 && - (unsigned)OldChainResultNo != ResNumResults-1) - CurDAG->ReplaceAllUsesOfValueWith(SDValue(NodeToMatch, - OldChainResultNo), - SDValue(Res, ResNumResults-1)); - - if (Res != NodeToMatch) { - // Otherwise, no replacement happened because the node already exists. - CurDAG->ReplaceAllUsesWith(NodeToMatch, Res); - } + Res = MorphNode(NodeToMatch, TargetOpc, VTList, Ops.data(), Ops.size(), + EmitNodeInfo); } // If the node had chain/flag results, update our notion of the current |