Changes in directory llvm/lib/Target/PowerPC:
PPCISelDAGToDAG.cpp updated: 1.186 -> 1.187 PPCISelLowering.cpp updated: 1.179 -> 1.180 PPCISelLowering.h updated: 1.49 -> 1.50 PPCInstrInfo.td updated: 1.219 -> 1.220 --- Log message: Make PPC call lowering more aggressive, making the isel matching code simple enough to be autogenerated. --- Diffs of the changes: (+98 -84) PPCISelDAGToDAG.cpp | 64 ---------------------------------------- PPCISelLowering.cpp | 83 ++++++++++++++++++++++++++++++++++++++++++++-------- PPCISelLowering.h | 10 +++++- PPCInstrInfo.td | 25 +++++++++++---- 4 files changed, 98 insertions(+), 84 deletions(-) Index: llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp diff -u llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.186 llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.187 --- llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp:1.186 Wed May 17 01:01:33 2006 +++ llvm/lib/Target/PowerPC/PPCISelDAGToDAG.cpp Wed May 17 14:00:46 2006 @@ -152,7 +152,6 @@ private: SDOperand SelectSETCC(SDOperand Op); - SDOperand SelectCALL(SDOperand Op); }; } @@ -864,66 +863,6 @@ } } -/// isCallCompatibleAddress - Return true if the specified 32-bit value is -/// representable in the immediate field of a Bx instruction. -static bool isCallCompatibleAddress(ConstantSDNode *C) { - int Addr = C->getValue(); - if (Addr & 3) return false; // Low 2 bits are implicitly zero. - return (Addr << 6 >> 6) == Addr; // Top 6 bits have to be sext of immediate. -} - -SDOperand PPCDAGToDAGISel::SelectCALL(SDOperand Op) { - SDNode *N = Op.Val; - SDOperand Chain, Flag; - Select(Chain, N->getOperand(0)); - if (N->getNumOperands() == 3) // input flag - Select(Flag, N->getOperand(2)); - - unsigned CallOpcode; - - std::vector<SDOperand> CallArgs; - if (GlobalAddressSDNode *GASD = - dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) { - CallOpcode = PPC::BL; - CallArgs.push_back(N->getOperand(1)); - } else if (ExternalSymbolSDNode *ESSDN = - dyn_cast<ExternalSymbolSDNode>(N->getOperand(1))) { - CallOpcode = PPC::BL; - CallArgs.push_back(N->getOperand(1)); - } else if (isa<ConstantSDNode>(N->getOperand(1)) && - isCallCompatibleAddress(cast<ConstantSDNode>(N->getOperand(1)))) { - ConstantSDNode *C = cast<ConstantSDNode>(N->getOperand(1)); - CallOpcode = PPC::BLA; - CallArgs.push_back(getI32Imm((int)C->getValue() >> 2)); - } else { - // Copy the callee address into the CTR register. - SDOperand Callee; - Select(Callee, N->getOperand(1)); - if (Flag.Val) - Chain = SDOperand(CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, MVT::Flag, - Callee, Chain, Flag), 0); - else - Chain = SDOperand(CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, MVT::Flag, - Callee, Chain), 0); - Flag = Chain.getValue(1); - - // Copy the callee address into R12 on darwin. - Chain = CurDAG->getCopyToReg(Chain, PPC::R12, Callee, Flag); - Flag = Chain.getValue(1); - - CallOpcode = PPC::BCTRL; - } - - // Emit the call itself. - CallArgs.push_back(Chain); - if (Flag.Val) - CallArgs.push_back(Flag); - Chain = SDOperand(CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag, - CallArgs), 0); - CodeGenMap[Op.getValue(0)] = Chain; - CodeGenMap[Op.getValue(1)] = Chain.getValue(1); - return Chain.getValue(Op.ResNo); -} // Select - Convert the specified operand from a target-independent to a // target-specific node if it hasn't already been changed. @@ -947,9 +886,6 @@ case ISD::SETCC: Result = SelectSETCC(Op); return; - case PPCISD::CALL: - Result = SelectCALL(Op); - return; case PPCISD::GlobalBaseReg: Result = getGlobalBaseReg(); return; Index: llvm/lib/Target/PowerPC/PPCISelLowering.cpp diff -u llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.179 llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.180 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp:1.179 Wed May 17 01:01:33 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.cpp Wed May 17 14:00:46 2006 @@ -276,6 +276,8 @@ case PPCISD::EXTSW_32: return "PPCISD::EXTSW_32"; case PPCISD::STD_32: return "PPCISD::STD_32"; case PPCISD::CALL: return "PPCISD::CALL"; + case PPCISD::MTCTR: return "PPCISD::MTCTR"; + case PPCISD::BCTRL: return "PPCISD::BCTRL"; case PPCISD::RET_FLAG: return "PPCISD::RET_FLAG"; case PPCISD::MFCR: return "PPCISD::MFCR"; case PPCISD::VCMP: return "PPCISD::VCMP"; @@ -877,6 +879,21 @@ return DAG.getNode(ISD::MERGE_VALUES, RetVT, ArgValues); } +/// isCallCompatibleAddress - Return the immediate to use if the specified +/// 32-bit value is representable in the immediate field of a BxA instruction. +static SDNode *isBLACompatibleAddress(SDOperand Op, SelectionDAG &DAG) { + ConstantSDNode *C = dyn_cast<ConstantSDNode>(Op); + if (!C) return 0; + + int Addr = C->getValue(); + if ((Addr & 3) != 0 || // Low 2 bits are implicitly zero. + (Addr << 6 >> 6) != Addr) + return 0; // Top 6 bits have to be sext of immediate. + + return DAG.getConstant((int)C->getValue() >> 2, MVT::i32).Val; +} + + static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { SDOperand Chain = Op.getOperand(0); unsigned CallingConv= cast<ConstantSDNode>(Op.getOperand(1))->getValue(); @@ -1026,22 +1043,59 @@ InFlag = Chain.getValue(1); } - // If the callee is a GlobalAddress node (quite common, every direct call is) - // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. + std::vector<MVT::ValueType> NodeTys; + + // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every + // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol + // node so that legalize doesn't hack it. if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) Callee = DAG.getTargetGlobalAddress(G->getGlobal(), Callee.getValueType()); + else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) + Callee = DAG.getTargetExternalSymbol(S->getSymbol(), Callee.getValueType()); + else if (SDNode *Dest = isBLACompatibleAddress(Callee, DAG)) + // If this is an absolute destination address, use the munged value. + Callee = SDOperand(Dest, 0); + else { + // Otherwise, this is an indirect call. We have to use a MTCTR/BCTRL pair + // to do the call, we can't use PPCISD::CALL. + std::vector<SDOperand> Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + NodeTys.push_back(MVT::Other); + NodeTys.push_back(MVT::Flag); + + if (InFlag.Val) + Ops.push_back(InFlag); + Chain = DAG.getNode(PPCISD::MTCTR, NodeTys, Ops); + InFlag = Chain.getValue(1); + + // Copy the callee address into R12 on darwin. + Chain = DAG.getCopyToReg(Chain, PPC::R12, Callee, InFlag); + InFlag = Chain.getValue(1); - // Create the PPCISD::CALL node itself. - std::vector<MVT::ValueType> NodeTys; - NodeTys.push_back(MVT::Other); // Returns a chain - NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. - std::vector<SDOperand> Ops; - Ops.push_back(Chain); - Ops.push_back(Callee); - if (InFlag.Val) + NodeTys.clear(); + NodeTys.push_back(MVT::Other); + NodeTys.push_back(MVT::Flag); + Ops.clear(); + Ops.push_back(Chain); Ops.push_back(InFlag); - Chain = DAG.getNode(PPCISD::CALL, NodeTys, Ops); - InFlag = Chain.getValue(1); + Chain = DAG.getNode(PPCISD::BCTRL, NodeTys, Ops); + InFlag = Chain.getValue(1); + Callee.Val = 0; + } + + // Create the PPCISD::CALL node itself. + if (Callee.Val) { + NodeTys.push_back(MVT::Other); // Returns a chain + NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. + std::vector<SDOperand> Ops; + Ops.push_back(Chain); + Ops.push_back(Callee); + if (InFlag.Val) + Ops.push_back(InFlag); + Chain = DAG.getNode(PPCISD::CALL, NodeTys, Ops); + InFlag = Chain.getValue(1); + } std::vector<SDOperand> ResultVals; NodeTys.clear(); @@ -1086,6 +1140,11 @@ DAG.getConstant(NumBytes, MVT::i32)); NodeTys.push_back(MVT::Other); + // If the function returns void, just return the chain. + if (ResultVals.empty()) + return Chain; + + // Otherwise, merge everything together with a MERGE_VALUES node. ResultVals.push_back(Chain); SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, ResultVals); return Res.getValue(Op.ResNo); Index: llvm/lib/Target/PowerPC/PPCISelLowering.h diff -u llvm/lib/Target/PowerPC/PPCISelLowering.h:1.49 llvm/lib/Target/PowerPC/PPCISelLowering.h:1.50 --- llvm/lib/Target/PowerPC/PPCISelLowering.h:1.49 Tue May 16 17:56:08 2006 +++ llvm/lib/Target/PowerPC/PPCISelLowering.h Wed May 17 14:00:46 2006 @@ -75,9 +75,17 @@ /// STD_32 - This is the STD instruction for use with "32-bit" registers. STD_32, - /// CALL - A function call. + /// CALL - A direct function call. CALL, + /// CHAIN,FLAG = MTCTR(VAL, CHAIN[, INFLAG]) - Directly corresponds to a + /// MTCTR instruction. + MTCTR, + + /// CHAIN,FLAG = BCTRL(CHAIN, INFLAG) - Directly corresponds to a + /// BCTRL instruction. + BCTRL, + /// Return with a flag operand, matched by 'blr' RET_FLAG, Index: llvm/lib/Target/PowerPC/PPCInstrInfo.td diff -u llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.219 llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.220 --- llvm/lib/Target/PowerPC/PPCInstrInfo.td:1.219 Wed May 17 01:01:33 2006 +++ llvm/lib/Target/PowerPC/PPCInstrInfo.td Wed May 17 14:00:46 2006 @@ -24,7 +24,6 @@ SDTCisVT<0, i32>, SDTCisVT<1, i32>, SDTCisVT<2, i32> ]>; def SDT_PPCCallSeq : SDTypeProfile<0, 1, [ SDTCisVT<0, i32> ]>; -def SDT_PPCRetFlag : SDTypeProfile<0, 0, []>; def SDT_PPCvperm : SDTypeProfile<1, 3, [ SDTCisVT<3, v16i8>, SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2> @@ -73,10 +72,14 @@ def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_PPCCallSeq,[SDNPHasChain]>; def SDT_PPCCall : SDTypeProfile<0, 1, [SDTCisVT<0, i32>]>; -def call : SDNode<"PPCISD::CALL", SDT_PPCCall, +def PPCcall : SDNode<"PPCISD::CALL", SDT_PPCCall, [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; +def PPCmtctr : SDNode<"PPCISD::MTCTR", SDT_PPCCall, + [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; +def PPCbctrl : SDNode<"PPCISD::BCTRL", SDTRet, + [SDNPHasChain, SDNPOptInFlag, SDNPOutFlag]>; -def retflag : SDNode<"PPCISD::RET_FLAG", SDT_PPCRetFlag, +def retflag : SDNode<"PPCISD::RET_FLAG", SDTRet, [SDNPHasChain, SDNPOptInFlag]>; def PPCvcmp : SDNode<"PPCISD::VCMP" , SDT_PPCvcmp, []>; @@ -308,11 +311,11 @@ CR0,CR1,CR5,CR6,CR7] in { // Convenient aliases for call instructions def BL : IForm<18, 0, 1, (ops calltarget:$func), - "bl $func", BrB, []>; + "bl $func", BrB, []>; // See Pat patterns below. def BLA : IForm<18, 1, 1, (ops aaddr:$func), - "bla $func", BrB, []>; + "bla $func", BrB, [(PPCcall imm:$func)]>; def BCTRL : XLForm_2_ext<19, 528, 20, 0, 1, (ops), "bctrl", BrB, - []>; + [(PPCbctrl)]>; } // D-Form instructions. Most instructions that perform an operation on a @@ -701,8 +704,10 @@ // def MFCTR : XFXForm_1_ext<31, 339, 9, (ops GPRC:$rT), "mfctr $rT", SprMFSPR>, PPC970_DGroup_First, PPC970_Unit_FXU; +let Pattern = [(PPCmtctr GPRC:$rS)] in { def MTCTR : XFXForm_7_ext<31, 467, 9, (ops GPRC:$rS), "mtctr $rS", SprMTSPR>, PPC970_DGroup_First, PPC970_Unit_FXU; +} def MTLR : XFXForm_7_ext<31, 467, 8, (ops GPRC:$rS), "mtlr $rS", SprMTSPR>, PPC970_DGroup_First, PPC970_Unit_FXU; @@ -1013,7 +1018,13 @@ (RLWNM GPRC:$in, GPRC:$sh, 0, 31)>; def : Pat<(rotl GPRC:$in, (i32 imm:$imm)), (RLWINM GPRC:$in, imm:$imm, 0, 31)>; - + +// Calls +def : Pat<(PPCcall tglobaladdr:$dst), + (BL tglobaladdr:$dst)>; +def : Pat<(PPCcall texternalsym:$dst), + (BL texternalsym:$dst)>; + // Hi and Lo for Darwin Global Addresses. def : Pat<(PPChi tglobaladdr:$in, 0), (LIS tglobaladdr:$in)>; def : Pat<(PPClo tglobaladdr:$in, 0), (LI tglobaladdr:$in)>; _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits