-
Notifications
You must be signed in to change notification settings - Fork 14.7k
RuntimeLibcalls: Move exception call config to tablegen #151948
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
base: main
Are you sure you want to change the base?
RuntimeLibcalls: Move exception call config to tablegen #151948
Conversation
Also starts pruning out these calls if the exception model is forced to none. I worked backwards from the logic in addPassesToHandleExceptions and the pass content. There appears to be some tolerance for mixing and matching exception modes inside of a single module. As far as I can tell _Unwind_CallPersonality is only relevant for wasm, so just add it there. As usual, the arm64ec case makes things difficult and is missing test coverage. The set of calls in list form is necessary to use foreach for the duplication, but in every other context a dag is more convenient. You cannot use foreach over a dag, and I haven't found a way to flatten a dag into a list. This removes the last manual setLibcallImpl call in generic code.
@llvm/pr-subscribers-llvm-ir @llvm/pr-subscribers-tablegen Author: Matt Arsenault (arsenm) ChangesAlso starts pruning out these calls if the exception model is I worked backwards from the logic in addPassesToHandleExceptions As usual, the arm64ec case makes things difficult and is This removes the last manual setLibcallImpl call in generic code. Full diff: https://github.com/llvm/llvm-project/pull/151948.diff 6 Files Affected:
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.h b/llvm/include/llvm/IR/RuntimeLibcalls.h
index f39e2e3c26900..6fb9b480c57a1 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.h
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.h
@@ -196,6 +196,7 @@ struct RuntimeLibcallsInfo {
/// Generated by tablegen.
void setTargetRuntimeLibcallSets(const Triple &TT,
+ ExceptionHandling ExceptionModel,
FloatABI::ABIType FloatABI);
/// Set default libcall names. If a target wants to opt-out of a libcall it
diff --git a/llvm/include/llvm/IR/RuntimeLibcalls.td b/llvm/include/llvm/IR/RuntimeLibcalls.td
index 384b7f29b9073..a173e41af8e49 100644
--- a/llvm/include/llvm/IR/RuntimeLibcalls.td
+++ b/llvm/include/llvm/IR/RuntimeLibcalls.td
@@ -38,6 +38,14 @@ def hasSinCos : RuntimeLibcallPredicate<"hasSinCos(TT)">;
// FIXME: Way to combine predicates
def hasSinCos_f32_f64 : RuntimeLibcallPredicate<"hasSinCos_f32_f64(TT)">;
+def ExceptionModelIsNotNone : RuntimeLibcallPredicate<
+ [{ExceptionModel != ExceptionHandling::None}]
+>;
+
+def ExceptionModelIsSjLj : RuntimeLibcallPredicate<
+ [{ExceptionModel == ExceptionHandling::SjLj}]
+>;
+
//--------------------------------------------------------------------
// Declare all kinds of used libcalls
//--------------------------------------------------------------------
@@ -692,10 +700,6 @@ foreach MemSize = [ 1, 2, 4, 8, 16 ] in {
!cast<RuntimeLibcall>("MEMSET_ELEMENT_UNORDERED_ATOMIC_"#MemSize)>;
}
-// Exception handling
-def _Unwind_Resume : RuntimeLibcallImpl<UNWIND_RESUME>;
-def __cxa_end_cleanup : RuntimeLibcallImpl<CXA_END_CLEANUP>;
-
// Atomic '__sync_*' libcalls.
foreach lc = LibCalls__sync in {
def __#!tolower(!cast<string>(lc)) : RuntimeLibcallImpl<lc>;
@@ -999,9 +1003,20 @@ defm sincos : LibmLongDoubleLibCall;
def bzero : RuntimeLibcallImpl<BZERO>;
def __bzero : RuntimeLibcallImpl<BZERO>;
-def _Unwind_SjLj_Resume : RuntimeLibcallImpl<UNWIND_RESUME>;
-def _Unwind_SjLj_Register : RuntimeLibcallImpl<UNWIND_REGISTER>;
-def _Unwind_SjLj_Unregister : RuntimeLibcallImpl<UNWIND_UNREGISTER>;
+
+// Exception handling
+defset list<RuntimeLibcallImpl> DefaultExceptionHandlingLibcalls = {
+ def _Unwind_Resume : RuntimeLibcallImpl<UNWIND_RESUME>;
+ def __cxa_end_cleanup : RuntimeLibcallImpl<CXA_END_CLEANUP>;
+}
+
+defset list<RuntimeLibcallImpl> SjLjExceptionHandlingLibcalls = {
+ def _Unwind_SjLj_Resume : RuntimeLibcallImpl<UNWIND_RESUME>;
+ def _Unwind_SjLj_Register : RuntimeLibcallImpl<UNWIND_REGISTER>;
+ def _Unwind_SjLj_Unregister : RuntimeLibcallImpl<UNWIND_UNREGISTER>;
+}
+
+// Only used on wasm?
def _Unwind_CallPersonality : RuntimeLibcallImpl<UNWIND_CALL_PERSONALITY>;
// Used on OpenBSD
@@ -1073,6 +1088,13 @@ defset list<RuntimeLibcallImpl> LibmF128FiniteLibcalls = {
// Common Libcall Sets
//===----------------------------------------------------------------------===//
+defvar ExceptionModelCalls = (add
+ LibcallImpls<(add DefaultExceptionHandlingLibcalls),
+ ExceptionModelIsNotNone>,
+ LibcallImpls<(add SjLjExceptionHandlingLibcalls),
+ ExceptionModelIsSjLj>
+);
+
// FIXME: Should move to explicit opt-in to different sets of libcalls
// instead of trying to remove from a default set. We have
// unreasonable defaults like reporting f80 calls on most targets when
@@ -1093,19 +1115,25 @@ defvar DefaultRuntimeLibcallImpls_f128 =
!filter(entry, AllDefaultRuntimeLibcallImpls,
!match(!cast<string>(entry.Provides), "_F128"));
-defvar DefaultRuntimeLibcallImpls =
+// FIXME: Ideally we would just use dags everywhere, but for the
+// arm64ec case we need iterable lists so we can add the # prefix
+defvar DefaultRuntimeLibcallImplsList =
!listremove(
!listremove(
!listremove(AllDefaultRuntimeLibcallImpls, Int128RTLibcalls),
DefaultRuntimeLibcallImpls_f80),
DefaultRuntimeLibcallImpls_ppcf128);
+defvar DefaultRuntimeLibcallImpls = (add DefaultRuntimeLibcallImplsList, ExceptionModelCalls);
+
/// Default set of libcall impls for 32-bit architectures.
-defvar DefaultLibcallImpls32 = DefaultRuntimeLibcallImpls;
+defvar DefaultLibcallImpls32List = DefaultRuntimeLibcallImplsList;
+defvar DefaultLibcallImpls32 = (add DefaultRuntimeLibcallImpls);
/// Default set of libcall impls for 64-bit architectures.
-defvar DefaultLibcallImpls64 = !listconcat(DefaultRuntimeLibcallImpls,
- Int128RTLibcalls);
+defvar DefaultLibcallImpls64List = !listconcat(DefaultRuntimeLibcallImplsList,
+ Int128RTLibcalls);
+defvar DefaultLibcallImpls64 = (add DefaultLibcallImpls32List);
defvar DarwinSinCosStret = LibcallImpls<(add __sincosf_stret, __sincos_stret),
darwinHasSinCosStret>;
@@ -1138,8 +1166,12 @@ defvar WindowsExclusions = !listconcat(WindowsMathRemovals, MostPowI);
// Targets which support windows should start with these as a base and
// add in calls for other OSes
-defvar Win32DefaultLibcallImpls = !listremove(DefaultLibcallImpls32, WindowsExclusions);
-defvar Win64DefaultLibcallImpls = !listremove(DefaultLibcallImpls64, WindowsExclusions);
+defvar Win32DefaultLibcallImpls = (sub DefaultLibcallImpls32, WindowsExclusions);
+defvar Win64DefaultLibcallImpls = (sub DefaultLibcallImpls64, WindowsExclusions);
+
+// We need a list (not-dag) to use foreach to define all the prefixed
+// versions, and there isn't an easy way to flatten a dag into a list.
+defvar Win64DefaultLibcallImplsList = !listremove(DefaultLibcallImpls64List, WindowsExclusions);
defvar LibmHasFrexpF32 = LibcallImpls<(add frexpf), isNotOSWindowsOrIsCygwinMinGW>;
defvar LibmHasLdexpF32 = LibcallImpls<(add ldexpf), isNotOSWindowsOrIsCygwinMinGW>;
@@ -1233,12 +1265,13 @@ def AArch64SystemLibrary : SystemRuntimeLibrary<
DarwinExp10, DarwinSinCosStret,
LibmHasSinCosF32, LibmHasSinCosF64, LibmHasSinCosF128,
DefaultLibmExp10,
- DefaultStackProtector)
+ DefaultStackProtector,
+ ExceptionModelCalls)
>;
// Prepend a # to every name
defset list<RuntimeLibcallImpl> WinArm64ECDefaultRuntimeLibcallImpls = {
- foreach libcall = Win64DefaultLibcallImpls in {
+ foreach libcall = Win64DefaultLibcallImplsList in {
def arm64ec_#libcall : DuplicateLibcallImplWithPrefix<libcall, "#">;
}
@@ -1247,9 +1280,29 @@ defset list<RuntimeLibcallImpl> WinArm64ECDefaultRuntimeLibcallImpls = {
}
}
+defset list<RuntimeLibcallImpl> WinArm64ECDefaultExceptionHandlingLibcalls = {
+ foreach libcall = DefaultExceptionHandlingLibcalls in {
+ def arm64ec_#libcall : DuplicateLibcallImplWithPrefix<libcall, "#">;
+ }
+}
+
+defset list<RuntimeLibcallImpl> WinArm64ECSjLjExceptionHandlingLibcalls = {
+ foreach libcall = SjLjExceptionHandlingLibcalls in {
+ def arm64ec_#libcall : DuplicateLibcallImplWithPrefix<libcall, "#">;
+ }
+}
+
+defvar ExceptionModelCallsArm64EC = (add
+ LibcallImpls<(add WinArm64ECDefaultExceptionHandlingLibcalls),
+ ExceptionModelIsNotNone>,
+ LibcallImpls<(add WinArm64ECSjLjExceptionHandlingLibcalls),
+ ExceptionModelIsSjLj>
+);
+
def WindowsARM64ECSystemLibrary
: SystemRuntimeLibrary<isWindowsArm64EC,
- (add WinArm64ECDefaultRuntimeLibcallImpls)>;
+ (add WinArm64ECDefaultRuntimeLibcallImpls,
+ ExceptionModelCallsArm64EC)>;
//===----------------------------------------------------------------------===//
// AMDGPU Runtime Libcalls
@@ -2163,7 +2216,8 @@ defvar X86CommonLibcalls =
// FIXME: MSVCRT doesn't have powi. The f128 case is added as a
// hack for one test relying on it.
__powitf2_f128,
- DefaultStackProtector
+ DefaultStackProtector,
+ ExceptionModelCalls
);
defvar Windows32DivRemMulCalls =
@@ -2308,6 +2362,7 @@ def WasmSystemLibrary
(add DefaultRuntimeLibcallImpls, Int128RTLibcalls,
CompilerRTOnlyInt64Libcalls, CompilerRTOnlyInt128Libcalls,
exp10f, exp10,
+ _Unwind_CallPersonality,
emscripten_return_address,
__stack_chk_fail)>;
diff --git a/llvm/lib/IR/RuntimeLibcalls.cpp b/llvm/lib/IR/RuntimeLibcalls.cpp
index b6e2cac5f7b04..60bf6428d5e56 100644
--- a/llvm/lib/IR/RuntimeLibcalls.cpp
+++ b/llvm/lib/IR/RuntimeLibcalls.cpp
@@ -71,10 +71,7 @@ void RuntimeLibcallsInfo::initLibcalls(const Triple &TT,
ExceptionHandling ExceptionModel,
FloatABI::ABIType FloatABI,
EABI EABIVersion, StringRef ABIName) {
- setTargetRuntimeLibcallSets(TT, FloatABI);
-
- if (ExceptionModel == ExceptionHandling::SjLj)
- setLibcallImpl(RTLIB::UNWIND_RESUME, RTLIB::_Unwind_SjLj_Resume);
+ setTargetRuntimeLibcallSets(TT, ExceptionModel, FloatABI);
if (TT.isARM() || TT.isThumb()) {
setARMLibcallNames(*this, TT, FloatABI, EABIVersion);
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td
index 49d5ecaa0e5c5..2a9beaca7947c 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter-calling-conv.td
@@ -41,7 +41,7 @@ def MSP430LibraryWithCondCC : SystemRuntimeLibrary<isMSP430,
>;
-// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(const llvm::Triple &TT, FloatABI::ABIType FloatABI) {
+// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI) {
// CHECK: if (TT.getArch() == Triple::avr && TT.isOSHurd()) {
// CHECK-NEXT: const CallingConv::ID DefaultCC = isFoo() ? CallingConv::Fast : CallingConv::GHC;
// CHECK-NEXT: for (CallingConv::ID &Entry : LibcallImplCallingConvs) {
diff --git a/llvm/test/TableGen/RuntimeLibcallEmitter.td b/llvm/test/TableGen/RuntimeLibcallEmitter.td
index 642f8b85a89c6..45cae1cbbcb32 100644
--- a/llvm/test/TableGen/RuntimeLibcallEmitter.td
+++ b/llvm/test/TableGen/RuntimeLibcallEmitter.td
@@ -150,7 +150,7 @@ def BlahLibrary : SystemRuntimeLibrary<isBlahArch, (add calloc, LibraryWithCondi
// CHECK-NEXT: };
-// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(const llvm::Triple &TT, FloatABI::ABIType FloatABI) {
+// CHECK: void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets(const llvm::Triple &TT, ExceptionHandling ExceptionModel, FloatABI::ABIType FloatABI) {
// CHECK-NEXT: struct LibcallImplPair {
// CHECK-NEXT: RTLIB::Libcall Func;
// CHECK-NEXT: RTLIB::LibcallImpl Impl;
diff --git a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
index 412431b96d030..720b3df851b4f 100644
--- a/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/RuntimeLibcallsEmitter.cpp
@@ -356,7 +356,8 @@ const uint16_t RTLIB::RuntimeLibcallsInfo::RuntimeLibcallNameOffsetTable[] = {
void RuntimeLibcallEmitter::emitSystemRuntimeLibrarySetCalls(
raw_ostream &OS) const {
OS << "void llvm::RTLIB::RuntimeLibcallsInfo::setTargetRuntimeLibcallSets("
- "const llvm::Triple &TT, FloatABI::ABIType FloatABI) {\n"
+ "const llvm::Triple &TT, ExceptionHandling ExceptionModel, "
+ "FloatABI::ABIType FloatABI) {\n"
" struct LibcallImplPair {\n"
" RTLIB::Libcall Func;\n"
" RTLIB::LibcallImpl Impl;\n"
|
Allows subclasses to directly initialize the underlying storage. This will enable tablegen to emit a smaller initializer list to initialize constant bitsets. For runtime libcalls we need to initialize many hundreds of bits in many different sets so this shrinks the generated output to a more manageable size. Extracted from #151948
Allows subclasses to directly initialize the underlying storage. This will enable tablegen to emit a smaller initializer list to initialize constant bitsets. For runtime libcalls we need to initialize many hundreds of bits in many different sets so this shrinks the generated output to a more manageable size. Extracted from #151948
Also starts pruning out these calls if the exception model is
forced to none.
I worked backwards from the logic in addPassesToHandleExceptions
and the pass content. There appears to be some tolerance
for mixing and matching exception modes inside of a single module.
As far as I can tell _Unwind_CallPersonality is only relevant for
wasm, so just add it there.
As usual, the arm64ec case makes things difficult and is
missing test coverage. The set of calls in list form is necessary
to use foreach for the duplication, but in every other context a
dag is more convenient. You cannot use foreach over a dag, and I
haven't found a way to flatten a dag into a list.
This removes the last manual setLibcallImpl call in generic code.