Refactor code. No functionality change.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@60478 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Evan Cheng 2008-12-03 08:38:43 +00:00
parent 0ea25cb941
commit 370e5340a5

View File

@ -5130,6 +5130,11 @@ SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) {
return Result;
}
// isX86LogicalCmp - Return true if opcode is a X86 logical comparison.
static bool isX86LogicalCmp(unsigned Opc) {
return Opc == X86ISD::CMP || Opc == X86ISD::COMI || Opc == X86ISD::UCOMI;
}
SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
bool addTest = true;
SDValue Cond = Op.getOperand(0);
@ -5152,9 +5157,7 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
!isScalarFPTypeInSSEReg(VT)) // FPStack?
IllegalFPCMov = !hasFPCMov(cast<ConstantSDNode>(CC)->getSExtValue());
if ((Opc == X86ISD::CMP ||
Opc == X86ISD::COMI ||
Opc == X86ISD::UCOMI) && !IllegalFPCMov) {
if (isX86LogicalCmp(Opc) && !IllegalFPCMov) {
Cond = Cmp;
addTest = false;
}
@ -5177,6 +5180,19 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
return DAG.getNode(X86ISD::CMOV, VTs, 2, &Ops[0], Ops.size());
}
// isAndOrOfSingleUseSetCCs - Return true if node is an ISD::AND or
// ISD::OR of two X86ISD::SETCC nodes each of which has no other use apart
// from the AND / OR.
static bool isAndOrOfSetCCs(SDValue Op, unsigned &Opc) {
Opc = Op.getOpcode();
if (Opc != ISD::OR && Opc != ISD::AND)
return false;
return (Op.getOperand(0).getOpcode() == X86ISD::SETCC &&
Op.getOperand(0).hasOneUse() &&
Op.getOperand(1).getOpcode() == X86ISD::SETCC &&
Op.getOperand(1).hasOneUse());
}
SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
bool addTest = true;
SDValue Chain = Op.getOperand(0);
@ -5196,86 +5212,73 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) {
SDValue Cmp = Cond.getOperand(1);
unsigned Opc = Cmp.getOpcode();
if (Opc == X86ISD::CMP ||
Opc == X86ISD::COMI ||
Opc == X86ISD::UCOMI) {
if (isX86LogicalCmp(Opc)) {
Cond = Cmp;
addTest = false;
} else {
ConstantSDNode *CSDN = cast<ConstantSDNode>(CC.getNode());
switch (CSDN->getZExtValue()) {
switch (cast<ConstantSDNode>(CC)->getZExtValue()) {
default: break;
case X86::COND_O:
case X86::COND_C:
// These can only come from an arithmetic instruction with overflow, e.g.
// SADDO, UADDO.
Cond = Cond.getNode()->getOperand(1);
addTest = false;
break;
}
}
// Also, recognize the pattern generated by an FCMP_UNE. We can emit
// two branches instead of an explicit OR instruction with a
// separate test.
} else if (Cond.getOpcode() == ISD::OR &&
Cond.hasOneUse() &&
Cond.getOperand(0).getOpcode() == X86ISD::SETCC &&
Cond.getOperand(0).hasOneUse() &&
Cond.getOperand(1).getOpcode() == X86ISD::SETCC &&
Cond.getOperand(1).hasOneUse()) {
SDValue Cmp = Cond.getOperand(0).getOperand(1);
unsigned Opc = Cmp.getOpcode();
if (Cmp == Cond.getOperand(1).getOperand(1) &&
(Opc == X86ISD::CMP ||
Opc == X86ISD::COMI ||
Opc == X86ISD::UCOMI)) {
CC = Cond.getOperand(0).getOperand(0);
Chain = DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
Chain, Dest, CC, Cmp);
CC = Cond.getOperand(1).getOperand(0);
Cond = Cmp;
addTest = false;
}
// Also, recognize the pattern generated by an FCMP_OEQ. We can emit
// two branches instead of an explicit AND instruction with a
// separate test. However, we only do this if this block doesn't
// have a fall-through edge, because this requires an explicit
// jmp when the condition is false.
} else if (Cond.getOpcode() == ISD::AND &&
Cond.hasOneUse() &&
Cond.getOperand(0).getOpcode() == X86ISD::SETCC &&
Cond.getOperand(0).hasOneUse() &&
Cond.getOperand(1).getOpcode() == X86ISD::SETCC &&
Cond.getOperand(1).hasOneUse()) {
SDValue Cmp = Cond.getOperand(0).getOperand(1);
unsigned Opc = Cmp.getOpcode();
if (Cmp == Cond.getOperand(1).getOperand(1) &&
(Opc == X86ISD::CMP ||
Opc == X86ISD::COMI ||
Opc == X86ISD::UCOMI) &&
Op.getNode()->hasOneUse()) {
X86::CondCode CCode =
(X86::CondCode)Cond.getOperand(0).getConstantOperandVal(0);
CCode = X86::GetOppositeBranchCondition(CCode);
CC = DAG.getConstant(CCode, MVT::i8);
SDValue User = SDValue(*Op.getNode()->use_begin(), 0);
// Look for an unconditional branch following this conditional branch.
// We need this because we need to reverse the successors in order
// to implement FCMP_OEQ.
if (User.getOpcode() == ISD::BR) {
SDValue FalseBB = User.getOperand(1);
SDValue NewBR =
DAG.UpdateNodeOperands(User, User.getOperand(0), Dest);
assert(NewBR == User);
Dest = FalseBB;
} else {
unsigned CondOpc;
if (Cond.hasOneUse() && isAndOrOfSetCCs(Cond, CondOpc)) {
SDValue Cmp = Cond.getOperand(0).getOperand(1);
unsigned Opc = Cmp.getOpcode();
if (CondOpc == ISD::OR) {
// Also, recognize the pattern generated by an FCMP_UNE. We can emit
// two branches instead of an explicit OR instruction with a
// separate test.
if (Cmp == Cond.getOperand(1).getOperand(1) &&
isX86LogicalCmp(Opc)) {
CC = Cond.getOperand(0).getOperand(0);
Chain = DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
Chain, Dest, CC, Cmp);
CC = Cond.getOperand(1).getOperand(0);
Cond = Cmp;
addTest = false;
}
} else { // ISD::AND
// Also, recognize the pattern generated by an FCMP_OEQ. We can emit
// two branches instead of an explicit AND instruction with a
// separate test. However, we only do this if this block doesn't
// have a fall-through edge, because this requires an explicit
// jmp when the condition is false.
if (Cmp == Cond.getOperand(1).getOperand(1) &&
isX86LogicalCmp(Opc) &&
Op.getNode()->hasOneUse()) {
X86::CondCode CCode =
(X86::CondCode)Cond.getOperand(0).getConstantOperandVal(0);
CCode = X86::GetOppositeBranchCondition(CCode);
CC = DAG.getConstant(CCode, MVT::i8);
SDValue User = SDValue(*Op.getNode()->use_begin(), 0);
// Look for an unconditional branch following this conditional branch.
// We need this because we need to reverse the successors in order
// to implement FCMP_OEQ.
if (User.getOpcode() == ISD::BR) {
SDValue FalseBB = User.getOperand(1);
SDValue NewBR =
DAG.UpdateNodeOperands(User, User.getOperand(0), Dest);
assert(NewBR == User);
Dest = FalseBB;
Chain = DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
Chain, Dest, CC, Cmp);
X86::CondCode CCode =
(X86::CondCode)Cond.getOperand(1).getConstantOperandVal(0);
CCode = X86::GetOppositeBranchCondition(CCode);
CC = DAG.getConstant(CCode, MVT::i8);
Cond = Cmp;
addTest = false;
Chain = DAG.getNode(X86ISD::BRCOND, Op.getValueType(),
Chain, Dest, CC, Cmp);
X86::CondCode CCode =
(X86::CondCode)Cond.getOperand(1).getConstantOperandVal(0);
CCode = X86::GetOppositeBranchCondition(CCode);
CC = DAG.getConstant(CCode, MVT::i8);
Cond = Cmp;
addTest = false;
}
}
}
}
}