aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2019-03-05 05:44:48 +0100
committerBjörn Gustavsson <[email protected]>2019-03-06 15:42:43 +0100
commitb96e5bd87c6aaaf96fa9c6e3679d95df74d1a499 (patch)
treeed075ffa80374c65fed94e1df802dfb07ae19e6b
parentdb9a338a0480067a6f05551ce62c33f3aaf1a08a (diff)
downloadotp-b96e5bd87c6aaaf96fa9c6e3679d95df74d1a499.tar.gz
otp-b96e5bd87c6aaaf96fa9c6e3679d95df74d1a499.tar.bz2
otp-b96e5bd87c6aaaf96fa9c6e3679d95df74d1a499.zip
Eliminate unused i_bs_skip_bits_all2 instruction
Starting in OTP 19 (in commit 9504c0dd71d0), the compiler emits a test_unit instruction instead of a skip instruction at the end of binary. We can do the same replacement in the loader to get rid of the i_bs_skip_bits_all2 instruction.
-rw-r--r--erts/emulator/beam/beam_load.c16
-rw-r--r--erts/emulator/beam/bs_instrs.tab10
-rw-r--r--erts/emulator/beam/ops.tab1
3 files changed, 14 insertions, 13 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 5aaba78de4..e3232f1beb 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -3565,10 +3565,22 @@ gen_skip_bits2(LoaderState* stp, GenOpArg Fail, GenOpArg Ms,
NATIVE_ENDIAN(Flags);
NEW_GENOP(stp, op);
if (Size.type == TAG_a && Size.val == am_all) {
- op->op = genop_i_bs_skip_bits_all2_3;
+ /*
+ * 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.
+ */
+ op->op = genop_bs_test_unit_3;
op->arity = 3;
op->a[0] = Fail;
- op->a[1] = Ms;
+ op->a[1] = Ms;
op->a[2] = Unit;
} else if (Size.type == TAG_i) {
op->op = genop_i_bs_skip_bits_imm2_3;
diff --git a/erts/emulator/beam/bs_instrs.tab b/erts/emulator/beam/bs_instrs.tab
index 4cf7faffb7..10f43cd786 100644
--- a/erts/emulator/beam/bs_instrs.tab
+++ b/erts/emulator/beam/bs_instrs.tab
@@ -272,16 +272,6 @@ i_bs_skip_bits2.execute(Fail, Unit) {
}
}
-i_bs_skip_bits_all2(Fail, Ms, Unit) {
- ErlBinMatchBuffer *_mb;
- _mb = ms_matchbuffer($Ms);
- if (((_mb->size - _mb->offset) % $Unit) == 0) {
- _mb->offset = _mb->size;
- } else {
- $FAIL($Fail);
- }
-}
-
i_bs_skip_bits_imm2(Fail, Ms, Bits) {
ErlBinMatchBuffer *_mb;
size_t new_offset;
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 2f00b82c1e..4e7e5f5de1 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -1192,7 +1192,6 @@ bs_skip_bits2 Fail=f Ms=xy Sz=sq Unit=u Flags=u => \
i_bs_skip_bits_imm2 f? xy W
i_bs_skip_bits2 xy xy f? t
-i_bs_skip_bits_all2 f? xy t
bs_test_tail2 Fail=f Ms=xy Bits=u==0 => bs_test_zero_tail2 Fail Ms
bs_test_tail2 Fail=f Ms=xy Bits=u => bs_test_tail_imm2 Fail Ms Bits