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

Nate Begeman natebegeman at mac.com
Thu Feb 2 22:47:08 PST 2006



Changes in directory llvm/lib/CodeGen/SelectionDAG:

DAGCombiner.cpp updated: 1.93 -> 1.94
---
Log message:

Add common code for reassociating ops in the dag combiner


---
Diffs of the changes:  (+55 -50)

 DAGCombiner.cpp |  105 +++++++++++++++++++++++++++++---------------------------
 1 files changed, 55 insertions(+), 50 deletions(-)


Index: llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.93 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.94
--- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp:1.93	Thu Feb  2 01:17:31 2006
+++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp	Fri Feb  3 00:46:56 2006
@@ -33,7 +33,6 @@
 // FIXME: divide by zero is currently left unfolded.  do we want to turn this
 //        into an undef?
 // FIXME: select ne (select cc, 1, 0), 0, true, false -> select cc, true, false
-// FIXME: reassociate (X+C)+Y  into (X+Y)+C  if the inner expression has one use
 // 
 //===----------------------------------------------------------------------===//
 
@@ -179,6 +178,8 @@
     SDOperand visitLOCATION(SDNode *N);
     SDOperand visitDEBUGLOC(SDNode *N);
 
+    SDOperand ReassociateOps(unsigned Opc, SDOperand LHS, SDOperand RHS);
+    
     bool SimplifySelectOps(SDNode *SELECT, SDOperand LHS, SDOperand RHS);
     SDOperand SimplifySelect(SDOperand N0, SDOperand N1, SDOperand N2);
     SDOperand SimplifySelectCC(SDOperand N0, SDOperand N1, SDOperand N2, 
@@ -418,6 +419,37 @@
   }
 }
 
+SDOperand DAGCombiner::ReassociateOps(unsigned Opc, SDOperand N0, SDOperand N1){
+  MVT::ValueType VT = N0.getValueType();
+  // reassoc. (op (op x, c1), y) -> (op (op x, y), c1) iff x+c1 has one use
+  // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2))
+  if (N0.getOpcode() == Opc && isa<ConstantSDNode>(N0.getOperand(1))) {
+    if (isa<ConstantSDNode>(N1)) {
+      SDOperand OpNode = DAG.getNode(Opc, VT, N0.getOperand(1), N1);
+      WorkList.push_back(OpNode.Val);
+      return DAG.getNode(Opc, VT, OpNode, N0.getOperand(0));
+    } else if (N0.hasOneUse()) {
+      SDOperand OpNode = DAG.getNode(Opc, VT, N0.getOperand(0), N1);
+      WorkList.push_back(OpNode.Val);
+      return DAG.getNode(Opc, VT, OpNode, N0.getOperand(1));
+    }
+  }
+  // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one use
+  // reassoc. (op c2, (op x, c1)) -> (op x, (op c1, c2))
+  if (N1.getOpcode() == Opc && isa<ConstantSDNode>(N1.getOperand(1))) {
+    if (isa<ConstantSDNode>(N0)) {
+      SDOperand OpNode = DAG.getNode(Opc, VT, N1.getOperand(1), N0);
+      WorkList.push_back(OpNode.Val);
+      return DAG.getNode(Opc, VT, OpNode, N1.getOperand(0));
+    } else if (N1.hasOneUse()) {
+      SDOperand OpNode = DAG.getNode(Opc, VT, N1.getOperand(0), N0);
+      WorkList.push_back(OpNode.Val);
+      return DAG.getNode(Opc, VT, OpNode, N1.getOperand(1));
+    }
+  }
+  return SDOperand();
+}
+
 void DAGCombiner::Run(bool RunningAfterLegalize) {
   // set the instance variable, so that the various visit routines may use it.
   AfterLegalize = RunningAfterLegalize;
@@ -587,25 +619,16 @@
   // fold (add x, 0) -> x
   if (N1C && N1C->isNullValue())
     return N0;
-  // fold (add (add x, c1), c2) -> (add x, c1+c2)
-  if (N1C && N0.getOpcode() == ISD::ADD) {
-    ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
-    ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
-    if (N00C)
-      return DAG.getNode(ISD::ADD, VT, N0.getOperand(1),
-                         DAG.getConstant(N1C->getValue()+N00C->getValue(), VT));
-    if (N01C)
-      return DAG.getNode(ISD::ADD, VT, N0.getOperand(0),
-                         DAG.getConstant(N1C->getValue()+N01C->getValue(), VT));
-  }
-  
   // fold ((c1-A)+c2) -> (c1+c2)-A
   if (N1C && N0.getOpcode() == ISD::SUB)
     if (ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0.getOperand(0)))
       return DAG.getNode(ISD::SUB, VT,
                          DAG.getConstant(N1C->getValue()+N0C->getValue(), VT),
                          N0.getOperand(1));
-  
+  // reassociate add
+  SDOperand RADD = ReassociateOps(ISD::ADD, N0, N1);
+  if (RADD.Val != 0)
+    return RADD;
   // fold ((0-A) + B) -> B-A
   if (N0.getOpcode() == ISD::SUB && isa<ConstantSDNode>(N0.getOperand(0)) &&
       cast<ConstantSDNode>(N0.getOperand(0))->isNullValue())
@@ -678,19 +701,10 @@
                             DAG.getConstant(Log2_64(-N1C->getSignExtended()),
                                             TLI.getShiftAmountTy())));
   }
-  
-  
-  // fold (mul (mul x, c1), c2) -> (mul x, c1*c2)
-  if (N1C && N0.getOpcode() == ISD::MUL) {
-    ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
-    ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
-    if (N00C)
-      return DAG.getNode(ISD::MUL, VT, N0.getOperand(1),
-                         DAG.getConstant(N1C->getValue()*N00C->getValue(), VT));
-    if (N01C)
-      return DAG.getNode(ISD::MUL, VT, N0.getOperand(0),
-                         DAG.getConstant(N1C->getValue()*N01C->getValue(), VT));
-  }
+  // reassociate mul
+  SDOperand RMUL = ReassociateOps(ISD::MUL, N0, N1);
+  if (RMUL.Val != 0)
+    return RMUL;
   return SDOperand();
 }
 
@@ -866,17 +880,10 @@
   if (N1C && 
       TLI.MaskedValueIsZero(N0, ~N1C->getValue() & (~0ULL>>(64-OpSizeInBits))))
     return N0;
-  // fold (and (and x, c1), c2) -> (and x, c1^c2)
-  if (N1C && N0.getOpcode() == ISD::AND) {
-    ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
-    ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
-    if (N00C)
-      return DAG.getNode(ISD::AND, VT, N0.getOperand(1),
-                         DAG.getConstant(N1C->getValue()&N00C->getValue(), VT));
-    if (N01C)
-      return DAG.getNode(ISD::AND, VT, N0.getOperand(0),
-                         DAG.getConstant(N1C->getValue()&N01C->getValue(), VT));
-  }
+  // reassociate and
+  SDOperand RAND = ReassociateOps(ISD::AND, N0, N1);
+  if (RAND.Val != 0)
+    return RAND;
   // fold (and (sign_extend_inreg x, i16 to i32), 1) -> (and x, 1)
   if (N1C && N0.getOpcode() == ISD::SIGN_EXTEND_INREG) {
     unsigned ExtendBits =
@@ -1031,19 +1038,13 @@
   if (N1C && 
       TLI.MaskedValueIsZero(N0,~N1C->getValue() & (~0ULL>>(64-OpSizeInBits))))
     return N1;
-  // fold (or (or x, c1), c2) -> (or x, c1|c2)
-  if (N1C && N0.getOpcode() == ISD::OR) {
-    ConstantSDNode *N00C = dyn_cast<ConstantSDNode>(N0.getOperand(0));
-    ConstantSDNode *N01C = dyn_cast<ConstantSDNode>(N0.getOperand(1));
-    if (N00C)
-      return DAG.getNode(ISD::OR, VT, N0.getOperand(1),
-                         DAG.getConstant(N1C->getValue()|N00C->getValue(), VT));
-    if (N01C)
-      return DAG.getNode(ISD::OR, VT, N0.getOperand(0),
-                         DAG.getConstant(N1C->getValue()|N01C->getValue(), VT));
-  } else if (N1C && N0.getOpcode() == ISD::AND && N0.Val->hasOneUse() &&
+  // reassociate or
+  SDOperand ROR = ReassociateOps(ISD::OR, N0, N1);
+  if (ROR.Val != 0)
+    return ROR;
+  // Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2)
+  if (N1C && N0.getOpcode() == ISD::AND && N0.Val->hasOneUse() &&
              isa<ConstantSDNode>(N0.getOperand(1))) {
-    // Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2)
     ConstantSDNode *C1 = cast<ConstantSDNode>(N0.getOperand(1));
     return DAG.getNode(ISD::AND, VT, DAG.getNode(ISD::OR, VT, N0.getOperand(0),
                                                  N1),
@@ -1160,6 +1161,10 @@
   // fold (xor x, 0) -> x
   if (N1C && N1C->isNullValue())
     return N0;
+  // reassociate xor
+  SDOperand RXOR = ReassociateOps(ISD::XOR, N0, N1);
+  if (RXOR.Val != 0)
+    return RXOR;
   // fold !(x cc y) -> (x !cc y)
   if (N1C && N1C->getValue() == 1 && isSetCCEquivalent(N0, LHS, RHS, CC)) {
     bool isInt = MVT::isInteger(LHS.getValueType());






More information about the llvm-commits mailing list