File 1124-Optimize-the-and-operators.patch of Package erlang

From d092687259075e384ec2c562347f8a8b1e52e9ef Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org>
Date: Sat, 2 Sep 2023 16:24:45 +0200
Subject: [PATCH 04/25] Optimize the `=:=` and `=/=` operators

---
 erts/emulator/beam/jit/arm/instr_common.cpp | 14 ++++++++++++--
 erts/emulator/beam/jit/x86/instr_common.cpp | 18 ++++++++++++++++--
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/erts/emulator/beam/jit/arm/instr_common.cpp b/erts/emulator/beam/jit/arm/instr_common.cpp
index cef3c81cf1..901a60570a 100644
--- a/erts/emulator/beam/jit/arm/instr_common.cpp
+++ b/erts/emulator/beam/jit/arm/instr_common.cpp
@@ -1463,7 +1463,12 @@ void BeamModuleAssembler::emit_is_eq_exact(const ArgLabel &Fail,
     a.cmp(x.reg, y.reg);
     a.b_eq(next);
 
-    if (always_same_types(X, Y)) {
+    if (exact_type<BeamTypeId::Integer>(X) &&
+        exact_type<BeamTypeId::Integer>(Y)) {
+        /* Fail immediately if one of the operands is a small. */
+        a.orr(TMP1, x.reg, y.reg);
+        emit_is_boxed(resolve_beam_label(Fail, dispUnknown), TMP1);
+    } else if (always_same_types(X, Y)) {
         comment("skipped tag test since they are always equal");
     } else if (Y.isLiteral()) {
         /* Fail immediately unless X is the same type of pointer as
@@ -1538,7 +1543,12 @@ void BeamModuleAssembler::emit_is_ne_exact(const ArgLabel &Fail,
     a.cmp(x.reg, y.reg);
     a.b_eq(resolve_beam_label(Fail, disp1MB));
 
-    if (always_same_types(X, Y)) {
+    if (exact_type<BeamTypeId::Integer>(X) &&
+        exact_type<BeamTypeId::Integer>(Y)) {
+        /* Succeed immediately if one of the operands is a small. */
+        a.orr(TMP1, x.reg, y.reg);
+        emit_is_boxed(next, TMP1);
+    } else if (always_same_types(X, Y)) {
         comment("skipped tag test since they are always equal");
     } else if (Y.isLiteral()) {
         /* Succeed immediately if X is not the same type of pointer as
diff --git a/erts/emulator/beam/jit/x86/instr_common.cpp b/erts/emulator/beam/jit/x86/instr_common.cpp
index 7a406d5d55..7574df29e0 100644
--- a/erts/emulator/beam/jit/x86/instr_common.cpp
+++ b/erts/emulator/beam/jit/x86/instr_common.cpp
@@ -1396,7 +1396,14 @@ void BeamModuleAssembler::emit_is_eq_exact(const ArgLabel &Fail,
     a.short_().je(next);
 #endif
 
-    if (always_same_types(X, Y)) {
+    if (exact_type<BeamTypeId::Integer>(X) &&
+        exact_type<BeamTypeId::Integer>(Y)) {
+        /* Fail immediately if one of the operands is a small. */
+        a.mov(RETd, ARG1d);
+        a.or_(RETd, ARG2d);
+        emit_test_boxed(RET);
+        a.jne(resolve_beam_label(Fail));
+    } else if (always_same_types(X, Y)) {
         comment("skipped tag test since they are always equal");
     } else if (Y.isLiteral()) {
         /* Fail immediately unless X is the same type of pointer as
@@ -1471,7 +1478,14 @@ void BeamModuleAssembler::emit_is_ne_exact(const ArgLabel &Fail,
     a.cmp(ARG1, ARG2);
     a.je(resolve_beam_label(Fail));
 
-    if (always_same_types(X, Y)) {
+    if (exact_type<BeamTypeId::Integer>(X) &&
+        exact_type<BeamTypeId::Integer>(Y)) {
+        /* Succeed immediately if one of the operands is a small. */
+        a.mov(RETd, ARG1d);
+        a.or_(RETd, ARG2d);
+        emit_test_boxed(RET);
+        a.short_().jne(next);
+    } else if (always_same_types(X, Y)) {
         comment("skipped tag test since they are always equal");
     } else if (Y.isLiteral()) {
         /* Succeed immediately if X is not the same type of pointer as
-- 
2.35.3

openSUSE Build Service is sponsored by