mirror of
https://github.com/RPCS3/llvm.git
synced 2024-12-04 09:54:09 +00:00
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
This commit is contained in:
parent
1d7b5de7ee
commit
5cdcc58d51
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user