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

openSUSE Build Service is sponsored by