From: Chris Lattner Date: Thu, 6 Oct 2005 19:03:35 +0000 (+0000) Subject: Pull out setcc, this reduces stack frame size from 7520 to 6032 bytes X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=222adac30a642b5ea4a916eb3e97d8d95eb32bea;p=oota-llvm.git 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 --- diff --git a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp index 687b1192727..ae32f9479e6 100644 --- a/lib/Target/PowerPC/PPCISelDAGToDAG.cpp +++ b/lib/Target/PowerPC/PPCISelDAGToDAG.cpp @@ -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(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 VTs; + VTs.push_back(MVT::Other); + VTs.push_back(MVT::Flag); // NONSTANDARD CopyToReg node: defines a flag + std::vector 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().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(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 VTs; - VTs.push_back(MVT::Other); - VTs.push_back(MVT::Flag); // NONSTANDARD CopyToReg node: defines a flag - std::vector 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().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(N->getOperand(4))->get();