From 3ff1e4db7896a8ccec74800d52a926118d025260 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 2 Mar 2010 06:55:04 +0000 Subject: [PATCH] factor node morphing out to its own helper method. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@97558 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/CodeGen/SelectionDAGISel.h | 2 + lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 116 ++++++++++-------- 2 files changed, 64 insertions(+), 54 deletions(-) diff --git a/include/llvm/CodeGen/SelectionDAGISel.h b/include/llvm/CodeGen/SelectionDAGISel.h index a72fa599684..e9cbb13fa66 100644 --- a/include/llvm/CodeGen/SelectionDAGISel.h +++ b/include/llvm/CodeGen/SelectionDAGISel.h @@ -275,6 +275,8 @@ protected: private: void DoInstructionSelection(); + SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs, + const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo); void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF, MachineModuleInfo *MMI, diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index b13ef3a02ac..f708ff25832 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -1749,6 +1749,66 @@ HandleMergeInputChains(SmallVectorImpl &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