diff options
author | Damien George <damien.p.george@gmail.com> | 2014-10-25 16:43:46 +0100 |
---|---|---|
committer | Damien George <damien.p.george@gmail.com> | 2014-10-25 20:23:13 +0100 |
commit | 8456cc017bc2e4a9fe063f485c3f2aa410435015 (patch) | |
tree | e0c8055f6de2c7975b6b7b31e80beb622ce9b3ad /py/emitbc.c | |
parent | 1084b0f9c21b093618da4494508dec9ca8467e35 (diff) | |
download | micropython-8456cc017bc2e4a9fe063f485c3f2aa410435015.tar.gz micropython-8456cc017bc2e4a9fe063f485c3f2aa410435015.zip |
py: Compress load-int, load-fast, store-fast, unop, binop bytecodes.
There is a lot potential in compress bytecodes and make more use of the
coding space. This patch introduces "multi" bytecodes which have their
argument included in the bytecode (by addition).
UNARY_OP and BINARY_OP now no longer take a 1 byte argument for the
opcode. Rather, the opcode is included in the first byte itself.
LOAD_FAST_[0,1,2] and STORE_FAST_[0,1,2] are removed in favour of their
multi versions, which can take an argument between 0 and 15 inclusive.
The majority of LOAD_FAST/STORE_FAST codes fit in this range and so this
saves a byte for each of these.
LOAD_CONST_SMALL_INT_MULTI is used to load small ints between -16 and 47
inclusive. Such ints are quite common and now only need 1 byte to
store, and now have much faster decoding.
In all this patch saves about 2% RAM for typically bytecode (1.8% on
64-bit test, 2.5% on pyboard test). It also reduces the binary size
(because bytecodes are simplified) and doesn't harm performance.
Diffstat (limited to 'py/emitbc.c')
-rw-r--r-- | py/emitbc.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/py/emitbc.c b/py/emitbc.c index cee6d3396c..795c412830 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -469,7 +469,11 @@ STATIC void emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) { STATIC void emit_bc_load_const_small_int(emit_t *emit, mp_int_t arg) { emit_bc_pre(emit, 1); - emit_write_bytecode_byte_int(emit, MP_BC_LOAD_CONST_SMALL_INT, arg); + if (-16 <= arg && arg <= 47) { + emit_write_bytecode_byte(emit, MP_BC_LOAD_CONST_SMALL_INT_MULTI + 16 + arg); + } else { + emit_write_bytecode_byte_int(emit, MP_BC_LOAD_CONST_SMALL_INT, arg); + } } STATIC void emit_bc_load_const_int(emit_t *emit, qstr qst) { @@ -499,11 +503,10 @@ STATIC void emit_bc_load_null(emit_t *emit) { STATIC void emit_bc_load_fast(emit_t *emit, qstr qst, mp_uint_t id_flags, mp_uint_t local_num) { assert(local_num >= 0); emit_bc_pre(emit, 1); - switch (local_num) { - case 0: emit_write_bytecode_byte(emit, MP_BC_LOAD_FAST_0); break; - case 1: emit_write_bytecode_byte(emit, MP_BC_LOAD_FAST_1); break; - case 2: emit_write_bytecode_byte(emit, MP_BC_LOAD_FAST_2); break; - default: emit_write_bytecode_byte_uint(emit, MP_BC_LOAD_FAST_N, local_num); break; + if (local_num <= 15) { + emit_write_bytecode_byte(emit, MP_BC_LOAD_FAST_MULTI + local_num); + } else { + emit_write_bytecode_byte_uint(emit, MP_BC_LOAD_FAST_N, local_num); } } @@ -545,11 +548,10 @@ STATIC void emit_bc_load_subscr(emit_t *emit) { STATIC void emit_bc_store_fast(emit_t *emit, qstr qst, mp_uint_t local_num) { assert(local_num >= 0); emit_bc_pre(emit, -1); - switch (local_num) { - case 0: emit_write_bytecode_byte(emit, MP_BC_STORE_FAST_0); break; - case 1: emit_write_bytecode_byte(emit, MP_BC_STORE_FAST_1); break; - case 2: emit_write_bytecode_byte(emit, MP_BC_STORE_FAST_2); break; - default: emit_write_bytecode_byte_uint(emit, MP_BC_STORE_FAST_N, local_num); break; + if (local_num <= 15) { + emit_write_bytecode_byte(emit, MP_BC_STORE_FAST_MULTI + local_num); + } else { + emit_write_bytecode_byte_uint(emit, MP_BC_STORE_FAST_N, local_num); } } @@ -724,12 +726,12 @@ STATIC void emit_bc_pop_except(emit_t *emit) { STATIC void emit_bc_unary_op(emit_t *emit, mp_unary_op_t op) { if (op == MP_UNARY_OP_NOT) { emit_bc_pre(emit, 0); - emit_write_bytecode_byte_byte(emit, MP_BC_UNARY_OP, MP_UNARY_OP_BOOL); + emit_write_bytecode_byte(emit, MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_BOOL); emit_bc_pre(emit, 0); emit_write_bytecode_byte(emit, MP_BC_NOT); } else { emit_bc_pre(emit, 0); - emit_write_bytecode_byte_byte(emit, MP_BC_UNARY_OP, op); + emit_write_bytecode_byte(emit, MP_BC_UNARY_OP_MULTI + op); } } @@ -743,7 +745,7 @@ STATIC void emit_bc_binary_op(emit_t *emit, mp_binary_op_t op) { op = MP_BINARY_OP_IS; } emit_bc_pre(emit, -1); - emit_write_bytecode_byte_byte(emit, MP_BC_BINARY_OP, op); + emit_write_bytecode_byte(emit, MP_BC_BINARY_OP_MULTI + op); if (invert) { emit_bc_pre(emit, 0); emit_write_bytecode_byte(emit, MP_BC_NOT); |