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

Chris Lattner lattner at cs.uiuc.edu
Sun Jan 9 12:53:06 PST 2005



Changes in directory llvm/lib/CodeGen/SelectionDAG:

SelectionDAG.cpp updated: 1.19 -> 1.20
---
Log message:

Add some folds for == and != comparisons.  This allows us to
codegen this loop in stepanov:

no_exit.i:              ; preds = %entry, %no_exit.i, %then.i, %_Z5checkd.exit
        %i.0.0 = phi int [ 0, %entry ], [ %i.0.0, %no_exit.i ], [ %inc.0, %_Z5checkd.exit ], [ %inc.012, %then.i ]              ; <int> [#uses=3]
        %indvar = phi uint [ %indvar.next, %no_exit.i ], [ 0, %entry ], [ 0, %then.i ], [ 0, %_Z5checkd.exit ]          ; <uint> [#uses=3]
        %result_addr.i.0 = phi double [ %tmp.4.i.i, %no_exit.i ], [ 0.000000e+00, %entry ], [ 0.000000e+00, %then.i ], [ 0.000000e+00, %_Z5checkd.exit ]          ; <double> [#uses=1]
        %first_addr.0.i.2.rec = cast uint %indvar to int                ; <int> [#uses=1]
        %first_addr.0.i.2 = getelementptr [2000 x double]* %data, int 0, uint %indvar           ; <double*> [#uses=1]
        %inc.i.rec = add int %first_addr.0.i.2.rec, 1           ; <int> [#uses=1]
        %inc.i = getelementptr [2000 x double]* %data, int 0, int %inc.i.rec            ; <double*> [#uses=1]
        %tmp.3.i.i = load double* %first_addr.0.i.2             ; <double> [#uses=1]
        %tmp.4.i.i = add double %result_addr.i.0, %tmp.3.i.i            ; <double> [#uses=2]
        %tmp.2.i = seteq double* %inc.i, getelementptr ([2000 x double]* %data, int 0, int 2000)                ; <bool> [#uses=1]
        %indvar.next = add uint %indvar, 1              ; <uint> [#uses=1]
        br bool %tmp.2.i, label %_Z10accumulateIPddET0_T_S2_S1_.exit, label %no_exit.i

To this:

.LBB_Z4testIPddEvT_S1_T0__1:    # no_exit.i
        fldl data(,%eax,8)
        fldl 16(%esp)
        faddp %st(1)
        fstpl 16(%esp)
        incl %eax
        movl %eax, %ecx
        shll $3, %ecx
        cmpl $16000, %ecx
        #FP_REG_KILL
        jne .LBB_Z4testIPddEvT_S1_T0__1 # no_exit.i

instead of this:

.LBB_Z4testIPddEvT_S1_T0__1:    # no_exit.i
        fldl data(,%eax,8)
        fldl 16(%esp)
        faddp %st(1)
        fstpl 16(%esp)
        incl %eax
        leal data(,%eax,8), %ecx
        leal data+16000, %edx
        cmpl %edx, %ecx
        #FP_REG_KILL
        jne .LBB_Z4testIPddEvT_S1_T0__1 # no_exit.i



---
Diffs of the changes:  (+58 -41)

Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff -u llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.19 llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.20
--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp:1.19	Sun Jan  9 14:41:56 2005
+++ llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp	Sun Jan  9 14:52:51 2005
@@ -22,6 +22,47 @@
 #include <algorithm>
 using namespace llvm;
 
+static bool isCommutativeBinOp(unsigned Opcode) {
+  switch (Opcode) {
+  case ISD::ADD:
+  case ISD::MUL:
+  case ISD::AND:
+  case ISD::OR:
+  case ISD::XOR: return true;
+  default: return false; // FIXME: Need commutative info for user ops!
+  }
+}
+
+static bool isAssociativeBinOp(unsigned Opcode) {
+  switch (Opcode) {
+  case ISD::ADD:
+  case ISD::MUL:
+  case ISD::AND:
+  case ISD::OR:
+  case ISD::XOR: return true;
+  default: return false; // FIXME: Need associative info for user ops!
+  }
+}
+
+static unsigned ExactLog2(uint64_t Val) {
+  unsigned Count = 0;
+  while (Val != 1) {
+    Val >>= 1;
+    ++Count;
+  }
+  return Count;
+}
+
+// isInvertibleForFree - Return true if there is no cost to emitting the logical
+// inverse of this node.
+static bool isInvertibleForFree(SDOperand N) {
+  if (isa<ConstantSDNode>(N.Val)) return true;
+  if (isa<SetCCSDNode>(N.Val) && N.Val->hasOneUse())
+    return true;
+  return false;  
+}
+
+
 /// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
 /// when given the operation for (X op Y).
 ISD::CondCode ISD::getSetCCSwappedOperands(ISD::CondCode Operation) {
@@ -357,6 +398,23 @@
     Cond = UOF == 0 ? ISD::SETUO : ISD::SETO;
   }
 
+  // Simplify (X+Y) == (X+Z) -->  Y == Z
+  if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) &&
+      N1.getOpcode() == N2.getOpcode() && MVT::isInteger(N1.getValueType()))
+    if (N1.getOpcode() == ISD::ADD || N1.getOpcode() == ISD::SUB) {
+      if (N1.getOperand(0) == N2.getOperand(0))
+        return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1));
+      if (N1.getOperand(1) == N2.getOperand(1))
+        return getSetCC(Cond, N1.getOperand(0), N2.getOperand(0));
+      if (isCommutativeBinOp(N1.getOpcode())) {
+        // If X op Y == Y op X, try other combinations.
+        if (N1.getOperand(0) == N2.getOperand(1))
+          return getSetCC(Cond, N1.getOperand(1), N2.getOperand(0));
+        if (N1.getOperand(1) == N2.getOperand(0))
+          return getSetCC(Cond, N1.getOperand(1), N2.getOperand(1));
+      }
+    }
+
 
   SetCCSDNode *&N = SetCCs[std::make_pair(std::make_pair(N1, N2), Cond)];
   if (N) return SDOperand(N, 0);
@@ -449,47 +507,6 @@
   return SDOperand(N, 0);
 }
 
-static bool isCommutativeBinOp(unsigned Opcode) {
-  switch (Opcode) {
-  case ISD::ADD:
-  case ISD::MUL:
-  case ISD::AND:
-  case ISD::OR:
-  case ISD::XOR: return true;
-  default: return false; // FIXME: Need commutative info for user ops!
-  }
-}
-
-static bool isAssociativeBinOp(unsigned Opcode) {
-  switch (Opcode) {
-  case ISD::ADD:
-  case ISD::MUL:
-  case ISD::AND:
-  case ISD::OR:
-  case ISD::XOR: return true;
-  default: return false; // FIXME: Need associative info for user ops!
-  }
-}
-
-static unsigned ExactLog2(uint64_t Val) {
-  unsigned Count = 0;
-  while (Val != 1) {
-    Val >>= 1;
-    ++Count;
-  }
-  return Count;
-}
-
-// isInvertibleForFree - Return true if there is no cost to emitting the logical
-// inverse of this node.
-static bool isInvertibleForFree(SDOperand N) {
-  if (isa<ConstantSDNode>(N.Val)) return true;
-  if (isa<SetCCSDNode>(N.Val) && N.Val->hasOneUse())
-    return true;
-  return false;  
-}
-
-
 SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
                                 SDOperand N1, SDOperand N2) {
   ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N1.Val);






More information about the llvm-commits mailing list