Skip to content

Commit

Permalink
Remove special handling of bs_skip_bits2 for literal sizes
Browse files Browse the repository at this point in the history
Starting from Erlang/OTP 26, the `bs_skip_bits2` instruction will
almost never have a literal size in optimized (skip instructions with
literal sizes will usually be part of a `bs_match`
instruction). Therefore, there is no longer any point in handling
literal sizes specially.

Note that there was special handling of operands of `bs_skip_bits2`
last emitted by Erlang/OTP 18. This is no longer necessary because the
loader will refuse to load any module compiled by Erlang/OTP 22 or
earlier.
  • Loading branch information
bjorng committed Jun 28, 2024
1 parent 9b04956 commit 6f872f0
Show file tree
Hide file tree
Showing 7 changed files with 27 additions and 101 deletions.
11 changes: 0 additions & 11 deletions erts/emulator/beam/emu/bs_instrs.tab
Original file line number Diff line number Diff line change
Expand Up @@ -280,17 +280,6 @@ i_bs_skip_bits2.execute(Fail, Unit) {
}
}

i_bs_skip_bits_imm2(Fail, Ms, Bits) {
ErlSubBits *sb = (ErlSubBits*)bitstring_val($Ms);
size_t new_offset;
new_offset = sb->start + ($Bits);
if (new_offset <= sb->end) {
sb->start = new_offset;
} else {
$FAIL($Fail);
}
}

bs_init_writable() {
HEAVY_SWAPOUT;
x(0) = erts_bs_init_writable(c_p, x(0));
Expand Down
12 changes: 9 additions & 3 deletions erts/emulator/beam/emu/ops.tab
Original file line number Diff line number Diff line change
Expand Up @@ -1189,10 +1189,16 @@ i_bs_get_float2 xy f? t s t d

# Miscellaneous

bs_skip_bits2 Fail=f Ms=xy Sz=sq Unit=u Flags=u =>
skip_bits2(Fail, Ms, Sz, Unit, Flags)
bs_skip_bits2 Fail=f Ms=xy Sz=xy Unit=u Flags=u =>
i_bs_skip_bits2 Ms Sz Fail Unit

# Starting with Erlang/OTP 26, bs_skip_bits2 with an immediate size is
# almost never found in optimized code. Therefore, there is no need to
# to implement it efficiently.

bs_skip_bits2 Fail=f Ms=xy Sz Unit=u Flags=u =>
move Sz x | bs_skip_bits2 Fail Ms x Unit Flags

i_bs_skip_bits_imm2 f? xy W
i_bs_skip_bits2 xy xy f? t

bs_test_tail2 Fail=f Ms=xy o => jump Fail
Expand Down
66 changes: 0 additions & 66 deletions erts/emulator/beam/generators.tab
Original file line number Diff line number Diff line change
Expand Up @@ -81,72 +81,6 @@ gen.get_utf16(Fail, Ms, Flags, Dst) {
return op;
}

// Generate the fastest instruction for bs_skip_bits.
gen.skip_bits2(Fail, Ms, Size, Unit, Flags) {
BeamOp* op;
$NewBeamOp(S, op);

$NativeEndian(Flags);
if (Size.type == TAG_a && Size.val == am_all) {
/*
* This kind of skip instruction will only be found in modules
* compiled before OTP 19. From OTP 19, the compiler generates
* a test_unit instruction of a bs_skip at the end of a
* binary.
*
* It is safe to replace the skip instruction with a test_unit
* instruction, because the position will never be used again.
* If the match context itself is used again, it will be used by
* a bs_restore2 instruction which will overwrite the position
* by one of the stored positions.
*/
$BeamOpNameArity(op, bs_test_unit, 3);
op->a[0] = Fail;
op->a[1] = Ms;
op->a[2] = Unit;
} else if (Size.type == TAG_i) {
$BeamOpNameArity(op, i_bs_skip_bits_imm2, 3);
op->a[0] = Fail;
op->a[1] = Ms;
op->a[2].type = TAG_u;
if (!beam_load_safe_mul(Size.val, Unit.val, &op->a[2].val)) {
goto error;
}
} else if (Size.type == TAG_q) {
Eterm big = beamfile_get_literal(&S->beam, Size.val);
Uint bigval;

if (!term_to_Uint(big, &bigval)) {
error:
$BeamOpNameArity(op, jump, 1);
op->a[0] = Fail;
} else {
$BeamOpNameArity(op, i_bs_skip_bits_imm2, 3);
op->a[0] = Fail;
op->a[1] = Ms;
op->a[2].type = TAG_u;
if (!beam_load_safe_mul(bigval, Unit.val, &op->a[2].val)) {
goto error;
}
}
} else if (Size.type == TAG_x || Size.type == TAG_y) {
$BeamOpNameArity(op, i_bs_skip_bits2, 4);
op->a[0] = Ms;
op->a[1] = Size;
op->a[2] = Fail;
op->a[3] = Unit;
} else {
/*
* Invalid literal size. Can only happen if compiler
* optimizations are selectively disabled. For example,
* at the time of writing, [no_copt, no_type_opt] will allow
* skip instructions with invalid sizes to slip through.
*/
goto error;
}
return op;
}

// Creates an instruction that moves a literal lambda to a register.
MakeLiteralFun(Op, Index, Arity, Dst) {
SWord literal;
Expand Down
7 changes: 0 additions & 7 deletions erts/emulator/beam/jit/arm/instr_bs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -510,13 +510,6 @@ void BeamModuleAssembler::emit_i_bs_skip_bits2(const ArgRegister &Ctx,
}
}

void BeamModuleAssembler::emit_i_bs_skip_bits_imm2(const ArgLabel &Fail,
const ArgRegister &Ctx,
const ArgWord &Bits) {
mov_arg(ARG1, Bits);
emit_bs_skip_bits(Fail, Ctx);
}

void BeamModuleAssembler::emit_i_bs_get_binary2(const ArgRegister &Ctx,
const ArgLabel &Fail,
const ArgWord &Live,
Expand Down
12 changes: 9 additions & 3 deletions erts/emulator/beam/jit/arm/ops.tab
Original file line number Diff line number Diff line change
Expand Up @@ -989,10 +989,16 @@ i_bs_get_float2 S f t s t d

# Miscellaneous

bs_skip_bits2 Fail=f Ms=xy Sz=sq Unit=u Flags=u =>
skip_bits2(Fail, Ms, Sz, Unit, Flags)
bs_skip_bits2 Fail=f Ms=xy Sz=xy Unit=u Flags=u =>
i_bs_skip_bits2 Ms Sz Fail Unit

# Starting with Erlang/OTP 26, bs_skip_bits2 with an immediate size is
# almost never found in optimized code. Therefore, there is no need to
# to implement it efficiently.

bs_skip_bits2 Fail=f Ms=xy Sz Unit=u Flags=u =>
move Sz x | bs_skip_bits2 Fail Ms x Unit Flags

i_bs_skip_bits_imm2 f S W
i_bs_skip_bits2 S S f t

bs_test_tail2 Fail=f Ms=xy o => jump Fail
Expand Down
8 changes: 0 additions & 8 deletions erts/emulator/beam/jit/x86/instr_bs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -481,14 +481,6 @@ void BeamModuleAssembler::emit_i_bs_skip_bits2(const ArgRegister &Ctx,
}
}

void BeamModuleAssembler::emit_i_bs_skip_bits_imm2(const ArgLabel &Fail,
const ArgRegister &Ctx,
const ArgWord &Bits) {
mov_arg(RET, Bits);

emit_bs_skip_bits(Fail, Ctx);
}

void BeamModuleAssembler::emit_i_bs_get_binary2(const ArgRegister &Ctx,
const ArgLabel &Fail,
const ArgWord &Live,
Expand Down
12 changes: 9 additions & 3 deletions erts/emulator/beam/jit/x86/ops.tab
Original file line number Diff line number Diff line change
Expand Up @@ -911,10 +911,16 @@ i_bs_get_float2 S f t s t d

# Miscellaneous

bs_skip_bits2 Fail=f Ms=xy Sz=sq Unit=u Flags=u =>
skip_bits2(Fail, Ms, Sz, Unit, Flags)
bs_skip_bits2 Fail=f Ms=xy Sz=xy Unit=u Flags=u =>
i_bs_skip_bits2 Ms Sz Fail Unit

# Starting with Erlang/OTP 26, bs_skip_bits2 with an immediate size is
# almost never found in optimized code. Therefore, there is no need to
# to implement it efficiently.

bs_skip_bits2 Fail=f Ms=xy Sz Unit=u Flags=u =>
move Sz x | bs_skip_bits2 Fail Ms x Unit Flags

i_bs_skip_bits_imm2 f S W
i_bs_skip_bits2 S S f t

bs_test_tail2 Fail=f Ms=xy o => jump Fail
Expand Down

0 comments on commit 6f872f0

Please sign in to comment.