Changes in directory llvm/lib/CodeGen/SelectionDAG:

SelectionDAG.cpp updated: 1.220 -> 1.221
---
Log message:

This is a bugfix for SelectNodeTo.  In certain situations, we could be
selecting a node and use a mix of getTargetNode() and SelectNodeTo.  Because
SelectNodeTo didn't check the CSE maps for a preexisting node and didn't insert
its result into the CSE maps, we would sometimes miss a CSE opportunity.

This is extremely rare, but worth fixing for completeness.



---
Diffs of the changes:  (+110 -0)

 SelectionDAG.cpp |  110 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 110 insertions(+)


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.220 
llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.221
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.220        Wed Nov 30 
16:45:14 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp      Thu Dec  1 12:00:57 2005
@@ -1415,40 +1415,74 @@
 /// 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.
+///
+/// Note that SelectNodeTo returns the resultant node.  If there is already a
+/// node of the specified opcode and operands, it returns that node instead of
+/// the current one.
 SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                      MVT::ValueType VT) {
+  // If an identical node already exists, use it.
+  SDNode *&ON = NullaryOps[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc, VT)];
+  if (ON) return SDOperand(ON, 0);
+  
   RemoveNodeFromCSEMaps(N);
+  
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   N->setValueTypes(VT);
+
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 
 SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                      MVT::ValueType VT, SDOperand Op1) {
+  // If an identical node already exists, use it.
+  SDNode *&ON = UnaryOps[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc,
+                                        std::make_pair(Op1, VT))];
+  if (ON) return SDOperand(ON, 0);
+  
   RemoveNodeFromCSEMaps(N);
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   N->setValueTypes(VT);
   N->setOperands(Op1);
+  
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 
 SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                      MVT::ValueType VT, SDOperand Op1,
                                      SDOperand Op2) {
+  // If an identical node already exists, use it.
+  SDNode *&ON = BinaryOps[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc,
+                                         std::make_pair(Op1, Op2))];
+  if (ON) return SDOperand(ON, 0);
+  
   RemoveNodeFromCSEMaps(N);
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   N->setValueTypes(VT);
   N->setOperands(Op1, Op2);
+  
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 
 SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc,
                                      MVT::ValueType VT, SDOperand Op1,
                                      SDOperand Op2, SDOperand Op3) {
+  // If an identical node already exists, use it.
+  std::vector<SDOperand> OpList;
+  OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3);
+  SDNode *&ON = OneResultNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc,
+                                              std::make_pair(VT, OpList))];
+  if (ON) return SDOperand(ON, 0);
+  
   RemoveNodeFromCSEMaps(N);
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   N->setValueTypes(VT);
   N->setOperands(Op1, Op2, Op3);
+
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 
@@ -1456,10 +1490,20 @@
                                      MVT::ValueType VT, SDOperand Op1,
                                      SDOperand Op2, SDOperand Op3,
                                      SDOperand Op4) {
+  // If an identical node already exists, use it.
+  std::vector<SDOperand> OpList;
+  OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3);
+  OpList.push_back(Op4);
+  SDNode *&ON = OneResultNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc,
+                                              std::make_pair(VT, OpList))];
+  if (ON) return SDOperand(ON, 0);
+  
   RemoveNodeFromCSEMaps(N);
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   N->setValueTypes(VT);
   N->setOperands(Op1, Op2, Op3, Op4);
+
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 
@@ -1467,10 +1511,20 @@
                                      MVT::ValueType VT, SDOperand Op1,
                                      SDOperand Op2, SDOperand Op3,SDOperand 
Op4,
                                      SDOperand Op5) {
+  // If an identical node already exists, use it.
+  std::vector<SDOperand> OpList;
+  OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3);
+  OpList.push_back(Op4); OpList.push_back(Op5);
+  SDNode *&ON = OneResultNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc,
+                                              std::make_pair(VT, OpList))];
+  if (ON) return SDOperand(ON, 0);
+  
   RemoveNodeFromCSEMaps(N);
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   N->setValueTypes(VT);
   N->setOperands(Op1, Op2, Op3, Op4, Op5);
+  
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 
@@ -1478,20 +1532,41 @@
                                      MVT::ValueType VT, SDOperand Op1,
                                      SDOperand Op2, SDOperand Op3,SDOperand 
Op4,
                                      SDOperand Op5, SDOperand Op6) {
+  // If an identical node already exists, use it.
+  std::vector<SDOperand> OpList;
+  OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3);
+  OpList.push_back(Op4); OpList.push_back(Op5); OpList.push_back(Op6);
+  SDNode *&ON = OneResultNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc,
+                                              std::make_pair(VT, OpList))];
+  if (ON) return SDOperand(ON, 0);
+
   RemoveNodeFromCSEMaps(N);
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   N->setValueTypes(VT);
   N->setOperands(Op1, Op2, Op3, Op4, Op5, Op6);
+  
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 
 SDOperand SelectionDAG::SelectNodeTo(SDNode *N, unsigned TargetOpc, 
                                      MVT::ValueType VT1, MVT::ValueType VT2,
                                      SDOperand Op1, SDOperand Op2) {
+  // If an identical node already exists, use it.
+  std::vector<SDOperand> OpList;
+  OpList.push_back(Op1); OpList.push_back(Op2); 
+  std::vector<MVT::ValueType> VTList;
+  VTList.push_back(VT1); VTList.push_back(VT2);
+  SDNode *&ON = ArbitraryNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc,
+                                              std::make_pair(VTList, OpList))];
+  if (ON) return SDOperand(ON, 0);
+
   RemoveNodeFromCSEMaps(N);
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   setNodeValueTypes(N, VT1, VT2);
   N->setOperands(Op1, Op2);
+  
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 
@@ -1499,10 +1574,21 @@
                                      MVT::ValueType VT1, MVT::ValueType VT2,
                                      SDOperand Op1, SDOperand Op2, 
                                      SDOperand Op3) {
+  // If an identical node already exists, use it.
+  std::vector<SDOperand> OpList;
+  OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3);
+  std::vector<MVT::ValueType> VTList;
+  VTList.push_back(VT1); VTList.push_back(VT2);
+  SDNode *&ON = ArbitraryNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc,
+                                              std::make_pair(VTList, OpList))];
+  if (ON) return SDOperand(ON, 0);
+
   RemoveNodeFromCSEMaps(N);
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   setNodeValueTypes(N, VT1, VT2);
   N->setOperands(Op1, Op2, Op3);
+  
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 
@@ -1510,10 +1596,22 @@
                                      MVT::ValueType VT1, MVT::ValueType VT2,
                                      SDOperand Op1, SDOperand Op2,
                                      SDOperand Op3, SDOperand Op4) {
+  // If an identical node already exists, use it.
+  std::vector<SDOperand> OpList;
+  OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3);
+  OpList.push_back(Op4);
+  std::vector<MVT::ValueType> VTList;
+  VTList.push_back(VT1); VTList.push_back(VT2);
+  SDNode *&ON = ArbitraryNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc,
+                                              std::make_pair(VTList, OpList))];
+  if (ON) return SDOperand(ON, 0);
+
   RemoveNodeFromCSEMaps(N);
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   setNodeValueTypes(N, VT1, VT2);
   N->setOperands(Op1, Op2, Op3, Op4);
+
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 
@@ -1522,10 +1620,22 @@
                                      SDOperand Op1, SDOperand Op2,
                                      SDOperand Op3, SDOperand Op4, 
                                      SDOperand Op5) {
+  // If an identical node already exists, use it.
+  std::vector<SDOperand> OpList;
+  OpList.push_back(Op1); OpList.push_back(Op2); OpList.push_back(Op3);
+  OpList.push_back(Op4); OpList.push_back(Op5);
+  std::vector<MVT::ValueType> VTList;
+  VTList.push_back(VT1); VTList.push_back(VT2);
+  SDNode *&ON = ArbitraryNodes[std::make_pair(ISD::BUILTIN_OP_END+TargetOpc,
+                                              std::make_pair(VTList, OpList))];
+  if (ON) return SDOperand(ON, 0);
+
   RemoveNodeFromCSEMaps(N);
   N->MorphNodeTo(ISD::BUILTIN_OP_END+TargetOpc);
   setNodeValueTypes(N, VT1, VT2);
   N->setOperands(Op1, Op2, Op3, Op4, Op5);
+  
+  ON = N;   // Memoize the new node.
   return SDOperand(N, 0);
 }
 



_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to