[llvm-commits] CVS: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

Chris Lattner lattner at cs.uiuc.edu
Wed Aug 24 15:44:50 PDT 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

SelectionDAG.cpp updated: 1.160 -> 1.161
---
Log message:

Add ReplaceAllUsesWith that can take a vector of replacement values.
Add some foldings to hopefully help the illegal setcc issue, and move some code around.


---
Diffs of the changes:  (+90 -15)

 SelectionDAG.cpp |  105 +++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 90 insertions(+), 15 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.160 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.161
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.160	Wed Aug 24 11:46:55 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Wed Aug 24 17:44:39 2005
@@ -534,8 +534,7 @@
       case ISD::SETGE:  return getConstant((int64_t)C1 >= (int64_t)C2, VT);
       }
     } else {
-      // If the LHS is a ZERO_EXTEND and if this is an ==/!= comparison, perform
-      // the comparison on the input.
+      // If the LHS is a ZERO_EXTEND, perform the comparison on the input.
       if (N1.getOpcode() == ISD::ZERO_EXTEND) {
         unsigned InSize = MVT::getSizeInBits(N1.getOperand(0).getValueType());
 
@@ -577,6 +576,25 @@
         default:
           break;   // todo, be more careful with signed comparisons
         }
+      } else if (N1.getOpcode() == ISD::SIGN_EXTEND_INREG &&
+                 (Cond == ISD::SETEQ || Cond == ISD::SETNE)) {
+        MVT::ValueType ExtSrcTy = cast<VTSDNode>(N1.getOperand(1))->getVT();
+        unsigned ExtSrcTyBits = MVT::getSizeInBits(ExtSrcTy);
+        MVT::ValueType ExtDstTy = N1.getValueType();
+        unsigned ExtDstTyBits = MVT::getSizeInBits(ExtDstTy);
+        
+        // If the extended part has any inconsistent bits, it cannot ever
+        // compare equal.  In other words, they have to be all ones or all
+        // zeros.
+        uint64_t ExtBits =
+          (~0ULL >> 64-ExtSrcTyBits) & (~0ULL << (ExtDstTyBits-1));
+        if ((C2 & ExtBits) != 0 && (C2 & ExtBits) != ExtBits)
+          return getConstant(Cond == ISD::SETNE, VT);
+        
+        // Otherwise, make this a use of a zext.
+        return getSetCC(VT, getZeroExtendInReg(N1.getOperand(0), ExtSrcTy),
+                        getConstant(C2 & (~0ULL >> 64-ExtSrcTyBits), ExtDstTy),
+                        Cond);
       }
 
       uint64_t MinVal, MaxVal;
@@ -1689,18 +1707,6 @@
 SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
                                 SDOperand N1, SDOperand N2, SDOperand N3,
                                 SDOperand N4, SDOperand N5) {
-  if (ISD::SELECT_CC == Opcode) {
-    assert(N1.getValueType() == N2.getValueType() &&
-           "LHS and RHS of condition must have same type!");
-    assert(N3.getValueType() == N4.getValueType() &&
-           "True and False arms of SelectCC must have same type!");
-    assert(N3.getValueType() == VT &&
-           "select_cc node must be of same type as true and false value!");
-    SDOperand Simp = SimplifySelectCC(N1, N2, N3, N4, 
-                                      cast<CondCodeSDNode>(N5)->get());
-    if (Simp.Val) return Simp;
-  }
-        
   std::vector<SDOperand> Ops;
   Ops.reserve(5);
   Ops.push_back(N1);
@@ -1768,6 +1774,40 @@
            "Can't do FP-INT conversion!");
     break;
   }
+  case ISD::SELECT_CC: {
+    assert(Ops.size() == 5 && "TRUNCSTORE takes 5 operands!");
+    assert(Ops[0].getValueType() == Ops[1].getValueType() &&
+           "LHS and RHS of condition must have same type!");
+    assert(Ops[2].getValueType() == Ops[3].getValueType() &&
+           "True and False arms of SelectCC must have same type!");
+    assert(Ops[2].getValueType() == VT &&
+           "select_cc node must be of same type as true and false value!");
+    SDOperand Simp = SimplifySelectCC(Ops[0], Ops[1], Ops[2], Ops[3], 
+                                      cast<CondCodeSDNode>(Ops[4])->get());
+    if (Simp.Val) return Simp;
+    break;
+  }
+  case ISD::BR_CC: {
+    assert(Ops.size() == 5 && "TRUNCSTORE takes 5 operands!");
+    assert(Ops[2].getValueType() == Ops[3].getValueType() &&
+           "LHS/RHS of comparison should match types!");
+    // Use SimplifySetCC  to simplify SETCC's.
+    SDOperand Simp = SimplifySetCC(MVT::i1, Ops[2], Ops[3],
+                                   cast<CondCodeSDNode>(Ops[1])->get());
+    if (Simp.Val) {
+      if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Simp)) {
+        if (C->getValue() & 1) // Unconditional branch
+          return getNode(ISD::BR, MVT::Other, Ops[0], Ops[4]);
+        else
+          return Ops[0];          // Unconditional Fall through
+      } else if (Simp.Val->getOpcode() == ISD::SETCC) {
+        Ops[2] = Simp.getOperand(0);
+        Ops[3] = Simp.getOperand(1);
+        Ops[1] = Simp.getOperand(2);
+      }
+    }
+    break;
+  }
   }
 
   // Memoize nodes.
@@ -1915,7 +1955,7 @@
     
     for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i)
       if (U->getOperand(i).Val == From) {
-        assert(From->getValueType(U->getOperand(i).ResNo) ==
+        assert(U->getOperand(i).getValueType() ==
                To->getValueType(U->getOperand(i).ResNo));
         From->removeUser(U);
         U->Operands[i].Val = To;
@@ -1930,6 +1970,41 @@
   }
 }
 
+void SelectionDAG::ReplaceAllUsesWith(SDNode *From,
+                                      const std::vector<SDOperand> &To) {
+  assert(From->getNumValues() == To.size() &&
+         "Incorrect number of values to replace with!");
+  if (To.size() == 1 && To[0].ResNo == 0) {
+    // Degenerate case handled above.
+    ReplaceAllUsesWith(From, To[0].Val);
+    return;
+  }
+
+  while (!From->use_empty()) {
+    // Process users until they are all gone.
+    SDNode *U = *From->use_begin();
+    
+    // This node is about to morph, remove its old self from the CSE maps.
+    RemoveNodeFromCSEMaps(U);
+    
+    for (unsigned i = 0, e = U->getNumOperands(); i != e; ++i)
+      if (U->getOperand(i).Val == From) {
+        const SDOperand &ToOp = To[U->getOperand(i).ResNo];
+        assert(U->getOperand(i).getValueType() == ToOp.getValueType());
+        From->removeUser(U);
+        U->Operands[i] = ToOp;
+        ToOp.Val->addUser(U);
+      }
+        
+    // Now that we have modified U, add it back to the CSE maps.  If it already
+    // exists there, recursively merge the results together.
+    if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U))
+      ReplaceAllUsesWith(U, Existing);
+    // U is now dead.
+  }
+}
+
+
 //===----------------------------------------------------------------------===//
 //                              SDNode Class
 //===----------------------------------------------------------------------===//






More information about the llvm-commits mailing list