summaryrefslogtreecommitdiffstatshomepage
path: root/py/emitbc.c
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2014-10-25 16:43:46 +0100
committerDamien George <damien.p.george@gmail.com>2014-10-25 20:23:13 +0100
commit8456cc017bc2e4a9fe063f485c3f2aa410435015 (patch)
treee0c8055f6de2c7975b6b7b31e80beb622ce9b3ad /py/emitbc.c
parent1084b0f9c21b093618da4494508dec9ca8467e35 (diff)
downloadmicropython-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.c30
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);