Changeset View
Changeset View
Standalone View
Standalone View
llvm/lib/Target/RISCV/RISCVISelLowering.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 8,741 Lines • ▼ Show 20 Lines | static unsigned allocateRVVReg(MVT ValVT, unsigned ValNo, | ||||
if (RC == &RISCV::VRM4RegClass) | if (RC == &RISCV::VRM4RegClass) | ||||
return State.AllocateReg(ArgVRM4s); | return State.AllocateReg(ArgVRM4s); | ||||
if (RC == &RISCV::VRM8RegClass) | if (RC == &RISCV::VRM8RegClass) | ||||
return State.AllocateReg(ArgVRM8s); | return State.AllocateReg(ArgVRM8s); | ||||
llvm_unreachable("Unhandled register class for ValueType"); | llvm_unreachable("Unhandled register class for ValueType"); | ||||
} | } | ||||
// Implements the RISC-V calling convention. Returns true upon failure. | // Implements the RISC-V calling convention. Returns true upon failure. | ||||
static bool CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo, | bool RISCV::CC_RISCV(const DataLayout &DL, RISCVABI::ABI ABI, unsigned ValNo, | ||||
MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, | MVT ValVT, MVT LocVT, CCValAssign::LocInfo LocInfo, | ||||
ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed, | ISD::ArgFlagsTy ArgFlags, CCState &State, bool IsFixed, | ||||
bool IsRet, Type *OrigTy, const RISCVTargetLowering &TLI, | bool IsRet, Type *OrigTy, const RISCVTargetLowering &TLI, | ||||
Optional<unsigned> FirstMaskArgument) { | Optional<unsigned> FirstMaskArgument) { | ||||
unsigned XLen = DL.getLargestLegalIntTypeSizeInBits(); | unsigned XLen = DL.getLargestLegalIntTypeSizeInBits(); | ||||
assert(XLen == 32 || XLen == 64); | assert(XLen == 32 || XLen == 64); | ||||
MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64; | MVT XLenVT = XLen == 32 ? MVT::i32 : MVT::i64; | ||||
▲ Show 20 Lines • Show All 411 Lines • ▼ Show 20 Lines | if (VA.getLocReg() == RISCV::X17) { | ||||
RegInfo.addLiveIn(VA.getLocReg() + 1, HiVReg); | RegInfo.addLiveIn(VA.getLocReg() + 1, HiVReg); | ||||
Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i32); | Hi = DAG.getCopyFromReg(Chain, DL, HiVReg, MVT::i32); | ||||
} | } | ||||
return DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi); | return DAG.getNode(RISCVISD::BuildPairF64, DL, MVT::f64, Lo, Hi); | ||||
} | } | ||||
// FastCC has less than 1% performance improvement for some particular | // FastCC has less than 1% performance improvement for some particular | ||||
// benchmark. But theoretically, it may has benenfit for some cases. | // benchmark. But theoretically, it may has benenfit for some cases. | ||||
static bool CC_RISCV_FastCC(const DataLayout &DL, RISCVABI::ABI ABI, | bool RISCV::CC_RISCV_FastCC(const DataLayout &DL, RISCVABI::ABI ABI, | ||||
unsigned ValNo, MVT ValVT, MVT LocVT, | unsigned ValNo, MVT ValVT, MVT LocVT, | ||||
CCValAssign::LocInfo LocInfo, | CCValAssign::LocInfo LocInfo, | ||||
ISD::ArgFlagsTy ArgFlags, CCState &State, | ISD::ArgFlagsTy ArgFlags, CCState &State, | ||||
bool IsFixed, bool IsRet, Type *OrigTy, | bool IsFixed, bool IsRet, Type *OrigTy, | ||||
const RISCVTargetLowering &TLI, | const RISCVTargetLowering &TLI, | ||||
Optional<unsigned> FirstMaskArgument) { | Optional<unsigned> FirstMaskArgument) { | ||||
// X5 and X6 might be used for save-restore libcall. | // X5 and X6 might be used for save-restore libcall. | ||||
▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | if (LocVT.isVector()) { | ||||
} | } | ||||
return false; | return false; | ||||
} | } | ||||
return true; // CC didn't match. | return true; // CC didn't match. | ||||
} | } | ||||
static bool CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, | bool RISCV::CC_RISCV_GHC(unsigned ValNo, MVT ValVT, MVT LocVT, | ||||
CCValAssign::LocInfo LocInfo, | CCValAssign::LocInfo LocInfo, ISD::ArgFlagsTy ArgFlags, | ||||
ISD::ArgFlagsTy ArgFlags, CCState &State) { | CCState &State) { | ||||
if (LocVT == MVT::i32 || LocVT == MVT::i64) { | if (LocVT == MVT::i32 || LocVT == MVT::i64) { | ||||
// Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, R5, R6, R7, SpLim | // Pass in STG registers: Base, Sp, Hp, R1, R2, R3, R4, R5, R6, R7, SpLim | ||||
// s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 | // s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 | ||||
static const MCPhysReg GPRList[] = { | static const MCPhysReg GPRList[] = { | ||||
RISCV::X9, RISCV::X18, RISCV::X19, RISCV::X20, RISCV::X21, RISCV::X22, | RISCV::X9, RISCV::X18, RISCV::X19, RISCV::X20, RISCV::X21, RISCV::X22, | ||||
RISCV::X23, RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27}; | RISCV::X23, RISCV::X24, RISCV::X25, RISCV::X26, RISCV::X27}; | ||||
if (unsigned Reg = State.AllocateReg(GPRList)) { | if (unsigned Reg = State.AllocateReg(GPRList)) { | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | SDValue RISCVTargetLowering::LowerFormalArguments( | ||||
// Used with vargs to acumulate store chains. | // Used with vargs to acumulate store chains. | ||||
std::vector<SDValue> OutChains; | std::vector<SDValue> OutChains; | ||||
// Assign locations to all of the incoming arguments. | // Assign locations to all of the incoming arguments. | ||||
SmallVector<CCValAssign, 16> ArgLocs; | SmallVector<CCValAssign, 16> ArgLocs; | ||||
CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); | CCState CCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); | ||||
if (CallConv == CallingConv::GHC) | if (CallConv == CallingConv::GHC) | ||||
CCInfo.AnalyzeFormalArguments(Ins, CC_RISCV_GHC); | CCInfo.AnalyzeFormalArguments(Ins, RISCV::CC_RISCV_GHC); | ||||
else | else | ||||
analyzeInputArgs(MF, CCInfo, Ins, /*IsRet=*/false, | analyzeInputArgs(MF, CCInfo, Ins, /*IsRet=*/false, | ||||
CallConv == CallingConv::Fast ? CC_RISCV_FastCC | CallConv == CallingConv::Fast ? RISCV::CC_RISCV_FastCC | ||||
: CC_RISCV); | : RISCV::CC_RISCV); | ||||
for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { | for (unsigned i = 0, e = ArgLocs.size(); i != e; ++i) { | ||||
CCValAssign &VA = ArgLocs[i]; | CCValAssign &VA = ArgLocs[i]; | ||||
SDValue ArgValue; | SDValue ArgValue; | ||||
// Passing f64 on RV32D with a soft float ABI must be handled as a special | // Passing f64 on RV32D with a soft float ABI must be handled as a special | ||||
// case. | // case. | ||||
if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) | if (VA.getLocVT() == MVT::i32 && VA.getValVT() == MVT::f64) | ||||
ArgValue = unpackF64OnRV32DSoftABI(DAG, Chain, VA, DL); | ArgValue = unpackF64OnRV32DSoftABI(DAG, Chain, VA, DL); | ||||
▲ Show 20 Lines • Show All 191 Lines • ▼ Show 20 Lines | SDValue RISCVTargetLowering::LowerCall(CallLoweringInfo &CLI, | ||||
MachineFunction &MF = DAG.getMachineFunction(); | MachineFunction &MF = DAG.getMachineFunction(); | ||||
// Analyze the operands of the call, assigning locations to each operand. | // Analyze the operands of the call, assigning locations to each operand. | ||||
SmallVector<CCValAssign, 16> ArgLocs; | SmallVector<CCValAssign, 16> ArgLocs; | ||||
CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); | CCState ArgCCInfo(CallConv, IsVarArg, MF, ArgLocs, *DAG.getContext()); | ||||
if (CallConv == CallingConv::GHC) | if (CallConv == CallingConv::GHC) | ||||
ArgCCInfo.AnalyzeCallOperands(Outs, CC_RISCV_GHC); | ArgCCInfo.AnalyzeCallOperands(Outs, RISCV::CC_RISCV_GHC); | ||||
else | else | ||||
analyzeOutputArgs(MF, ArgCCInfo, Outs, /*IsRet=*/false, &CLI, | analyzeOutputArgs(MF, ArgCCInfo, Outs, /*IsRet=*/false, &CLI, | ||||
CallConv == CallingConv::Fast ? CC_RISCV_FastCC | CallConv == CallingConv::Fast ? RISCV::CC_RISCV_FastCC | ||||
: CC_RISCV); | : RISCV::CC_RISCV); | ||||
// Check if it's really possible to do a tail call. | // Check if it's really possible to do a tail call. | ||||
if (IsTailCall) | if (IsTailCall) | ||||
IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs); | IsTailCall = isEligibleForTailCallOptimization(ArgCCInfo, CLI, MF, ArgLocs); | ||||
if (IsTailCall) | if (IsTailCall) | ||||
++NumTailCalls; | ++NumTailCalls; | ||||
else if (CLI.CB && CLI.CB->isMustTailCall()) | else if (CLI.CB && CLI.CB->isMustTailCall()) | ||||
▲ Show 20 Lines • Show All 228 Lines • ▼ Show 20 Lines | Chain = DAG.getCALLSEQ_END(Chain, | ||||
DAG.getConstant(NumBytes, DL, PtrVT, true), | DAG.getConstant(NumBytes, DL, PtrVT, true), | ||||
DAG.getConstant(0, DL, PtrVT, true), | DAG.getConstant(0, DL, PtrVT, true), | ||||
Glue, DL); | Glue, DL); | ||||
Glue = Chain.getValue(1); | Glue = Chain.getValue(1); | ||||
// Assign locations to each value returned by this call. | // Assign locations to each value returned by this call. | ||||
SmallVector<CCValAssign, 16> RVLocs; | SmallVector<CCValAssign, 16> RVLocs; | ||||
CCState RetCCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); | CCState RetCCInfo(CallConv, IsVarArg, MF, RVLocs, *DAG.getContext()); | ||||
analyzeInputArgs(MF, RetCCInfo, Ins, /*IsRet=*/true, CC_RISCV); | analyzeInputArgs(MF, RetCCInfo, Ins, /*IsRet=*/true, RISCV::CC_RISCV); | ||||
// Copy all of the result registers out of their specified physreg. | // Copy all of the result registers out of their specified physreg. | ||||
for (auto &VA : RVLocs) { | for (auto &VA : RVLocs) { | ||||
// Copy the value out | // Copy the value out | ||||
SDValue RetValue = | SDValue RetValue = | ||||
DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue); | DAG.getCopyFromReg(Chain, DL, VA.getLocReg(), VA.getLocVT(), Glue); | ||||
// Glue the RetValue to the end of the call sequence | // Glue the RetValue to the end of the call sequence | ||||
Chain = RetValue.getValue(1); | Chain = RetValue.getValue(1); | ||||
Show All 26 Lines | bool RISCVTargetLowering::CanLowerReturn( | ||||
Optional<unsigned> FirstMaskArgument; | Optional<unsigned> FirstMaskArgument; | ||||
if (Subtarget.hasVInstructions()) | if (Subtarget.hasVInstructions()) | ||||
FirstMaskArgument = preAssignMask(Outs); | FirstMaskArgument = preAssignMask(Outs); | ||||
for (unsigned i = 0, e = Outs.size(); i != e; ++i) { | for (unsigned i = 0, e = Outs.size(); i != e; ++i) { | ||||
MVT VT = Outs[i].VT; | MVT VT = Outs[i].VT; | ||||
ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; | ISD::ArgFlagsTy ArgFlags = Outs[i].Flags; | ||||
RISCVABI::ABI ABI = MF.getSubtarget<RISCVSubtarget>().getTargetABI(); | RISCVABI::ABI ABI = MF.getSubtarget<RISCVSubtarget>().getTargetABI(); | ||||
if (CC_RISCV(MF.getDataLayout(), ABI, i, VT, VT, CCValAssign::Full, | if (RISCV::CC_RISCV(MF.getDataLayout(), ABI, i, VT, VT, CCValAssign::Full, | ||||
ArgFlags, CCInfo, /*IsFixed=*/true, /*IsRet=*/true, nullptr, | ArgFlags, CCInfo, /*IsFixed=*/true, /*IsRet=*/true, | ||||
*this, FirstMaskArgument)) | nullptr, *this, FirstMaskArgument)) | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
SDValue | SDValue | ||||
RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, | RISCVTargetLowering::LowerReturn(SDValue Chain, CallingConv::ID CallConv, | ||||
bool IsVarArg, | bool IsVarArg, | ||||
const SmallVectorImpl<ISD::OutputArg> &Outs, | const SmallVectorImpl<ISD::OutputArg> &Outs, | ||||
const SmallVectorImpl<SDValue> &OutVals, | const SmallVectorImpl<SDValue> &OutVals, | ||||
const SDLoc &DL, SelectionDAG &DAG) const { | const SDLoc &DL, SelectionDAG &DAG) const { | ||||
const MachineFunction &MF = DAG.getMachineFunction(); | const MachineFunction &MF = DAG.getMachineFunction(); | ||||
const RISCVSubtarget &STI = MF.getSubtarget<RISCVSubtarget>(); | const RISCVSubtarget &STI = MF.getSubtarget<RISCVSubtarget>(); | ||||
// Stores the assignment of the return value to a location. | // Stores the assignment of the return value to a location. | ||||
SmallVector<CCValAssign, 16> RVLocs; | SmallVector<CCValAssign, 16> RVLocs; | ||||
// Info about the registers and stack slot. | // Info about the registers and stack slot. | ||||
CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, | CCState CCInfo(CallConv, IsVarArg, DAG.getMachineFunction(), RVLocs, | ||||
*DAG.getContext()); | *DAG.getContext()); | ||||
analyzeOutputArgs(DAG.getMachineFunction(), CCInfo, Outs, /*IsRet=*/true, | analyzeOutputArgs(DAG.getMachineFunction(), CCInfo, Outs, /*IsRet=*/true, | ||||
nullptr, CC_RISCV); | nullptr, RISCV::CC_RISCV); | ||||
if (CallConv == CallingConv::GHC && !RVLocs.empty()) | if (CallConv == CallingConv::GHC && !RVLocs.empty()) | ||||
report_fatal_error("GHC functions return void only"); | report_fatal_error("GHC functions return void only"); | ||||
SDValue Glue; | SDValue Glue; | ||||
SmallVector<SDValue, 4> RetOps(1, Chain); | SmallVector<SDValue, 4> RetOps(1, Chain); | ||||
// Copy the result values into the output registers. | // Copy the result values into the output registers. | ||||
▲ Show 20 Lines • Show All 1,021 Lines • Show Last 20 Lines |