Refactor a bunch of includes so that TargetMachine.h doesn't have to include
[oota-llvm.git] / lib / CodeGen / SelectionDAG / DAGCombiner.cpp
index 3294b4ca580ea3ba1ea864695870706e69563ea4..0aaee2f04320ae1115cfd74ef64c3f54f80ccfa8 100644 (file)
@@ -76,7 +76,7 @@ namespace {
     SDOperand CombineTo(SDNode *N, const std::vector<SDOperand> &To) {
       ++NodesCombined;
       DEBUG(std::cerr << "\nReplacing "; N->dump();
-            std::cerr << "\nWith: "; To[0].Val->dump();
+            std::cerr << "\nWith: "; To[0].Val->dump(&DAG);
             std::cerr << " and " << To.size()-1 << " other values\n");
       std::vector<SDNode*> NowDead;
       DAG.ReplaceAllUsesWith(N, To, &NowDead);
@@ -128,7 +128,7 @@ namespace {
       // Replace the old value with the new one.
       ++NodesCombined;
       DEBUG(std::cerr << "\nReplacing "; TLO.Old.Val->dump();
-            std::cerr << "\nWith: "; TLO.New.Val->dump());
+            std::cerr << "\nWith: "; TLO.New.Val->dump(&DAG));
 
       std::vector<SDNode*> NowDead;
       DAG.ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, NowDead);
@@ -577,7 +577,7 @@ void DAGCombiner::Run(bool RunningAfterLegalize) {
       // mechanics for us, we have no work to do in this case.
       if (RV.Val != N) {
         DEBUG(std::cerr << "\nReplacing "; N->dump();
-              std::cerr << "\nWith: "; RV.Val->dump();
+              std::cerr << "\nWith: "; RV.Val->dump(&DAG);
               std::cerr << '\n');
         std::vector<SDNode*> NowDead;
         DAG.ReplaceAllUsesWith(N, std::vector<SDOperand>(1, RV), &NowDead);
@@ -680,7 +680,8 @@ SDOperand DAGCombiner::visitTokenFactor(SDNode *N) {
   // If the token factor has two operands and one is the entry token, replace
   // the token factor with the other operand.
   if (N->getNumOperands() == 2) {
-    if (N->getOperand(0).getOpcode() == ISD::EntryToken)
+    if (N->getOperand(0).getOpcode() == ISD::EntryToken ||
+        N->getOperand(0) == N->getOperand(1))
       return N->getOperand(1);
     if (N->getOperand(1).getOpcode() == ISD::EntryToken)
       return N->getOperand(0);
@@ -694,8 +695,11 @@ SDOperand DAGCombiner::visitTokenFactor(SDNode *N) {
       Changed = true;
       for (unsigned j = 0, e = Op.getNumOperands(); j != e; ++j)
         Ops.push_back(Op.getOperand(j));
-    } else {
+    } else if (i == 0 || N->getOperand(i) != N->getOperand(i-1)) {
       Ops.push_back(Op);
+    } else {
+      // Deleted an operand that was the same as the last one.
+      Changed = true;
     }
   }
   if (Changed)
@@ -1049,8 +1053,9 @@ SDOperand DAGCombiner::SimplifyBinOpWithSameOpcodeHands(SDNode *N) {
   // fold (OP (zext x), (zext y)) -> (zext (OP x, y))
   // fold (OP (sext x), (sext y)) -> (sext (OP x, y))
   // fold (OP (aext x), (aext y)) -> (aext (OP x, y))
+  // fold (OP (trunc x), (trunc y)) -> (trunc (OP x, y))
   if ((N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND||
-       N0.getOpcode() == ISD::SIGN_EXTEND) &&
+       N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::TRUNCATE) &&
       N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
     SDOperand ORNode = DAG.getNode(N->getOpcode(), 
                                    N0.getOperand(0).getValueType(),
@@ -1059,19 +1064,6 @@ SDOperand DAGCombiner::SimplifyBinOpWithSameOpcodeHands(SDNode *N) {
     return DAG.getNode(N0.getOpcode(), VT, ORNode);
   }
   
-  // fold (and (trunc x), (trunc y)) -> (trunc (and x, y))
-  // fold (or  (trunc x), (trunc y)) -> (trunc (or  x, y))
-  // fold (xor (trunc x), (trunc y)) -> (trunc (xor x, y))
-  if (N0.getOpcode() == ISD::TRUNCATE &&
-      N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) {
-    SDOperand ORNode = DAG.getNode(N->getOpcode(),
-                                   N0.getOperand(0).getValueType(),
-                                   N0.getOperand(0), N1.getOperand(0));
-    AddToWorkList(ORNode.Val);
-    return DAG.getNode(ISD::TRUNCATE, VT, ORNode);
-  }
-  
-  
   // For each of OP in SHL/SRL/SRA/AND...
   //   fold (and (OP x, z), (OP y, z)) -> (OP (and x, y), z)
   //   fold (or  (OP x, z), (OP y, z)) -> (OP (or  x, y), z)
@@ -1587,6 +1579,11 @@ SDOperand DAGCombiner::visitSRA(SDNode *N) {
     }
   }
   
+  // Simplify, based on bits shifted out of the LHS. 
+  if (N1C && SimplifyDemandedBits(SDOperand(N, 0)))
+    return SDOperand(N, 0);
+  
+  
   // If the sign bit is known to be zero, switch this to a SRL.
   if (TLI.MaskedValueIsZero(N0, MVT::getIntVTSignBit(VT)))
     return DAG.getNode(ISD::SRL, VT, N0, N1);
@@ -1627,6 +1624,18 @@ SDOperand DAGCombiner::visitSRL(SDNode *N) {
                        DAG.getConstant(c1 + c2, N1.getValueType()));
   }
   
+  // fold (srl (anyextend x), c) -> (anyextend (srl x, c))
+  if (N1C && N0.getOpcode() == ISD::ANY_EXTEND) {
+    // Shifting in all undef bits?
+    MVT::ValueType SmallVT = N0.getOperand(0).getValueType();
+    if (N1C->getValue() >= MVT::getSizeInBits(SmallVT))
+      return DAG.getNode(ISD::UNDEF, VT);
+
+    SDOperand SmallShift = DAG.getNode(ISD::SRL, SmallVT, N0.getOperand(0), N1);
+    AddToWorkList(SmallShift.Val);
+    return DAG.getNode(ISD::ANY_EXTEND, VT, SmallShift);
+  }
+  
   // fold (srl (ctlz x), "5") -> x  iff x has one bit set (the low bit).
   if (N1C && N0.getOpcode() == ISD::CTLZ && 
       N1C->getValue() == Log2_32(MVT::getSizeInBits(VT))) {
@@ -1664,33 +1673,30 @@ SDOperand DAGCombiner::visitSRL(SDNode *N) {
 
 SDOperand DAGCombiner::visitCTLZ(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
-  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   MVT::ValueType VT = N->getValueType(0);
 
   // fold (ctlz c1) -> c2
-  if (N0C)
+  if (isa<ConstantSDNode>(N0))
     return DAG.getNode(ISD::CTLZ, VT, N0);
   return SDOperand();
 }
 
 SDOperand DAGCombiner::visitCTTZ(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
-  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   MVT::ValueType VT = N->getValueType(0);
   
   // fold (cttz c1) -> c2
-  if (N0C)
+  if (isa<ConstantSDNode>(N0))
     return DAG.getNode(ISD::CTTZ, VT, N0);
   return SDOperand();
 }
 
 SDOperand DAGCombiner::visitCTPOP(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
-  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   MVT::ValueType VT = N->getValueType(0);
   
   // fold (ctpop c1) -> c2
-  if (N0C)
+  if (isa<ConstantSDNode>(N0))
     return DAG.getNode(ISD::CTPOP, VT, N0);
   return SDOperand();
 }
@@ -1790,21 +1796,24 @@ SDOperand DAGCombiner::visitSETCC(SDNode *N) {
 
 SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
-  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   MVT::ValueType VT = N->getValueType(0);
 
   // fold (sext c1) -> c1
-  if (N0C)
+  if (ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0))
     return DAG.getNode(ISD::SIGN_EXTEND, VT, N0);
+  
   // fold (sext (sext x)) -> (sext x)
-  if (N0.getOpcode() == ISD::SIGN_EXTEND)
+  // fold (sext (aext x)) -> (sext x)
+  if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND)
     return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0));
+  
   // fold (sext (truncate x)) -> (sextinreg x) iff x size == sext size.
   if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT&&
       (!AfterLegalize || 
        TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, N0.getValueType())))
     return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0),
                        DAG.getValueType(N0.getValueType()));
+  
   // fold (sext (load x)) -> (sext (truncate (sextload x)))
   if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() &&
       (!AfterLegalize||TLI.isOperationLegal(ISD::SEXTLOAD, N0.getValueType()))){
@@ -1821,9 +1830,9 @@ SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
   // fold (sext ( extload x)) -> (sext (truncate (sextload x)))
   if ((N0.getOpcode() == ISD::SEXTLOAD || N0.getOpcode() == ISD::EXTLOAD) &&
       N0.hasOneUse()) {
-    SDOperand ExtLoad = DAG.getNode(ISD::SEXTLOAD, VT, N0.getOperand(0),
-                                    N0.getOperand(1), N0.getOperand(2),
-                                    N0.getOperand(3));
+    MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, N0.getOperand(0),
+                                       N0.getOperand(1), N0.getOperand(2), EVT);
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
               ExtLoad.getValue(1));
@@ -1835,14 +1844,14 @@ SDOperand DAGCombiner::visitSIGN_EXTEND(SDNode *N) {
 
 SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
-  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   MVT::ValueType VT = N->getValueType(0);
 
   // fold (zext c1) -> c1
-  if (N0C)
+  if (ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0))
     return DAG.getNode(ISD::ZERO_EXTEND, VT, N0);
   // fold (zext (zext x)) -> (zext x)
-  if (N0.getOpcode() == ISD::ZERO_EXTEND)
+  // fold (zext (aext x)) -> (zext x)
+  if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND)
     return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0));
   // fold (zext (truncate x)) -> (zextinreg x) iff x size == zext size.
   if (N0.getOpcode() == ISD::TRUNCATE && N0.getOperand(0).getValueType() == VT&&
@@ -1864,9 +1873,9 @@ SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) {
   // fold (zext ( extload x)) -> (zext (truncate (zextload x)))
   if ((N0.getOpcode() == ISD::ZEXTLOAD || N0.getOpcode() == ISD::EXTLOAD) &&
       N0.hasOneUse()) {
-    SDOperand ExtLoad = DAG.getNode(ISD::ZEXTLOAD, VT, N0.getOperand(0),
-                                    N0.getOperand(1), N0.getOperand(2),
-                                    N0.getOperand(3));
+    MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, N0.getOperand(0),
+                                       N0.getOperand(1), N0.getOperand(2), EVT);
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
               ExtLoad.getValue(1));
@@ -1877,11 +1886,10 @@ SDOperand DAGCombiner::visitZERO_EXTEND(SDNode *N) {
 
 SDOperand DAGCombiner::visitANY_EXTEND(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
-  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   MVT::ValueType VT = N->getValueType(0);
   
   // fold (aext c1) -> c1
-  if (N0C)
+  if (isa<ConstantSDNode>(N0))
     return DAG.getNode(ISD::ANY_EXTEND, VT, N0);
   // fold (aext (aext x)) -> (aext x)
   // fold (aext (zext x)) -> (zext x)
@@ -1912,9 +1920,9 @@ SDOperand DAGCombiner::visitANY_EXTEND(SDNode *N) {
   if ((N0.getOpcode() == ISD::ZEXTLOAD || N0.getOpcode() == ISD::EXTLOAD ||
        N0.getOpcode() == ISD::SEXTLOAD) &&
       N0.hasOneUse()) {
-    SDOperand ExtLoad = DAG.getNode(N0.getOpcode(), VT, N0.getOperand(0),
-                                    N0.getOperand(1), N0.getOperand(2),
-                                    N0.getOperand(3));
+    MVT::ValueType EVT = cast<VTSDNode>(N0.getOperand(3))->getVT();
+    SDOperand ExtLoad = DAG.getExtLoad(N0.getOpcode(), VT, N0.getOperand(0),
+                                       N0.getOperand(1), N0.getOperand(2), EVT);
     CombineTo(N, ExtLoad);
     CombineTo(N0.Val, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad),
               ExtLoad.getValue(1));
@@ -1927,44 +1935,42 @@ SDOperand DAGCombiner::visitANY_EXTEND(SDNode *N) {
 SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
   SDOperand N1 = N->getOperand(1);
-  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   MVT::ValueType VT = N->getValueType(0);
   MVT::ValueType EVT = cast<VTSDNode>(N1)->getVT();
   unsigned EVTBits = MVT::getSizeInBits(EVT);
   
   // fold (sext_in_reg c1) -> c1
-  if (N0C) {
-    SDOperand Truncate = DAG.getConstant(N0C->getValue(), EVT);
-    return DAG.getNode(ISD::SIGN_EXTEND, VT, Truncate);
-  }
-  // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt1
-  if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG && 
-      cast<VTSDNode>(N0.getOperand(1))->getVT() <= EVT) {
+  if (isa<ConstantSDNode>(N0) || N0.getOpcode() == ISD::UNDEF)
+    return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0, N1);
+  
+  // If the input is already sign extended, just drop the extension.
+  if (TLI.ComputeNumSignBits(N0) >= MVT::getSizeInBits(VT)-EVTBits+1)
     return N0;
-  }
+  
   // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt2
   if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG &&
       EVT < cast<VTSDNode>(N0.getOperand(1))->getVT()) {
     return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), N1);
   }
-  // fold (sext_in_reg (assert_sext x)) -> (assert_sext x)
-  if (N0.getOpcode() == ISD::AssertSext && 
-      cast<VTSDNode>(N0.getOperand(1))->getVT() <= EVT) {
-    return N0;
-  }
-  // fold (sext_in_reg (sextload x)) -> (sextload x)
-  if (N0.getOpcode() == ISD::SEXTLOAD && 
-      cast<VTSDNode>(N0.getOperand(3))->getVT() <= EVT) {
-    return N0;
-  }
-  // fold (sext_in_reg (setcc x)) -> setcc x iff (setcc x) == 0 or -1
-  if (N0.getOpcode() == ISD::SETCC &&
-      TLI.getSetCCResultContents() == 
-        TargetLowering::ZeroOrNegativeOneSetCCResult)
-    return N0;
+
   // fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is zero
   if (TLI.MaskedValueIsZero(N0, 1ULL << (EVTBits-1)))
     return DAG.getZeroExtendInReg(N0, EVT);
+  
+  // fold (sext_in_reg (srl X, 24), i8) -> sra X, 24
+  // fold (sext_in_reg (srl X, 23), i8) -> sra X, 23 iff possible.
+  // We already fold "(sext_in_reg (srl X, 25), i8) -> srl X, 25" above.
+  if (N0.getOpcode() == ISD::SRL) {
+    if (ConstantSDNode *ShAmt = dyn_cast<ConstantSDNode>(N0.getOperand(1)))
+      if (ShAmt->getValue()+EVTBits <= MVT::getSizeInBits(VT)) {
+        // We can turn this into an SRA iff the input to the SRL is already sign
+        // extended enough.
+        unsigned InSignBits = TLI.ComputeNumSignBits(N0.getOperand(0));
+        if (MVT::getSizeInBits(VT)-(ShAmt->getValue()+EVTBits) < InSignBits)
+          return DAG.getNode(ISD::SRA, VT, N0.getOperand(0), N0.getOperand(1));
+      }
+  }
+  
   // fold (sext_inreg (extload x)) -> (sextload x)
   if (N0.getOpcode() == ISD::EXTLOAD && 
       EVT == cast<VTSDNode>(N0.getOperand(3))->getVT() &&
@@ -1992,20 +1998,20 @@ SDOperand DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) {
 
 SDOperand DAGCombiner::visitTRUNCATE(SDNode *N) {
   SDOperand N0 = N->getOperand(0);
-  ConstantSDNode *N0C = dyn_cast<ConstantSDNode>(N0);
   MVT::ValueType VT = N->getValueType(0);
 
   // noop truncate
   if (N0.getValueType() == N->getValueType(0))
     return N0;
   // fold (truncate c1) -> c1
-  if (N0C)
+  if (isa<ConstantSDNode>(N0))
     return DAG.getNode(ISD::TRUNCATE, VT, N0);
   // fold (truncate (truncate x)) -> (truncate x)
   if (N0.getOpcode() == ISD::TRUNCATE)
     return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0));
   // fold (truncate (ext x)) -> (ext x) or (truncate x) or x
-  if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::SIGN_EXTEND){
+  if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::SIGN_EXTEND||
+      N0.getOpcode() == ISD::ANY_EXTEND) {
     if (N0.getValueType() < VT)
       // if the source is smaller than the dest, we still need an extend
       return DAG.getNode(N0.getOpcode(), VT, N0.getOperand(0));
@@ -2425,6 +2431,20 @@ SDOperand DAGCombiner::visitFP_EXTEND(SDNode *N) {
   // fold (fp_extend c1fp) -> c1fp
   if (N0CFP)
     return DAG.getNode(ISD::FP_EXTEND, VT, N0);
+  
+  // fold (fpext (load x)) -> (fpext (fpround (extload x)))
+  if (N0.getOpcode() == ISD::LOAD && N0.hasOneUse() &&
+      (!AfterLegalize||TLI.isOperationLegal(ISD::EXTLOAD, N0.getValueType()))) {
+    SDOperand ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, N0.getOperand(0),
+                                       N0.getOperand(1), N0.getOperand(2),
+                                       N0.getValueType());
+    CombineTo(N, ExtLoad);
+    CombineTo(N0.Val, DAG.getNode(ISD::FP_ROUND, N0.getValueType(), ExtLoad),
+              ExtLoad.getValue(1));
+    return SDOperand(N, 0);   // Return N so it doesn't get rechecked!
+  }
+  
+  
   return SDOperand();
 }