Skip to content

RuntimeLibcalls: Associate calling convention with libcall impls #144979

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: users/arsenm/tablegen/define-runtime-libcall-sets-tablegen
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions llvm/include/llvm/CodeGen/TargetLowering.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
}
Expand Down
32 changes: 23 additions & 9 deletions llvm/include/llvm/IR/RuntimeLibcalls.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,21 @@ template <> struct enum_iteration_traits<RTLIB::Libcall> {
static constexpr bool is_iterable = true;
};

template <> struct enum_iteration_traits<RTLIB::LibcallImpl> {
static constexpr bool is_iterable = true;
};

namespace RTLIB {

// Return an iterator over all Libcall values.
static inline auto libcalls() {
return enum_seq(static_cast<RTLIB::Libcall>(0), RTLIB::UNKNOWN_LIBCALL);
}

static inline auto libcall_impls() {
return enum_seq(static_cast<RTLIB::LibcallImpl>(1), RTLIB::NumLibcallImpls);
}

/// A simple container for information about the supported runtime calls.
struct RuntimeLibcallsInfo {
explicit RuntimeLibcallsInfo(
Expand Down Expand Up @@ -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<RTLIB::LibcallImpl> getLibcallImpls() const {
Expand Down Expand Up @@ -130,8 +143,9 @@ struct RuntimeLibcallsInfo {
static_assert(static_cast<int>(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.
Expand Down
70 changes: 42 additions & 28 deletions llvm/lib/IR/RuntimeLibcalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 {
Expand All @@ -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);
}
}
}
Expand All @@ -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);
}
}

Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -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);
}
}

Expand Down Expand Up @@ -453,18 +467,18 @@ 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);
}
}

if (TT.isARM() || TT.isThumb())
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()) {
Expand Down
24 changes: 15 additions & 9 deletions llvm/lib/Target/ARM/ARMISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}
}
}
Expand All @@ -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);
}
}

Expand All @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions llvm/lib/Target/Lanai/LanaiISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion llvm/lib/Target/MSP430/MSP430ISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down
Loading