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

Nate Begeman natebegeman at mac.com
Wed Sep 7 16:26:04 PDT 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

DAGCombiner.cpp updated: 1.7 -> 1.8
SelectionDAG.cpp updated: 1.187 -> 1.188
---
Log message:

Another round of dag combiner changes.  This fixes some missing XOR folds
as well as fixing how we replace old values with new values.


---
Diffs of the changes:  (+48 -17)

 DAGCombiner.cpp  |   57 ++++++++++++++++++++++++++++++++++++++++++-------------
 SelectionDAG.cpp |    8 +++----
 2 files changed, 48 insertions(+), 17 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.7 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.8
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.7	Wed Sep  7 11:09:19 2005
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp	Wed Sep  7 18:25:52 2005
@@ -223,11 +223,11 @@
   return false;
 }
 
-// isInvertibleForFree - Return true if there is no cost to emitting the logical
-// inverse of this node.
-static bool isInvertibleForFree(SDOperand N) {
+// isOneUseSetCC - Return true if this is a SetCC-equivalent operation with only
+// one use.  If this is true, it allows the users to invert the operation for
+// free when it is profitable to do so.
+static bool isOneUseSetCC(SDOperand N) {
   SDOperand N0, N1, N2;
-  if (isa<ConstantSDNode>(N.Val)) return true;
   if (isSetCCEquivalent(N, N0, N1, N2) && N.Val->hasOneUse())
     return true;
   return false;
@@ -270,7 +270,7 @@
         DEBUG(std::cerr << "\nReplacing "; N->dump();
               std::cerr << "\nWith: "; RV.Val->dump();
               std::cerr << '\n');
-        DAG.ReplaceAllUsesWith(SDOperand(N, 0), RV);
+        DAG.ReplaceAllUsesWith(N, std::vector<SDOperand>(1, RV));
           
         // Push the new node and any users onto the worklist
         WorkList.push_back(RV.Val);
@@ -347,6 +347,11 @@
   // fold (add c1, c2) -> c1+c2
   if (N0C && N1C)
     return DAG.getConstant(N0C->getValue() + N1C->getValue(), VT);
+  // canonicalize constant to RHS
+  if (N0C && !N1C) {
+    std::swap(N0, N1);
+    std::swap(N0C, N1C);
+  }
   // fold (add x, 0) -> x
   if (N1C && N1C->isNullValue())
     return N0;
@@ -426,6 +431,11 @@
   if (N0C && N1C)
     return DAG.getConstant(N0C->getValue() * N1C->getValue(),
                            N->getValueType(0));
+  // canonicalize constant to RHS
+  if (N0C && !N1C) {
+    std::swap(N0, N1);
+    std::swap(N0C, N1C);
+  }
   // fold (mul x, 0) -> 0
   if (N1C && N1C->isNullValue())
     return N1;
@@ -556,6 +566,11 @@
   // fold (and c1, c2) -> c1&c2
   if (N0C && N1C)
     return DAG.getConstant(N0C->getValue() & N1C->getValue(), VT);
+  // canonicalize constant to RHS
+  if (N0C && !N1C) {
+    std::swap(N0, N1);
+    std::swap(N0C, N1C);
+  }
   // fold (and x, -1) -> x
   if (N1C && N1C->isAllOnesValue())
     return N0;
@@ -593,6 +608,11 @@
   if (N0C && N1C)
     return DAG.getConstant(N0C->getValue() | N1C->getValue(),
                            N->getValueType(0));
+  // canonicalize constant to RHS
+  if (N0C && !N1C) {
+    std::swap(N0, N1);
+    std::swap(N0C, N1C);
+  }
   // fold (or x, 0) -> x
   if (N1C && N1C->isNullValue())
     return N0;
@@ -617,6 +637,11 @@
   // fold (xor c1, c2) -> c1^c2
   if (N0C && N1C)
     return DAG.getConstant(N0C->getValue() ^ N1C->getValue(), VT);
+  // canonicalize constant to RHS
+  if (N0C && !N1C) {
+    std::swap(N0, N1);
+    std::swap(N0C, N1C);
+  }
   // fold (xor x, 0) -> x
   if (N1C && N1C->isNullValue())
     return N0;
@@ -632,22 +657,28 @@
     assert(0 && "Unhandled SetCC Equivalent!");
     abort();
   }
-  // fold !(x or y) -> (!x and !y) iff x or y are freely invertible
-  if (N1C && N1C->isAllOnesValue() && N0.getOpcode() == ISD::OR) {
+  // fold !(x or y) -> (!x and !y) iff x or y are setcc
+  if (N1C && N1C->getValue() == 1 && 
+      (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) {
     SDOperand LHS = N0.getOperand(0), RHS = N0.getOperand(1);
-    if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) {
+    if (isOneUseSetCC(RHS) || isOneUseSetCC(LHS)) {
+      unsigned NewOpcode = N0.getOpcode() == ISD::AND ? ISD::OR : ISD::AND;
       LHS = DAG.getNode(ISD::XOR, VT, LHS, N1);  // RHS = ~LHS
       RHS = DAG.getNode(ISD::XOR, VT, RHS, N1);  // RHS = ~RHS
-      return DAG.getNode(ISD::AND, VT, LHS, RHS);
+      WorkList.push_back(LHS.Val); WorkList.push_back(RHS.Val);
+      return DAG.getNode(NewOpcode, VT, LHS, RHS);
     }
   }
-  // fold !(x and y) -> (!x or !y) iff x or y are freely invertible
-  if (N1C && N1C->isAllOnesValue() && N0.getOpcode() == ISD::AND) {
+  // fold !(x or y) -> (!x and !y) iff x or y are constants
+  if (N1C && N1C->isAllOnesValue() && 
+      (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) {
     SDOperand LHS = N0.getOperand(0), RHS = N0.getOperand(1);
-    if (isInvertibleForFree(RHS) || isInvertibleForFree(LHS)) {
+    if (isa<ConstantSDNode>(RHS) || isa<ConstantSDNode>(LHS)) {
+      unsigned NewOpcode = N0.getOpcode() == ISD::AND ? ISD::OR : ISD::AND;
       LHS = DAG.getNode(ISD::XOR, VT, LHS, N1);  // RHS = ~LHS
       RHS = DAG.getNode(ISD::XOR, VT, RHS, N1);  // RHS = ~RHS
-      return DAG.getNode(ISD::OR, VT, LHS, RHS);
+      WorkList.push_back(LHS.Val); WorkList.push_back(RHS.Val);
+      return DAG.getNode(NewOpcode, VT, LHS, RHS);
     }
   }
   return SDOperand();


Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.187 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.188
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.187	Wed Sep  7 00:37:01 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Wed Sep  7 18:25:52 2005
@@ -1256,7 +1256,6 @@
   ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N2.Val);
   if (N1C) {
     if (N2C) {
-      if (!CombinerEnabled) {
       uint64_t C1 = N1C->getValue(), C2 = N2C->getValue();
       switch (Opcode) {
       case ISD::ADD: return getConstant(C1 + C2, VT);
@@ -1284,7 +1283,6 @@
       case ISD::SRA  : return getConstant(N1C->getSignExtended() >>(int)C2, VT);
       default: break;
       }
-      }
     } else {      // Cannonicalize constant to RHS if commutative
       if (isCommutativeBinOp(Opcode)) {
         std::swap(N1C, N2C);
@@ -1315,6 +1313,7 @@
   if (N2C) {
     uint64_t C2 = N2C->getValue();
 
+    if (!CombinerEnabled) {
     switch (Opcode) {
     case ISD::ADD:
       if (!C2) return N1;         // add X, 0 -> X
@@ -1481,6 +1480,7 @@
       }
       break;
     }
+    }
 
     // Reassociate ((X op C1) op C2) if possible.
     if (N1.getOpcode() == Opcode && isAssociativeBinOp(Opcode))
@@ -1493,7 +1493,6 @@
   ConstantFPSDNode *N2CFP = dyn_cast<ConstantFPSDNode>(N2.Val);
   if (N1CFP) {
     if (N2CFP) {
-      if (!CombinerEnabled) {
       double C1 = N1CFP->getValue(), C2 = N2CFP->getValue();
       switch (Opcode) {
       case ISD::ADD: return getConstantFP(C1 + C2, VT);
@@ -1507,7 +1506,6 @@
         break;
       default: break;
       }
-      }
     } else {      // Cannonicalize constant to RHS if commutative
       if (isCommutativeBinOp(Opcode)) {
         std::swap(N1CFP, N2CFP);
@@ -1515,9 +1513,11 @@
       }
     }
 
+    if (!CombinerEnabled) {
     if (Opcode == ISD::FP_ROUND_INREG)
       return getNode(ISD::FP_EXTEND, VT,
                      getNode(ISD::FP_ROUND, cast<VTSDNode>(N2)->getVT(), N1));
+    }
   }
 
   // Finally, fold operations that do not require constants.






More information about the llvm-commits mailing list