diff options
author | Chris Lattner <sabre@nondot.org> | 2005-01-09 20:52:51 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2005-01-09 20:52:51 +0000 |
commit | 5cdcc58d51c792d329202bab97c34aefbc043b15 (patch) | |
tree | 5e4af8c8b2efad5349a23a499ca8114e8600cf59 /lib/CodeGen/SelectionDAG/SelectionDAG.cpp | |
parent | 1d7b5de7eef6039dbc00bf50b582a5d7426e03fc (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.cpp | 99 |
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); |