Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:Ledest:erlang:25
erlang
1164-Optimize-testing-for-small-operands.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 1164-Optimize-testing-for-small-operands.patch of Package erlang
From 512fc927093064e8a75c0a818b11d4ba06f8753d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= <bjorn@erlang.org> Date: Thu, 8 Sep 2022 05:53:39 +0200 Subject: [PATCH 4/7] Optimize testing for small operands --- erts/emulator/beam/jit/x86/instr_arith.cpp | 52 ++++++++++++++-------- 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/erts/emulator/beam/jit/x86/instr_arith.cpp b/erts/emulator/beam/jit/x86/instr_arith.cpp index fc29ff844f..bc8c8ea3bb 100644 --- a/erts/emulator/beam/jit/x86/instr_arith.cpp +++ b/erts/emulator/beam/jit/x86/instr_arith.cpp @@ -31,6 +31,9 @@ extern "C" #include "erl_bif_table.h" } +/* + * Clobbers ARG1. + */ void BeamModuleAssembler::emit_is_small(Label fail, const ArgSource &Arg, x86::Gp Reg) { @@ -40,7 +43,7 @@ void BeamModuleAssembler::emit_is_small(Label fail, comment("skipped test for small operand since it is always small"); } else if (always_one_of(Arg, BEAM_TYPE_FLOAT | BEAM_TYPE_INTEGER)) { comment("simplified test for small operand since it is a number"); - a.test(Reg.r32(), imm(TAG_PRIMARY_LIST)); + a.test(Reg.r8(), imm(TAG_PRIMARY_LIST)); a.short_().je(fail); } else { comment("is the operand small?"); @@ -51,6 +54,9 @@ void BeamModuleAssembler::emit_is_small(Label fail, } } +/* + * Clobbers RET, ARG1. + */ void BeamModuleAssembler::emit_are_both_small(Label fail, const ArgSource &LHS, x86::Gp A, @@ -63,9 +69,9 @@ void BeamModuleAssembler::emit_are_both_small(Label fail, always_one_of(RHS, BEAM_TYPE_FLOAT | BEAM_TYPE_INTEGER)) { comment("simplified test for small operands since both are numbers"); if (always_small(RHS)) { - a.test(A.r32(), imm(TAG_PRIMARY_LIST)); + a.test(A.r8(), imm(TAG_PRIMARY_LIST)); } else if (always_small(LHS)) { - a.test(B.r32(), imm(TAG_PRIMARY_LIST)); + a.test(B.r8(), imm(TAG_PRIMARY_LIST)); } else if (A != RET && B != RET) { a.mov(RETd, A.r32()); a.and_(RETd, B.r32()); @@ -73,9 +79,29 @@ void BeamModuleAssembler::emit_are_both_small(Label fail, } else { a.mov(ARG1d, A.r32()); a.and_(ARG1d, B.r32()); - a.test(ARG1d, imm(TAG_PRIMARY_LIST)); + a.test(ARG1.r8(), imm(TAG_PRIMARY_LIST)); } a.short_().je(fail); + } else if (always_small(LHS)) { + if (A == RET || B == RET) { + emit_is_small(fail, RHS, B); + } else { + comment("is the operand small?"); + a.mov(RETd, B.r32()); + a.and_(RETb, imm(_TAG_IMMED1_MASK)); + a.cmp(RETb, imm(_TAG_IMMED1_SMALL)); + a.short_().jne(fail); + } + } else if (always_small(RHS)) { + if (A == RET || B == RET) { + emit_is_small(fail, LHS, A); + } else { + comment("is the operand small?"); + a.mov(RETd, A.r32()); + a.and_(RETb, imm(_TAG_IMMED1_MASK)); + a.cmp(RETb, imm(_TAG_IMMED1_SMALL)); + a.short_().jne(fail); + } } else { comment("are both operands small?"); if (A != RET && B != RET) { @@ -1064,11 +1090,7 @@ void BeamModuleAssembler::emit_i_band(const ArgSource &LHS, Label generic = a.newLabel(), next = a.newLabel(); - if (always_small(RHS)) { - emit_is_small(generic, LHS, ARG2); - } else { - emit_are_both_small(generic, LHS, ARG2, RHS, RET); - } + emit_are_both_small(generic, LHS, ARG2, RHS, RET); /* TAG & TAG = TAG, so we don't need to tag it again. */ a.and_(RET, ARG2); @@ -1119,11 +1141,7 @@ void BeamModuleAssembler::emit_i_bor(const ArgLabel &Fail, Label generic = a.newLabel(), next = a.newLabel(); - if (always_small(RHS)) { - emit_is_small(generic, LHS, ARG2); - } else { - emit_are_both_small(generic, LHS, ARG2, RHS, RET); - } + emit_are_both_small(generic, LHS, ARG2, RHS, RET); /* TAG | TAG = TAG, so we don't need to tag it again. */ a.or_(RET, ARG2); @@ -1176,11 +1194,7 @@ void BeamModuleAssembler::emit_i_bxor(const ArgLabel &Fail, Label generic = a.newLabel(), next = a.newLabel(); - if (always_small(RHS)) { - emit_is_small(generic, LHS, ARG2); - } else { - emit_are_both_small(generic, LHS, ARG2, RHS, RET); - } + emit_are_both_small(generic, LHS, ARG2, RHS, RET); /* TAG ^ TAG = 0, so we need to tag it again. */ a.xor_(RET, ARG2); -- 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