diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:01:22 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2017-04-16 16:01:22 +0000 |
commit | 71d5a2540a98c81f5bcaeb48805e0e2881f530ef (patch) | |
tree | 5343938942df402b49ec7300a1c25a2d4ccd5821 /lib/Target/Hexagon/HexagonISelLowering.cpp | |
parent | 31bbf64f3a4974a2d6c8b3b27ad2f519caf74057 (diff) | |
download | src-71d5a2540a98c81f5bcaeb48805e0e2881f530ef.tar.gz src-71d5a2540a98c81f5bcaeb48805e0e2881f530ef.zip |
Vendor import of llvm trunk r300422:vendor/llvm/llvm-trunk-r300422
Notes
Notes:
svn path=/vendor/llvm/dist/; revision=317017
svn path=/vendor/llvm/llvm-trunk-r300422/; revision=317018; tag=vendor/llvm/llvm-trunk-r300422
Diffstat (limited to 'lib/Target/Hexagon/HexagonISelLowering.cpp')
-rw-r--r-- | lib/Target/Hexagon/HexagonISelLowering.cpp | 170 |
1 files changed, 95 insertions, 75 deletions
diff --git a/lib/Target/Hexagon/HexagonISelLowering.cpp b/lib/Target/Hexagon/HexagonISelLowering.cpp index e87e1e6a7e0f..418dd71aeb4b 100644 --- a/lib/Target/Hexagon/HexagonISelLowering.cpp +++ b/lib/Target/Hexagon/HexagonISelLowering.cpp @@ -256,7 +256,9 @@ static bool CC_Hexagon (unsigned ValNo, MVT ValVT, MVT LocVT, return false; } - if (LocVT == MVT::i1 || LocVT == MVT::i8 || LocVT == MVT::i16) { + if (LocVT == MVT::i1) { + LocVT = MVT::i32; + } else if (LocVT == MVT::i8 || LocVT == MVT::i16) { LocVT = MVT::i32; ValVT = MVT::i32; if (ArgFlags.isSExt()) @@ -483,9 +485,7 @@ static bool RetCC_Hexagon32(unsigned ValNo, MVT ValVT, } } - unsigned Offset = State.AllocateStack(4, 4); - State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); - return false; + return true; } static bool RetCC_Hexagon64(unsigned ValNo, MVT ValVT, @@ -498,9 +498,7 @@ static bool RetCC_Hexagon64(unsigned ValNo, MVT ValVT, } } - unsigned Offset = State.AllocateStack(8, 8); - State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); - return false; + return true; } static bool RetCC_HexagonVector(unsigned ValNo, MVT ValVT, @@ -511,7 +509,6 @@ static bool RetCC_HexagonVector(unsigned ValNo, MVT ValVT, bool UseHVX = HST.useHVXOps(); bool UseHVXDbl = HST.useHVXDblOps(); - unsigned OffSiz = 64; if (LocVT == MVT::v16i32) { if (unsigned Reg = State.AllocateReg(Hexagon::V0)) { State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); @@ -523,18 +520,14 @@ static bool RetCC_HexagonVector(unsigned ValNo, MVT ValVT, State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); return false; } - OffSiz = 128; } else if (LocVT == MVT::v64i32) { if (unsigned Reg = State.AllocateReg(Hexagon::W0)) { State.addLoc(CCValAssign::getReg(ValNo, ValVT, Reg, LocVT, LocInfo)); return false; } - OffSiz = 256; } - unsigned Offset = State.AllocateStack(OffSiz, OffSiz); - State.addLoc(CCValAssign::getMem(ValNo, ValVT, Offset, LocVT, LocInfo)); - return false; + return true; } void HexagonTargetLowering::promoteLdStType(MVT VT, MVT PromotedLdStVT) { @@ -590,6 +583,16 @@ static bool isHvxVectorType(MVT Ty) { } } +bool +HexagonTargetLowering::CanLowerReturn( + CallingConv::ID CallConv, MachineFunction &MF, bool isVarArg, + const SmallVectorImpl<ISD::OutputArg> &Outs, + LLVMContext &Context) const { + SmallVector<CCValAssign, 16> RVLocs; + CCState CCInfo(CallConv, isVarArg, MF, RVLocs, Context); + return CCInfo.CheckReturn(Outs, RetCC_Hexagon); +} + // LowerReturn - Lower ISD::RET. If a struct is larger than 8 bytes and is // passed by value, the function prototype is modified to return void and // the value is stored in memory pointed by a pointer passed by caller. @@ -644,11 +647,11 @@ bool HexagonTargetLowering::mayBeEmittedAsTailCall(CallInst *CI) const { /// LowerCallResult - Lower the result values of an ISD::CALL into the /// appropriate copies out of appropriate physical registers. This assumes that -/// Chain/InFlag are the input chain/flag to use, and that TheCall is the call +/// Chain/Glue are the input chain/glue to use, and that TheCall is the call /// being lowered. Returns a SDNode with the same number of values as the /// ISD::CALL. SDValue HexagonTargetLowering::LowerCallResult( - SDValue Chain, SDValue InFlag, CallingConv::ID CallConv, bool isVarArg, + SDValue Chain, SDValue Glue, CallingConv::ID CallConv, bool isVarArg, const SmallVectorImpl<ISD::InputArg> &Ins, const SDLoc &dl, SelectionDAG &DAG, SmallVectorImpl<SDValue> &InVals, const SmallVectorImpl<SDValue> &OutVals, SDValue Callee) const { @@ -671,21 +674,24 @@ SDValue HexagonTargetLowering::LowerCallResult( // predicate register as the call result. auto &MRI = DAG.getMachineFunction().getRegInfo(); SDValue FR0 = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), - MVT::i32, InFlag); + MVT::i32, Glue); // FR0 = (Value, Chain, Glue) unsigned PredR = MRI.createVirtualRegister(&Hexagon::PredRegsRegClass); SDValue TPR = DAG.getCopyToReg(FR0.getValue(1), dl, PredR, FR0.getValue(0), FR0.getValue(2)); // TPR = (Chain, Glue) - RetVal = DAG.getCopyFromReg(TPR.getValue(0), dl, PredR, MVT::i1, - TPR.getValue(1)); + // Don't glue this CopyFromReg, because it copies from a virtual + // register. If it is glued to the call, InstrEmitter will add it + // as an implicit def to the call (EmitMachineNode). + RetVal = DAG.getCopyFromReg(TPR.getValue(0), dl, PredR, MVT::i1); + Glue = TPR.getValue(1); } else { RetVal = DAG.getCopyFromReg(Chain, dl, RVLocs[i].getLocReg(), - RVLocs[i].getValVT(), InFlag); + RVLocs[i].getValVT(), Glue); + Glue = RetVal.getValue(2); } InVals.push_back(RetVal.getValue(0)); Chain = RetVal.getValue(1); - InFlag = RetVal.getValue(2); } return Chain; @@ -840,16 +846,17 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, if (!MemOpChains.empty()) Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, MemOpChains); + SDValue Glue; if (!IsTailCall) { SDValue C = DAG.getConstant(NumBytes, dl, PtrVT, true); Chain = DAG.getCALLSEQ_START(Chain, C, dl); + Glue = Chain.getValue(1); } // Build a sequence of copy-to-reg nodes chained together with token // chain and flag operands which copy the outgoing args into registers. // The Glue is necessary since all emitted instructions must be // stuck together. - SDValue Glue; if (!IsTailCall) { for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { Chain = DAG.getCopyToReg(Chain, dl, RegsToPass[i].first, @@ -902,6 +909,10 @@ HexagonTargetLowering::LowerCall(TargetLowering::CallLoweringInfo &CLI, RegsToPass[i].second.getValueType())); } + const uint32_t *Mask = HRI.getCallPreservedMask(MF, CallConv); + assert(Mask && "Missing call preserved mask for calling convention"); + Ops.push_back(DAG.getRegisterMask(Mask)); + if (Glue.getNode()) Ops.push_back(Glue); @@ -1054,6 +1065,18 @@ SDValue HexagonTargetLowering::LowerPREFETCH(SDValue Op, return DAG.getNode(HexagonISD::DCFETCH, DL, MVT::Other, Chain, Addr, Zero); } +// Custom-handle ISD::READCYCLECOUNTER because the target-independent SDNode +// is marked as having side-effects, while the register read on Hexagon does +// not have any. TableGen refuses to accept the direct pattern from that node +// to the A4_tfrcpp. +SDValue HexagonTargetLowering::LowerREADCYCLECOUNTER(SDValue Op, + SelectionDAG &DAG) const { + SDValue Chain = Op.getOperand(0); + SDLoc dl(Op); + SDVTList VTs = DAG.getVTList(MVT::i32, MVT::Other); + return DAG.getNode(HexagonISD::READCYCLE, dl, VTs, Chain); +} + SDValue HexagonTargetLowering::LowerINTRINSIC_VOID(SDValue Op, SelectionDAG &DAG) const { SDValue Chain = Op.getOperand(0); @@ -1140,10 +1163,25 @@ SDValue HexagonTargetLowering::LowerFormalArguments( EVT RegVT = VA.getLocVT(); if (RegVT == MVT::i8 || RegVT == MVT::i16 || RegVT == MVT::i32 || RegVT == MVT::f32) { - unsigned VReg = + unsigned VReg = RegInfo.createVirtualRegister(&Hexagon::IntRegsRegClass); RegInfo.addLiveIn(VA.getLocReg(), VReg); - InVals.push_back(DAG.getCopyFromReg(Chain, dl, VReg, RegVT)); + SDValue Copy = DAG.getCopyFromReg(Chain, dl, VReg, RegVT); + // Treat values of type MVT::i1 specially: they are passed in + // registers of type i32, but they need to remain as values of + // type i1 for consistency of the argument lowering. + if (VA.getValVT() == MVT::i1) { + // Generate a copy into a predicate register and use the value + // of the register as the "InVal". + unsigned PReg = + RegInfo.createVirtualRegister(&Hexagon::PredRegsRegClass); + SDNode *T = DAG.getMachineNode(Hexagon::C2_tfrrp, dl, MVT::i1, + Copy.getValue(0)); + Copy = DAG.getCopyToReg(Copy.getValue(1), dl, PReg, SDValue(T, 0)); + Copy = DAG.getCopyFromReg(Copy, dl, PReg, MVT::i1); + } + InVals.push_back(Copy); + Chain = Copy.getValue(1); } else if (RegVT == MVT::i64 || RegVT == MVT::f64) { unsigned VReg = RegInfo.createVirtualRegister(&Hexagon::DoubleRegsRegClass); @@ -1217,7 +1255,7 @@ SDValue HexagonTargetLowering::LowerFormalArguments( InVals.push_back(FIN); } else { InVals.push_back( - DAG.getLoad(VA.getLocVT(), dl, Chain, FIN, MachinePointerInfo())); + DAG.getLoad(VA.getValVT(), dl, Chain, FIN, MachinePointerInfo())); } } } @@ -1272,17 +1310,6 @@ static bool isSExtFree(SDValue N) { return false; } -SDValue HexagonTargetLowering::LowerCTPOP(SDValue Op, SelectionDAG &DAG) const { - SDLoc dl(Op); - SDValue InpVal = Op.getOperand(0); - if (isa<ConstantSDNode>(InpVal)) { - uint64_t V = cast<ConstantSDNode>(InpVal)->getZExtValue(); - return DAG.getTargetConstant(countPopulation(V), dl, MVT::i64); - } - SDValue PopOut = DAG.getNode(HexagonISD::POPCOUNT, dl, MVT::i32, InpVal); - return DAG.getNode(ISD::ZERO_EXTEND, dl, MVT::i64, PopOut); -} - SDValue HexagonTargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) const { SDLoc dl(Op); @@ -1571,9 +1598,10 @@ HexagonTargetLowering::LowerGLOBAL_OFFSET_TABLE(SDValue Op, SelectionDAG &DAG) SDValue HexagonTargetLowering::GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain, - GlobalAddressSDNode *GA, SDValue *InFlag, EVT PtrVT, unsigned ReturnReg, + GlobalAddressSDNode *GA, SDValue Glue, EVT PtrVT, unsigned ReturnReg, unsigned char OperandFlags) const { - MachineFrameInfo &MFI = DAG.getMachineFunction().getFrameInfo(); + MachineFunction &MF = DAG.getMachineFunction(); + MachineFrameInfo &MFI = MF.getFrameInfo(); SDVTList NodeTys = DAG.getVTList(MVT::Other, MVT::Glue); SDLoc dl(GA); SDValue TGA = DAG.getTargetGlobalAddress(GA->getGlobal(), dl, @@ -1585,23 +1613,21 @@ HexagonTargetLowering::GetDynamicTLSAddr(SelectionDAG &DAG, SDValue Chain, // 2. Callee which in this case is the Global address value. // 3. Registers live into the call.In this case its R0, as we // have just one argument to be passed. - // 4. InFlag if there is any. + // 4. Glue. // Note: The order is important. - if (InFlag) { - SDValue Ops[] = { Chain, TGA, - DAG.getRegister(Hexagon::R0, PtrVT), *InFlag }; - Chain = DAG.getNode(HexagonISD::CALL, dl, NodeTys, Ops); - } else { - SDValue Ops[] = { Chain, TGA, DAG.getRegister(Hexagon::R0, PtrVT)}; - Chain = DAG.getNode(HexagonISD::CALL, dl, NodeTys, Ops); - } + const auto &HRI = *Subtarget.getRegisterInfo(); + const uint32_t *Mask = HRI.getCallPreservedMask(MF, CallingConv::C); + assert(Mask && "Missing call preserved mask for calling convention"); + SDValue Ops[] = { Chain, TGA, DAG.getRegister(Hexagon::R0, PtrVT), + DAG.getRegisterMask(Mask), Glue }; + Chain = DAG.getNode(HexagonISD::CALL, dl, NodeTys, Ops); // Inform MFI that function has calls. MFI.setAdjustsStack(true); - SDValue Flag = Chain.getValue(1); - return DAG.getCopyFromReg(Chain, dl, ReturnReg, PtrVT, Flag); + Glue = Chain.getValue(1); + return DAG.getCopyFromReg(Chain, dl, ReturnReg, PtrVT, Glue); } // @@ -1694,7 +1720,7 @@ HexagonTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, Chain = DAG.getCopyToReg(DAG.getEntryNode(), dl, Hexagon::R0, Chain, InFlag); InFlag = Chain.getValue(1); - return GetDynamicTLSAddr(DAG, Chain, GA, &InFlag, PtrVT, + return GetDynamicTLSAddr(DAG, Chain, GA, InFlag, PtrVT, Hexagon::R0, HexagonII::MO_GDPLT); } @@ -1821,6 +1847,7 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1, Expand); setOperationAction(ISD::INLINEASM, MVT::Other, Custom); setOperationAction(ISD::PREFETCH, MVT::Other, Custom); + setOperationAction(ISD::READCYCLECOUNTER, MVT::i64, Custom); setOperationAction(ISD::INTRINSIC_VOID, MVT::Other, Custom); setOperationAction(ISD::EH_RETURN, MVT::Other, Custom); setOperationAction(ISD::GLOBAL_OFFSET_TABLE, MVT::i32, Custom); @@ -1891,7 +1918,12 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, setOperationAction(ISD::CTPOP, MVT::i8, Promote); setOperationAction(ISD::CTPOP, MVT::i16, Promote); setOperationAction(ISD::CTPOP, MVT::i32, Promote); - setOperationAction(ISD::CTPOP, MVT::i64, Custom); + setOperationAction(ISD::CTPOP, MVT::i64, Legal); + + setOperationAction(ISD::BITREVERSE, MVT::i32, Legal); + setOperationAction(ISD::BITREVERSE, MVT::i64, Legal); + setOperationAction(ISD::BSWAP, MVT::i32, Legal); + setOperationAction(ISD::BSWAP, MVT::i64, Legal); // We custom lower i64 to i64 mul, so that it is not considered as a legal // operation. There is a pattern that will match i64 mul and transform it @@ -1901,7 +1933,7 @@ HexagonTargetLowering::HexagonTargetLowering(const TargetMachine &TM, for (unsigned IntExpOp : { ISD::SDIV, ISD::UDIV, ISD::SREM, ISD::UREM, ISD::SDIVREM, ISD::UDIVREM, ISD::ROTL, ISD::ROTR, - ISD::BSWAP, ISD::SHL_PARTS, ISD::SRA_PARTS, ISD::SRL_PARTS, + ISD::SHL_PARTS, ISD::SRA_PARTS, ISD::SRL_PARTS, ISD::SMUL_LOHI, ISD::UMUL_LOHI }) { setOperationAction(IntExpOp, MVT::i32, Expand); setOperationAction(IntExpOp, MVT::i64, Expand); @@ -2268,7 +2300,6 @@ const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const { case HexagonISD::INSERTRP: return "HexagonISD::INSERTRP"; case HexagonISD::JT: return "HexagonISD::JT"; case HexagonISD::PACKHL: return "HexagonISD::PACKHL"; - case HexagonISD::POPCOUNT: return "HexagonISD::POPCOUNT"; case HexagonISD::RET_FLAG: return "HexagonISD::RET_FLAG"; case HexagonISD::SHUFFEB: return "HexagonISD::SHUFFEB"; case HexagonISD::SHUFFEH: return "HexagonISD::SHUFFEH"; @@ -2296,6 +2327,7 @@ const char* HexagonTargetLowering::getTargetNodeName(unsigned Opcode) const { case HexagonISD::VSRLW: return "HexagonISD::VSRLW"; case HexagonISD::VSXTBH: return "HexagonISD::VSXTBH"; case HexagonISD::VSXTBW: return "HexagonISD::VSXTBW"; + case HexagonISD::READCYCLE: return "HexagonISD::READCYCLE"; case HexagonISD::OP_END: break; } return nullptr; @@ -2968,11 +3000,11 @@ HexagonTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const { case ISD::DYNAMIC_STACKALLOC: return LowerDYNAMIC_STACKALLOC(Op, DAG); case ISD::SETCC: return LowerSETCC(Op, DAG); case ISD::VSELECT: return LowerVSELECT(Op, DAG); - case ISD::CTPOP: return LowerCTPOP(Op, DAG); case ISD::INTRINSIC_WO_CHAIN: return LowerINTRINSIC_WO_CHAIN(Op, DAG); case ISD::INTRINSIC_VOID: return LowerINTRINSIC_VOID(Op, DAG); case ISD::INLINEASM: return LowerINLINEASM(Op, DAG); case ISD::PREFETCH: return LowerPREFETCH(Op, DAG); + case ISD::READCYCLECOUNTER: return LowerREADCYCLECOUNTER(Op, DAG); } } @@ -3026,37 +3058,25 @@ HexagonTargetLowering::getRegForInlineAsmConstraint( return std::make_pair(0U, &Hexagon::DoubleRegsRegClass); } case 'q': // q0-q3 - switch (VT.SimpleTy) { + switch (VT.getSizeInBits()) { default: - llvm_unreachable("getRegForInlineAsmConstraint Unhandled data type"); - case MVT::v1024i1: - case MVT::v512i1: - case MVT::v32i16: - case MVT::v16i32: - case MVT::v64i8: - case MVT::v8i64: + llvm_unreachable("getRegForInlineAsmConstraint Unhandled vector size"); + case 512: return std::make_pair(0U, &Hexagon::VecPredRegsRegClass); + case 1024: + return std::make_pair(0U, &Hexagon::VecPredRegs128BRegClass); } case 'v': // V0-V31 - switch (VT.SimpleTy) { + switch (VT.getSizeInBits()) { default: - llvm_unreachable("getRegForInlineAsmConstraint Unhandled data type"); - case MVT::v16i32: - case MVT::v32i16: - case MVT::v64i8: - case MVT::v8i64: + llvm_unreachable("getRegForInlineAsmConstraint Unhandled vector size"); + case 512: return std::make_pair(0U, &Hexagon::VectorRegsRegClass); - case MVT::v32i32: - case MVT::v64i16: - case MVT::v16i64: - case MVT::v128i8: + case 1024: if (Subtarget.hasV60TOps() && UseHVX && UseHVXDbl) return std::make_pair(0U, &Hexagon::VectorRegs128BRegClass); return std::make_pair(0U, &Hexagon::VecDblRegsRegClass); - case MVT::v256i8: - case MVT::v128i16: - case MVT::v64i32: - case MVT::v32i64: + case 2048: return std::make_pair(0U, &Hexagon::VecDblRegs128BRegClass); } |