aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-08-16 18:17:10 +0000
committerChris Lattner <sabre@nondot.org>2005-08-16 18:17:10 +0000
commit149c58ce0b94e64faf3c4ccdbf894061cf7d66e1 (patch)
tree2099d0357111156f9e286dbc4ee0da2d5dcad79a
parent1b95095857b78e12138c22e76c7936611c51355b (diff)
Add some methods for dag->dag isel.
Split RemoveNodeFromCSEMaps out of DeleteNodesIfDead to do it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@22801 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/CodeGen/SelectionDAG/LegalizeDAG.cpp2
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp76
2 files changed, 59 insertions, 19 deletions
diff --git a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
index 3d13b21f22..63e7435074 100644
--- a/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
@@ -203,7 +203,7 @@ SDOperand SelectionDAGLegalize::ExpandLegalUINT_TO_FP(SDOperand Op0,
return DAG.getNode(ISD::ADD, DestVT, Tmp1, FudgeInReg);
}
-/// PromoteLegalUINT_TO_FP - This function is responsible for legalizing a
+/// PromoteLegalINT_TO_FP - This function is responsible for legalizing a
/// *INT_TO_FP operation of the specified operand when the target requests that
/// we promote it. At this point, we know that the result and operand types are
/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 993b3ec2aa..e921c12295 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -177,12 +177,40 @@ void SelectionDAG::RemoveDeadNodes(SDNode *N) {
delete DummyNode;
}
+
void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
if (!N->use_empty())
return;
// Okay, we really are going to delete this node. First take this out of the
// appropriate CSE map.
+ RemoveNodeFromCSEMaps(N);
+
+ // Next, brutally remove the operand list. This is safe to do, as there are
+ // no cycles in the graph.
+ while (!N->Operands.empty()) {
+ SDNode *O = N->Operands.back().Val;
+ N->Operands.pop_back();
+ O->removeUser(N);
+
+ // Now that we removed this operand, see if there are no uses of it left.
+ DeleteNodeIfDead(O, NodeSet);
+ }
+
+ // Remove the node from the nodes set and delete it.
+ std::set<SDNode*> &AllNodeSet = *(std::set<SDNode*>*)NodeSet;
+ AllNodeSet.erase(N);
+
+ // Now that the node is gone, check to see if any of the operands of this node
+ // are dead now.
+ delete N;
+}
+
+/// RemoveNodeFromCSEMaps - Take the specified node out of the CSE map that
+/// correspond to it. This is useful when we're about to delete or repurpose
+/// the node. We don't want future request for structurally identical nodes
+/// to return N anymore.
+void SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) {
switch (N->getOpcode()) {
case ISD::Constant:
Constants.erase(std::make_pair(cast<ConstantSDNode>(N)->getValue(),
@@ -253,24 +281,6 @@ void SelectionDAG::DeleteNodeIfDead(SDNode *N, void *NodeSet) {
}
break;
}
-
- // Next, brutally remove the operand list.
- while (!N->Operands.empty()) {
- SDNode *O = N->Operands.back().Val;
- N->Operands.pop_back();
- O->removeUser(N);
-
- // Now that we removed this operand, see if there are no uses of it left.
- DeleteNodeIfDead(O, NodeSet);
- }
-
- // Remove the node from the nodes set and delete it.
- std::set<SDNode*> &AllNodeSet = *(std::set<SDNode*>*)NodeSet;
- AllNodeSet.erase(N);
-
- // Now that the node is gone, check to see if any of the operands of this node
- // are dead now.
- delete N;
}
@@ -1679,6 +1689,36 @@ SDOperand SelectionDAG::getNode(unsigned Opcode,
return SDOperand(N, 0);
}
+
+/// SelectNodeTo - These are used for target selectors to *mutate* the
+/// specified node to have the specified return type, Target opcode, and
+/// operands. Note that target opcodes are stored as
+/// ISD::BUILTIN_OP_END+TargetOpcode in the node opcode field.
+void SelectionDAG::SelectNodeTo(SDNode *N, MVT::ValueType VT,
+ unsigned TargetOpc, SDOperand Op1) {
+ RemoveNodeFromCSEMaps(N);
+ N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
+ N->setValueTypes(VT);
+ N->setOperands(Op1);
+}
+void SelectionDAG::SelectNodeTo(SDNode *N, MVT::ValueType VT,
+ unsigned TargetOpc, SDOperand Op1,
+ SDOperand Op2) {
+ RemoveNodeFromCSEMaps(N);
+ N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
+ N->setValueTypes(VT);
+ N->setOperands(Op1, Op2);
+}
+void SelectionDAG::SelectNodeTo(SDNode *N, MVT::ValueType VT,
+ unsigned TargetOpc, SDOperand Op1,
+ SDOperand Op2, SDOperand Op3) {
+ RemoveNodeFromCSEMaps(N);
+ N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
+ N->setValueTypes(VT);
+ N->setOperands(Op1, Op2, Op3);
+}
+
+
/// hasNUsesOfValue - Return true if there are exactly NUSES uses of the
/// indicated value. This method ignores uses of other values defined by this
/// operation.