aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2005-01-09 20:52:51 +0000
committerChris Lattner <sabre@nondot.org>2005-01-09 20:52:51 +0000
commit5cdcc58d51c792d329202bab97c34aefbc043b15 (patch)
tree5e4af8c8b2efad5349a23a499ca8114e8600cf59 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp
parent1d7b5de7eef6039dbc00bf50b582a5d7426e03fc (diff)
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19425 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/SelectionDAG/SelectionDAG.cpp')
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp99
1 files changed, 58 insertions, 41 deletions
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 9c58304966..f3c18d37d3 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -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 @@ SDOperand SelectionDAG::getSetCC(ISD::CondCode Cond, SDOperand N1,
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 @@ SDOperand SelectionDAG::getNode(unsigned Opcode, MVT::ValueType VT,
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);