[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