Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:26
erlang
1143-Always-combine-is_tuple-and-test_arity-ins...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 1143-Always-combine-is_tuple-and-test_arity-instructions.patch of Package erlang
From befdce1cd7bf227fccf8f319b4a9f68d4febab26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org> Date: Sat, 9 Sep 2023 17:57:17 +0200 Subject: [PATCH 13/25] Always combine is_tuple and test_arity instructions We used to only combine `is_tuple` and `test_arity` instructions having the same failure labels. --- erts/emulator/beam/jit/arm/instr_common.cpp | 28 +++++++++++++++++++ erts/emulator/beam/jit/arm/ops.tab | 5 ++++ erts/emulator/beam/jit/x86/instr_common.cpp | 31 +++++++++++++++++++++ erts/emulator/beam/jit/x86/ops.tab | 5 ++++ 4 files changed, 69 insertions(+) diff --git a/erts/emulator/beam/jit/arm/instr_common.cpp b/erts/emulator/beam/jit/arm/instr_common.cpp index 117c17a098..15e5d54553 100644 --- a/erts/emulator/beam/jit/arm/instr_common.cpp +++ b/erts/emulator/beam/jit/arm/instr_common.cpp @@ -1418,6 +1418,34 @@ void BeamModuleAssembler::emit_i_is_tuple_of_arity(const ArgLabel &Fail, a.b_ne(resolve_beam_label(Fail, disp1MB)); } +/* Note: This instruction leaves the untagged pointer to the tuple in + * ARG1. */ +void BeamModuleAssembler::emit_i_is_tuple_of_arity_ff(const ArgLabel &NotTuple, + const ArgLabel &BadArity, + const ArgSource &Src, + const ArgWord &Arity) { + auto src = load_source(Src, ARG1); + + emit_is_boxed(resolve_beam_label(NotTuple, dispUnknown), Src, src.reg); + + emit_untag_ptr(ARG1, src.reg); + + a.ldr(TMP1, arm::Mem(ARG1)); + + /* As an optimization for the `error | {ok, Value}` case, skip checking the + * header word when we know that the only possible boxed type is a tuple. */ + if (masked_types<BeamTypeId::MaybeBoxed>(Src) == BeamTypeId::Tuple) { + comment("skipped header test since we know it's a tuple when boxed"); + } else { + ERTS_CT_ASSERT(_TAG_HEADER_ARITYVAL == 0); + a.tst(TMP1, imm(_TAG_HEADER_MASK)); + a.b_ne(resolve_beam_label(NotTuple, disp1MB)); + } + + cmp_arg(TMP1, Arity); + a.b_ne(resolve_beam_label(BadArity, disp1MB)); +} + /* Note: This instruction leaves the untagged pointer to the tuple in * ARG1. */ void BeamModuleAssembler::emit_i_test_arity(const ArgLabel &Fail, diff --git a/erts/emulator/beam/jit/arm/ops.tab b/erts/emulator/beam/jit/arm/ops.tab index 1f2c95612e..5e75154e81 100644 --- a/erts/emulator/beam/jit/arm/ops.tab +++ b/erts/emulator/beam/jit/arm/ops.tab @@ -207,6 +207,10 @@ is_tuple Fail=f Src | test_arity Fail2 Src2 Arity | equal(Fail, Fail2) | equal(Src, Src) => i_is_tuple_of_arity Fail Src Arity | current_tuple Src +is_tuple Fail1=f Src | test_arity Fail2 Src2 Arity | + equal(Src, Src) => + i_is_tuple_of_arity_ff Fail1 Fail2 Src Arity | current_tuple Src + test_arity Fail Src Arity => i_test_arity Fail Src Arity | current_tuple Src is_tuple NotTupleFail Src | @@ -221,6 +225,7 @@ is_tagged_tuple Fail Tuple Arity Atom => is_tuple Fail=f Src => i_is_tuple Fail Src | current_tuple Src i_is_tuple_of_arity f s A +i_is_tuple_of_arity_ff f f s A i_test_arity f s A i_is_tagged_tuple f s A a diff --git a/erts/emulator/beam/jit/x86/instr_common.cpp b/erts/emulator/beam/jit/x86/instr_common.cpp index fa45b9e0cd..48b21e8bc6 100644 --- a/erts/emulator/beam/jit/x86/instr_common.cpp +++ b/erts/emulator/beam/jit/x86/instr_common.cpp @@ -1336,6 +1336,37 @@ void BeamModuleAssembler::emit_i_is_tuple_of_arity(const ArgLabel &Fail, a.jne(resolve_beam_label(Fail)); } +/* Note: This instruction leaves the pointer to the tuple in ARG2. */ +void BeamModuleAssembler::emit_i_is_tuple_of_arity_ff(const ArgLabel &NotTuple, + const ArgLabel &BadArity, + const ArgSource &Src, + const ArgWord &Arity) { + mov_arg(ARG2, Src); + + if (masked_types<BeamTypeId::MaybeBoxed>(Src) == BeamTypeId::Tuple) { + /* Fast path for the `error | {ok, Value}` case. */ + comment("simplified tuple test since the source is always a tuple " + "when boxed"); + /* We must be careful to still leave the pointer to the tuple + * in ARG2. */ + (void)emit_ptr_val(ARG2, ARG2); + emit_test_boxed(ARG2); + a.jne(resolve_beam_label(NotTuple)); + ERTS_CT_ASSERT(Support::isInt32(make_arityval(MAX_ARITYVAL))); + a.cmp(emit_boxed_val(ARG2, 0, sizeof(Uint32)), imm(Arity.get())); + a.jne(resolve_beam_label(BadArity)); + } else { + emit_is_boxed(resolve_beam_label(NotTuple), Src, ARG2); + (void)emit_ptr_val(ARG2, ARG2); + ERTS_CT_ASSERT(Support::isInt32(make_arityval(MAX_ARITYVAL))); + a.mov(RETd, emit_boxed_val(ARG2, 0, sizeof(Uint32))); + a.test(RETb, imm(_TAG_HEADER_MASK)); + a.jne(resolve_beam_label(NotTuple)); + a.cmp(RETd, imm(Arity.get())); + a.jne(resolve_beam_label(BadArity)); + } +} + /* Note: This instruction leaves the pointer to the tuple in ARG2. */ void BeamModuleAssembler::emit_i_test_arity(const ArgLabel &Fail, const ArgSource &Src, diff --git a/erts/emulator/beam/jit/x86/ops.tab b/erts/emulator/beam/jit/x86/ops.tab index c0cdcfe22d..39b9f32ef3 100644 --- a/erts/emulator/beam/jit/x86/ops.tab +++ b/erts/emulator/beam/jit/x86/ops.tab @@ -215,6 +215,10 @@ is_tuple Fail=f Src | test_arity Fail2 Src2 Arity | equal(Fail, Fail2) | equal(Src, Src2) => i_is_tuple_of_arity Fail Src Arity | current_tuple Src +is_tuple Fail1=f Src | test_arity Fail2 Src2 Arity | + equal(Src, Src) => + i_is_tuple_of_arity_ff Fail1 Fail2 Src Arity | current_tuple Src + test_arity Fail Src Arity => i_test_arity Fail Src Arity | current_tuple Src is_tuple NotTupleFail Src | @@ -229,6 +233,7 @@ is_tagged_tuple Fail Tuple Arity Atom => is_tuple Fail=f Src => i_is_tuple Fail Src | current_tuple Src i_is_tuple_of_arity f s A +i_is_tuple_of_arity_ff f f s A i_test_arity f s A i_is_tagged_tuple f s A a -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor