File 1132-Suppress-deallocate-return-instructions-after-exit-B.patch of Package erlang
From 1f21f534f63fd61a106945b31ea2db1528a5eff2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Fri, 8 Sep 2023 08:48:01 +0200
Subject: [PATCH 12/25] Suppress deallocate+return instructions after exit BIFs
---
erts/emulator/beam/jit/arm/ops.tab | 9 ++++++++
erts/emulator/beam/jit/arm/predicates.tab | 26 +++++++++++++++++++++++
erts/emulator/beam/jit/x86/ops.tab | 9 ++++++++
erts/emulator/beam/jit/x86/predicates.tab | 26 +++++++++++++++++++++++
4 files changed, 70 insertions(+)
diff --git a/erts/emulator/beam/jit/arm/ops.tab b/erts/emulator/beam/jit/arm/ops.tab
index e4b303ca23..1f2c95612e 100644
--- a/erts/emulator/beam/jit/arm/ops.tab
+++ b/erts/emulator/beam/jit/arm/ops.tab
@@ -648,6 +648,15 @@ call_ext_last u Bif=u$is_bif D | is_heavy_bif(Bif) =>
call_ext_only Ar=u Bif=u$is_bif | is_heavy_bif(Bif) =>
allocate u Ar | i_call_ext Bif | deallocate u | return
+#
+# BIFs that always raise an exception need no trailing deallocate and
+# return instructions.
+#
+call_ext_last u Bif u | is_exit_bif(Bif) =>
+ call_light_bif Bif
+call_ext_only Ar=u Bif | is_exit_bif(Bif) =>
+ allocate u Ar | call_light_bif Bif
+
#
# The general case for BIFs that have no special requirements.
#
diff --git a/erts/emulator/beam/jit/arm/predicates.tab b/erts/emulator/beam/jit/arm/predicates.tab
index 3a1fa0219b..8a3ae485ec 100644
--- a/erts/emulator/beam/jit/arm/predicates.tab
+++ b/erts/emulator/beam/jit/arm/predicates.tab
@@ -128,3 +128,29 @@ pred.is_lt_bif(Bif) {
}
return 0;
}
+
+pred.is_exit_bif(Bif) {
+ BeamFile_ImportEntry *import;
+
+ if (Bif.type != TAG_u || Bif.val >= S->beam.imports.count) {
+ return 0;
+ }
+
+ import = &S->beam.imports.entries[Bif.val];
+ if (import->module != am_erlang) {
+ return 0;
+ } else {
+ switch (import->function) {
+ case am_error:
+ return 1 <= import->arity && import->arity <= 3;
+ case am_exit:
+ return import->arity == 1;
+ case am_throw:
+ return import->arity == 1;
+ case am_nif_error:
+ return import->arity == 1 || import->arity == 2;
+ default:
+ return 0;
+ }
+ }
+}
diff --git a/erts/emulator/beam/jit/x86/ops.tab b/erts/emulator/beam/jit/x86/ops.tab
index 6879225dcd..c0cdcfe22d 100644
--- a/erts/emulator/beam/jit/x86/ops.tab
+++ b/erts/emulator/beam/jit/x86/ops.tab
@@ -617,6 +617,15 @@ call_ext_last u Bif=u$is_bif D | is_heavy_bif(Bif) =>
call_ext_only Ar=u Bif=u$is_bif | is_heavy_bif(Bif) =>
allocate u Ar | i_call_ext Bif | deallocate u | return
+#
+# BIFs that always raise an exception need no trailing deallocate and
+# return instructions.
+#
+call_ext_last u Bif u | is_exit_bif(Bif) =>
+ call_light_bif Bif
+call_ext_only Ar=u Bif | is_exit_bif(Bif) =>
+ allocate u Ar | call_light_bif Bif
+
#
# The general case for BIFs that have no special requirements.
#
diff --git a/erts/emulator/beam/jit/x86/predicates.tab b/erts/emulator/beam/jit/x86/predicates.tab
index c274aba598..58bdbc2290 100644
--- a/erts/emulator/beam/jit/x86/predicates.tab
+++ b/erts/emulator/beam/jit/x86/predicates.tab
@@ -129,3 +129,29 @@ pred.is_lt_bif(Bif) {
}
return 0;
}
+
+pred.is_exit_bif(Bif) {
+ BeamFile_ImportEntry *import;
+
+ if (Bif.type != TAG_u || Bif.val >= S->beam.imports.count) {
+ return 0;
+ }
+
+ import = &S->beam.imports.entries[Bif.val];
+ if (import->module != am_erlang) {
+ return 0;
+ } else {
+ switch (import->function) {
+ case am_error:
+ return 1 <= import->arity && import->arity <= 3;
+ case am_exit:
+ return import->arity == 1;
+ case am_throw:
+ return import->arity == 1;
+ case am_nif_error:
+ return import->arity == 1 || import->arity == 2;
+ default:
+ return 0;
+ }
+ }
+}
--
2.35.3