diff --git a/llvm/include/llvm/CodeGen/TargetLowering.h b/llvm/include/llvm/CodeGen/TargetLowering.h index 69ae4f80297d5..fa08eb64642de 100644 --- a/llvm/include/llvm/CodeGen/TargetLowering.h +++ b/llvm/include/llvm/CodeGen/TargetLowering.h @@ -3562,6 +3562,11 @@ class LLVM_ABI TargetLoweringBase { Libcalls.setLibcallImpl(Call, Impl); } + /// Get the libcall impl routine name for the specified libcall. + RTLIB::LibcallImpl getLibcallImpl(RTLIB::Libcall Call) const { + return Libcalls.getLibcallImpl(Call); + } + /// Get the libcall routine name for the specified libcall. const char *getLibcallName(RTLIB::Libcall Call) const { return Libcalls.getLibcallName(Call); @@ -3584,11 +3589,18 @@ class LLVM_ABI TargetLoweringBase { } /// Set the CallingConv that should be used for the specified libcall. - void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) { - Libcalls.setLibcallCallingConv(Call, CC); + void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) { + Libcalls.setLibcallImplCallingConv(Call, CC); + } + + /// Get the CallingConv that should be used for the specified libcall + /// implementation. + CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const { + return Libcalls.getLibcallImplCallingConv(Call); } /// Get the CallingConv that should be used for the specified libcall. + // FIXME: Remove this wrapper and directly use the used LibcallImpl CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const { return Libcalls.getLibcallCallingConv(Call); } diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h index d69c23753da7a..dce16ab99171f 100644 --- a/llvm/include/llvm/IR/RuntimeLibcalls.h +++ b/llvm/include/llvm/IR/RuntimeLibcalls.h @@ -37,6 +37,10 @@ template <> struct enum_iteration_traits { static constexpr bool is_iterable = true; }; +template <> struct enum_iteration_traits { + static constexpr bool is_iterable = true; +}; + namespace RTLIB { // Return an iterator over all Libcall values. @@ -44,6 +48,10 @@ static inline auto libcalls() { return enum_seq(static_cast(0), RTLIB::UNKNOWN_LIBCALL); } +static inline auto libcall_impls() { + return enum_seq(static_cast(1), RTLIB::NumLibcallImpls); +} + /// A simple container for information about the supported runtime calls. struct RuntimeLibcallsInfo { explicit RuntimeLibcallsInfo( @@ -76,16 +84,21 @@ struct RuntimeLibcallsInfo { return LibcallImpls[Call]; } - /// Set the CallingConv that should be used for the specified libcall. - // FIXME: This should be a function of RTLIB::LibcallImpl - void setLibcallCallingConv(RTLIB::Libcall Call, CallingConv::ID CC) { - LibcallCallingConvs[Call] = CC; + /// Set the CallingConv that should be used for the specified libcall + /// implementation + void setLibcallImplCallingConv(RTLIB::LibcallImpl Call, CallingConv::ID CC) { + LibcallImplCallingConvs[Call] = CC; } - /// Get the CallingConv that should be used for the specified libcall. - // FIXME: This should be a function of RTLIB::LibcallImpl + // FIXME: Remove this wrapper in favor of directly using + // getLibcallImplCallingConv CallingConv::ID getLibcallCallingConv(RTLIB::Libcall Call) const { - return LibcallCallingConvs[Call]; + return LibcallImplCallingConvs[LibcallImpls[Call]]; + } + + /// Get the CallingConv that should be used for the specified libcall. + CallingConv::ID getLibcallImplCallingConv(RTLIB::LibcallImpl Call) const { + return LibcallImplCallingConvs[Call]; } ArrayRef getLibcallImpls() const { @@ -130,8 +143,9 @@ struct RuntimeLibcallsInfo { static_assert(static_cast(CallingConv::C) == 0, "default calling conv should be encoded as 0"); - /// Stores the CallingConv that should be used for each libcall. - CallingConv::ID LibcallCallingConvs[RTLIB::UNKNOWN_LIBCALL] = {}; + /// Stores the CallingConv that should be used for each libcall + /// implementation.; + CallingConv::ID LibcallImplCallingConvs[RTLIB::NumLibcallImpls] = {}; /// The condition type that should be used to test the result of each of the /// soft floating-point comparison libcall against integer zero. diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp index eaa2cf5100c77..9492aef16e638 100644 --- a/llvm/lib/IR/RuntimeLibcalls.cpp +++ b/llvm/lib/IR/RuntimeLibcalls.cpp @@ -29,8 +29,8 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, CallingConv::ID DefaultCC = FloatABIType == FloatABI::Hard ? CallingConv::ARM_AAPCS_VFP : CallingConv::ARM_AAPCS; - for (RTLIB::Libcall LC : RTLIB::libcalls()) - Info.setLibcallCallingConv(LC, DefaultCC); + for (RTLIB::LibcallImpl LC : RTLIB::libcall_impls()) + Info.setLibcallImplCallingConv(LC, DefaultCC); } // Register based DivRem for AEABI (RTABI 4.2) @@ -50,7 +50,7 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, for (const auto &LC : LibraryCalls) { Info.setLibcallImpl(LC.Op, LC.Impl); - Info.setLibcallCallingConv(LC.Op, LC.CC); + Info.setLibcallImplCallingConv(LC.Impl, LC.CC); } } else { const struct { @@ -66,7 +66,7 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, for (const auto &LC : LibraryCalls) { Info.setLibcallImpl(LC.Op, LC.Impl); - Info.setLibcallCallingConv(LC.Op, LC.CC); + Info.setLibcallImplCallingConv(LC.Impl, LC.CC); } } } @@ -89,7 +89,7 @@ static void setARMLibcallNames(RuntimeLibcallsInfo &Info, const Triple &TT, for (const auto &LC : LibraryCalls) { Info.setLibcallImpl(LC.Op, LC.Impl); - Info.setLibcallCallingConv(LC.Op, LC.CC); + Info.setLibcallImplCallingConv(LC.Impl, LC.CC); } } @@ -199,20 +199,34 @@ static void setMSP430Libcalls(RuntimeLibcallsInfo &Info, const Triple &TT) { Info.setLibcallImpl(LC.Op, LC.Impl); // Several of the runtime library functions use a special calling conv - Info.setLibcallCallingConv(RTLIB::UDIV_I64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::UREM_I64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::SDIV_I64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::SREM_I64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::ADD_F64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::SUB_F64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::MUL_F64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::DIV_F64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::OEQ_F64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::UNE_F64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::OGE_F64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::OLT_F64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::OLE_F64, CallingConv::MSP430_BUILTIN); - Info.setLibcallCallingConv(RTLIB::OGT_F64, CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_divull, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_remull, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_divlli, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_remlli, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_addd, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_subd, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_mpyd, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_divd, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__oeq, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__une, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__oge, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__olt, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__ole, + CallingConv::MSP430_BUILTIN); + Info.setLibcallImplCallingConv(RTLIB::__mspabi_cmpd__ogt, + CallingConv::MSP430_BUILTIN); // TODO: __mspabi_srall, __mspabi_srlll, __mspabi_sllll } @@ -361,10 +375,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, setLibcallImpl(RTLIB::SINCOS_STRET_F32, RTLIB::__sincosf_stret); setLibcallImpl(RTLIB::SINCOS_STRET_F64, RTLIB::__sincos_stret); if (TT.isWatchABI()) { - setLibcallCallingConv(RTLIB::SINCOS_STRET_F32, - CallingConv::ARM_AAPCS_VFP); - setLibcallCallingConv(RTLIB::SINCOS_STRET_F64, - CallingConv::ARM_AAPCS_VFP); + setLibcallImplCallingConv(RTLIB::__sincosf_stret, + CallingConv::ARM_AAPCS_VFP); + setLibcallImplCallingConv(RTLIB::__sincos_stret, + CallingConv::ARM_AAPCS_VFP); } } @@ -453,7 +467,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, for (const auto &LC : LibraryCalls) { setLibcallImpl(LC.Op, LC.Impl); - setLibcallCallingConv(LC.Op, LC.CC); + setLibcallImplCallingConv(LC.Impl, LC.CC); } } @@ -461,10 +475,10 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT, setARMLibcallNames(*this, TT, FloatABI, EABIVersion); else if (TT.getArch() == Triple::ArchType::avr) { // Several of the runtime library functions use a special calling conv - setLibcallCallingConv(RTLIB::SDIVREM_I8, CallingConv::AVR_BUILTIN); - setLibcallCallingConv(RTLIB::SDIVREM_I16, CallingConv::AVR_BUILTIN); - setLibcallCallingConv(RTLIB::UDIVREM_I8, CallingConv::AVR_BUILTIN); - setLibcallCallingConv(RTLIB::UDIVREM_I16, CallingConv::AVR_BUILTIN); + setLibcallImplCallingConv(RTLIB::__divmodqi4, CallingConv::AVR_BUILTIN); + setLibcallImplCallingConv(RTLIB::__divmodhi4, CallingConv::AVR_BUILTIN); + setLibcallImplCallingConv(RTLIB::__udivmodqi4, CallingConv::AVR_BUILTIN); + setLibcallImplCallingConv(RTLIB::__udivmodhi4, CallingConv::AVR_BUILTIN); } if (!TT.isWasm()) { diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 478791699df88..85f0d99923f90 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -686,7 +686,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, for (const auto &LC : LibraryCalls) { setLibcallImpl(LC.Op, LC.Impl); - setLibcallCallingConv(LC.Op, LC.CC); + setLibcallImplCallingConv(LC.Impl, LC.CC); if (LC.Cond != CmpInst::BAD_ICMP_PREDICATE) setCmpLibcallCC(LC.Op, LC.Cond); } @@ -725,7 +725,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, for (const auto &LC : MemOpsLibraryCalls) { setLibcallImpl(LC.Op, LC.Impl); - setLibcallCallingConv(LC.Op, LC.CC); + setLibcallImplCallingConv(LC.Impl, LC.CC); } } } @@ -735,13 +735,19 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, // hard-float calling convention by default. if (!TT.isWatchABI()) { if (TM.isAAPCS_ABI()) { - setLibcallCallingConv(RTLIB::FPROUND_F32_F16, CallingConv::ARM_AAPCS); - setLibcallCallingConv(RTLIB::FPROUND_F64_F16, CallingConv::ARM_AAPCS); - setLibcallCallingConv(RTLIB::FPEXT_F16_F32, CallingConv::ARM_AAPCS); + setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPROUND_F32_F16), + CallingConv::ARM_AAPCS); + setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPROUND_F64_F16), + CallingConv::ARM_AAPCS); + setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPEXT_F16_F32), + CallingConv::ARM_AAPCS); } else { - setLibcallCallingConv(RTLIB::FPROUND_F32_F16, CallingConv::ARM_APCS); - setLibcallCallingConv(RTLIB::FPROUND_F64_F16, CallingConv::ARM_APCS); - setLibcallCallingConv(RTLIB::FPEXT_F16_F32, CallingConv::ARM_APCS); + setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPROUND_F32_F16), + CallingConv::ARM_APCS); + setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPROUND_F64_F16), + CallingConv::ARM_APCS); + setLibcallImplCallingConv(getLibcallImpl(RTLIB::FPEXT_F16_F32), + CallingConv::ARM_APCS); } } @@ -763,7 +769,7 @@ ARMTargetLowering::ARMTargetLowering(const TargetMachine &TM_, for (const auto &LC : LibraryCalls) { setLibcallImpl(LC.Op, LC.Impl); - setLibcallCallingConv(LC.Op, LC.CC); + setLibcallImplCallingConv(LC.Impl, LC.CC); } } else if (!TT.isOSBinFormatMachO()) { setLibcallImpl(RTLIB::FPROUND_F32_F16, RTLIB::__gnu_f2h_ieee); diff --git a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp index 7781817aef71a..a00c2870c9afc 100644 --- a/llvm/lib/Target/Lanai/LanaiISelLowering.cpp +++ b/llvm/lib/Target/Lanai/LanaiISelLowering.cpp @@ -151,8 +151,8 @@ LanaiTargetLowering::LanaiTargetLowering(const TargetMachine &TM, setMinimumJumpTableEntries(100); // Use fast calling convention for library functions. - for (RTLIB::Libcall LC : RTLIB::libcalls()) - setLibcallCallingConv(LC, CallingConv::Fast); + for (RTLIB::LibcallImpl LC : RTLIB::libcall_impls()) + setLibcallImplCallingConv(LC, CallingConv::Fast); MaxStoresPerMemset = 16; // For @llvm.memset -> sequence of stores MaxStoresPerMemsetOptSize = 8; diff --git a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp index f8f688c8fbb14..d558dd253dc46 100644 --- a/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp +++ b/llvm/lib/Target/MSP430/MSP430ISelLowering.cpp @@ -208,7 +208,8 @@ MSP430TargetLowering::MSP430TargetLowering(const TargetMachine &TM, for (const auto &LC : LibraryCalls) { setLibcallImpl(LC.Op, LC.Impl); } - setLibcallCallingConv(RTLIB::MUL_I64, CallingConv::MSP430_BUILTIN); + setLibcallImplCallingConv(RTLIB::__mspabi_mpyll, + CallingConv::MSP430_BUILTIN); } setMinFunctionAlignment(Align(2));