Pull out setcc, this reduces stack frame size from 7520 to 6032 bytes

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@23649 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2005-10-06 19:03:35 +00:00
parent 2b63e4c5e2
commit 222adac30a

View File

@ -93,9 +93,10 @@ namespace {
#include "PPC32GenDAGISel.inc"
private:
SDOperand SelectDYNAMIC_STACKALLOC(SDOperand N);
SDOperand SelectADD_PARTS(SDOperand N);
SDOperand SelectSUB_PARTS(SDOperand N);
SDOperand SelectDYNAMIC_STACKALLOC(SDOperand Op);
SDOperand SelectADD_PARTS(SDOperand Op);
SDOperand SelectSUB_PARTS(SDOperand Op);
SDOperand SelectSETCC(SDOperand Op);
};
}
@ -775,6 +776,113 @@ SDOperand PPC32DAGToDAGISel::SelectSUB_PARTS(SDOperand Op) {
return Result[Op.ResNo];
}
SDOperand PPC32DAGToDAGISel::SelectSETCC(SDOperand Op) {
SDNode *N = Op.Val;
unsigned Imm;
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
if (isIntImmediate(N->getOperand(1), Imm)) {
// We can codegen setcc op, imm very efficiently compared to a brcond.
// Check for those cases here.
// setcc op, 0
if (Imm == 0) {
SDOperand Op = Select(N->getOperand(0));
switch (CC) {
default: assert(0 && "Unhandled SetCC condition"); abort();
case ISD::SETEQ:
Op = CurDAG->getTargetNode(PPC::CNTLZW, MVT::i32, Op);
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(27),
getI32Imm(5), getI32Imm(31));
break;
case ISD::SETNE: {
SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
Op, getI32Imm(~0U));
CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1));
break;
}
case ISD::SETLT:
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(1),
getI32Imm(31), getI32Imm(31));
break;
case ISD::SETGT: {
SDOperand T = CurDAG->getTargetNode(PPC::NEG, MVT::i32, Op);
T = CurDAG->getTargetNode(PPC::ANDC, MVT::i32, T, Op);;
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, T, getI32Imm(1),
getI32Imm(31), getI32Imm(31));
break;
}
}
return SDOperand(N, 0);
} else if (Imm == ~0U) { // setcc op, -1
SDOperand Op = Select(N->getOperand(0));
switch (CC) {
default: assert(0 && "Unhandled SetCC condition"); abort();
case ISD::SETEQ:
Op = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
Op, getI32Imm(1));
CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32,
CurDAG->getTargetNode(PPC::LI, MVT::i32,
getI32Imm(0)),
Op.getValue(1));
break;
case ISD::SETNE: {
Op = CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op);
SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
Op, getI32Imm(~0U));
CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1));
break;
}
case ISD::SETLT: {
SDOperand AD = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op,
getI32Imm(1));
SDOperand AN = CurDAG->getTargetNode(PPC::AND, MVT::i32, AD, Op);
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, AN, getI32Imm(1),
getI32Imm(31), getI32Imm(31));
break;
}
case ISD::SETGT:
Op = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Op, getI32Imm(1),
getI32Imm(31), getI32Imm(31));
CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1));
break;
}
return SDOperand(N, 0);
}
}
bool Inv;
unsigned Idx = getCRIdxForSetCC(CC, Inv);
SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC);
SDOperand IntCR;
// Force the ccreg into CR7.
SDOperand CR7Reg = CurDAG->getRegister(PPC::CR7, MVT::i32);
std::vector<MVT::ValueType> VTs;
VTs.push_back(MVT::Other);
VTs.push_back(MVT::Flag); // NONSTANDARD CopyToReg node: defines a flag
std::vector<SDOperand> Ops;
Ops.push_back(CurDAG->getEntryNode());
Ops.push_back(CR7Reg);
Ops.push_back(CCReg);
CCReg = CurDAG->getNode(ISD::CopyToReg, VTs, Ops).getValue(1);
if (TLI.getTargetMachine().getSubtarget<PPCSubtarget>().isGigaProcessor())
IntCR = CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, CR7Reg, CCReg);
else
IntCR = CurDAG->getTargetNode(PPC::MFCR, MVT::i32, CCReg);
if (!Inv) {
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, IntCR,
getI32Imm(32-(3-Idx)), getI32Imm(31), getI32Imm(31));
} else {
SDOperand Tmp =
CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, IntCR,
getI32Imm(32-(3-Idx)), getI32Imm(31),getI32Imm(31));
CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1));
}
return SDOperand(N, 0);
}
// Select - Convert the specified operand from a target-independent to a
// target-specific node if it hasn't already been changed.
@ -790,6 +898,10 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
switch (N->getOpcode()) {
default: break;
case ISD::DYNAMIC_STACKALLOC: return SelectDYNAMIC_STACKALLOC(Op);
case ISD::ADD_PARTS: return SelectADD_PARTS(Op);
case ISD::SUB_PARTS: return SelectSUB_PARTS(Op);
case ISD::SETCC: return SelectSETCC(Op);
case ISD::TokenFactor: {
SDOperand New;
if (N->getNumOperands() == 2) {
@ -862,8 +974,7 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, GA);
return SDOperand(N, 0);
}
case ISD::DYNAMIC_STACKALLOC:
return SelectDYNAMIC_STACKALLOC(Op);
case PPCISD::FSEL: {
SDOperand Comparison = Select(N->getOperand(0));
// Extend the comparison to 64-bits.
@ -1132,9 +1243,7 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
Select(N->getOperand(0)));
return SDOperand(N, 0);
}
case ISD::ADD_PARTS: return SelectADD_PARTS(Op);
case ISD::SUB_PARTS: return SelectSUB_PARTS(Op);
case ISD::LOAD:
case ISD::EXTLOAD:
case ISD::ZEXTLOAD:
@ -1209,113 +1318,6 @@ SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) {
return SDOperand(N, 0);
}
case ISD::SETCC: {
unsigned Imm;
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get();
if (isIntImmediate(N->getOperand(1), Imm)) {
// We can codegen setcc op, imm very efficiently compared to a brcond.
// Check for those cases here.
// setcc op, 0
if (Imm == 0) {
SDOperand Op = Select(N->getOperand(0));
switch (CC) {
default: assert(0 && "Unhandled SetCC condition"); abort();
case ISD::SETEQ:
Op = CurDAG->getTargetNode(PPC::CNTLZW, MVT::i32, Op);
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(27),
getI32Imm(5), getI32Imm(31));
break;
case ISD::SETNE: {
SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
Op, getI32Imm(~0U));
CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1));
break;
}
case ISD::SETLT:
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(1),
getI32Imm(31), getI32Imm(31));
break;
case ISD::SETGT: {
SDOperand T = CurDAG->getTargetNode(PPC::NEG, MVT::i32, Op);
T = CurDAG->getTargetNode(PPC::ANDC, MVT::i32, T, Op);;
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, T, getI32Imm(1),
getI32Imm(31), getI32Imm(31));
break;
}
}
return SDOperand(N, 0);
} else if (Imm == ~0U) { // setcc op, -1
SDOperand Op = Select(N->getOperand(0));
switch (CC) {
default: assert(0 && "Unhandled SetCC condition"); abort();
case ISD::SETEQ:
Op = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
Op, getI32Imm(1));
CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32,
CurDAG->getTargetNode(PPC::LI, MVT::i32,
getI32Imm(0)),
Op.getValue(1));
break;
case ISD::SETNE: {
Op = CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op);
SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag,
Op, getI32Imm(~0U));
CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1));
break;
}
case ISD::SETLT: {
SDOperand AD = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op,
getI32Imm(1));
SDOperand AN = CurDAG->getTargetNode(PPC::AND, MVT::i32, AD, Op);
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, AN, getI32Imm(1),
getI32Imm(31), getI32Imm(31));
break;
}
case ISD::SETGT:
Op = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Op, getI32Imm(1),
getI32Imm(31), getI32Imm(31));
CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1));
break;
}
return SDOperand(N, 0);
}
}
bool Inv;
unsigned Idx = getCRIdxForSetCC(CC, Inv);
SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC);
SDOperand IntCR;
// Force the ccreg into CR7.
SDOperand CR7Reg = CurDAG->getRegister(PPC::CR7, MVT::i32);
std::vector<MVT::ValueType> VTs;
VTs.push_back(MVT::Other);
VTs.push_back(MVT::Flag); // NONSTANDARD CopyToReg node: defines a flag
std::vector<SDOperand> Ops;
Ops.push_back(CurDAG->getEntryNode());
Ops.push_back(CR7Reg);
Ops.push_back(CCReg);
CCReg = CurDAG->getNode(ISD::CopyToReg, VTs, Ops).getValue(1);
if (TLI.getTargetMachine().getSubtarget<PPCSubtarget>().isGigaProcessor())
IntCR = CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, CR7Reg, CCReg);
else
IntCR = CurDAG->getTargetNode(PPC::MFCR, MVT::i32, CCReg);
if (!Inv) {
CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, IntCR,
getI32Imm(32-(3-Idx)), getI32Imm(31), getI32Imm(31));
} else {
SDOperand Tmp =
CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, IntCR,
getI32Imm(32-(3-Idx)), getI32Imm(31),getI32Imm(31));
CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1));
}
return SDOperand(N, 0);
}
case ISD::SELECT_CC: {
ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(4))->get();