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