Commit adaf0d86 authored by Damien George's avatar Damien George
Browse files

py: Combine 3 comprehension opcodes (list/dict/set) into 1.

With the previous patch combining 3 emit functions into 1, it now makes
sense to also combine the corresponding VM opcodes, which is what this
patch does.  This eliminates 2 opcodes which simplifies the VM and reduces
code size, in bytes: bare-arm:44, minimal:64, unix(NDEBUG,x86-64):272,
stmhal:92, esp8266:200.  Profiling (with a simple script that creates many
list/dict/set comprehensions) shows no measurable change in performance.
parent a5624bf3
......@@ -82,13 +82,11 @@
#define MP_BC_BUILD_TUPLE (0x50) // uint
#define MP_BC_BUILD_LIST (0x51) // uint
#define MP_BC_LIST_APPEND (0x52) // uint
#define MP_BC_BUILD_MAP (0x53) // uint
#define MP_BC_STORE_MAP (0x54)
#define MP_BC_MAP_ADD (0x55) // uint
#define MP_BC_BUILD_SET (0x56) // uint
#define MP_BC_SET_ADD (0x57) // uint
#define MP_BC_BUILD_SLICE (0x58) // uint
#define MP_BC_STORE_COMP (0x57) // uint
#define MP_BC_UNPACK_SEQUENCE (0x59) // uint
#define MP_BC_UNPACK_EX (0x5a) // uint
......
......@@ -862,21 +862,21 @@ void mp_emit_bc_build_slice(emit_t *emit, mp_uint_t n_args) {
#endif
void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_stack_index) {
int t;
int n;
byte opcode;
if (kind == SCOPE_LIST_COMP) {
n = -1;
opcode = MP_BC_LIST_APPEND;
} else if (MICROPY_PY_BUILTINS_SET && kind == SCOPE_SET_COMP) {
n = -1;
opcode = MP_BC_SET_ADD;
} else {
// scope == SCOPE_DICT_COMP
n = -2;
opcode = MP_BC_MAP_ADD;
n = 0;
t = 0;
} else if (!MICROPY_PY_BUILTINS_SET || kind == SCOPE_DICT_COMP) {
n = 1;
t = 1;
} else if (MICROPY_PY_BUILTINS_SET) {
n = 0;
t = 2;
}
emit_bc_pre(emit, n);
emit_write_bytecode_byte_uint(emit, opcode, collection_stack_index);
emit_bc_pre(emit, -1 - n);
// the lower 2 bits of the opcode argument indicate the collection type
emit_write_bytecode_byte_uint(emit, MP_BC_STORE_COMP, ((collection_stack_index + n) << 2) | t);
}
void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args) {
......
......@@ -409,11 +409,6 @@ const byte *mp_bytecode_print_str(const byte *ip) {
printf("BUILD_LIST " UINT_FMT, unum);
break;
case MP_BC_LIST_APPEND:
DECODE_UINT;
printf("LIST_APPEND " UINT_FMT, unum);
break;
case MP_BC_BUILD_MAP:
DECODE_UINT;
printf("BUILD_MAP " UINT_FMT, unum);
......@@ -423,21 +418,11 @@ const byte *mp_bytecode_print_str(const byte *ip) {
printf("STORE_MAP");
break;
case MP_BC_MAP_ADD:
DECODE_UINT;
printf("MAP_ADD " UINT_FMT, unum);
break;
case MP_BC_BUILD_SET:
DECODE_UINT;
printf("BUILD_SET " UINT_FMT, unum);
break;
case MP_BC_SET_ADD:
DECODE_UINT;
printf("SET_ADD " UINT_FMT, unum);
break;
#if MICROPY_PY_BUILTINS_SLICE
case MP_BC_BUILD_SLICE:
DECODE_UINT;
......@@ -445,6 +430,11 @@ const byte *mp_bytecode_print_str(const byte *ip) {
break;
#endif
case MP_BC_STORE_COMP:
DECODE_UINT;
printf("STORE_COMP " UINT_FMT, unum);
break;
case MP_BC_UNPACK_SEQUENCE:
DECODE_UINT;
printf("UNPACK_SEQUENCE " UINT_FMT, unum);
......
......@@ -777,15 +777,6 @@ unwind_jump:;
DISPATCH();
}
ENTRY(MP_BC_LIST_APPEND): {
MARK_EXC_IP_SELECTIVE();
DECODE_UINT;
// I think it's guaranteed by the compiler that sp[unum] is a list
mp_obj_list_append(sp[-unum], sp[0]);
sp--;
DISPATCH();
}
ENTRY(MP_BC_BUILD_MAP): {
MARK_EXC_IP_SELECTIVE();
DECODE_UINT;
......@@ -799,15 +790,6 @@ unwind_jump:;
mp_obj_dict_store(sp[0], sp[2], sp[1]);
DISPATCH();
ENTRY(MP_BC_MAP_ADD): {
MARK_EXC_IP_SELECTIVE();
DECODE_UINT;
// I think it's guaranteed by the compiler that sp[-unum - 1] is a map
mp_obj_dict_store(sp[-unum - 1], sp[0], sp[-1]);
sp -= 2;
DISPATCH();
}
#if MICROPY_PY_BUILTINS_SET
ENTRY(MP_BC_BUILD_SET): {
MARK_EXC_IP_SELECTIVE();
......@@ -816,15 +798,6 @@ unwind_jump:;
SET_TOP(mp_obj_new_set(unum, sp));
DISPATCH();
}
ENTRY(MP_BC_SET_ADD): {
MARK_EXC_IP_SELECTIVE();
DECODE_UINT;
// I think it's guaranteed by the compiler that sp[-unum] is a set
mp_obj_set_store(sp[-unum], sp[0]);
sp--;
DISPATCH();
}
#endif
#if MICROPY_PY_BUILTINS_SLICE
......@@ -845,6 +818,25 @@ unwind_jump:;
}
#endif
ENTRY(MP_BC_STORE_COMP): {
MARK_EXC_IP_SELECTIVE();
DECODE_UINT;
mp_obj_t obj = sp[-(unum >> 2)];
if ((unum & 3) == 0) {
mp_obj_list_append(obj, sp[0]);
sp--;
} else if (!MICROPY_PY_BUILTINS_SET || (unum & 3) == 1) {
mp_obj_dict_store(obj, sp[0], sp[-1]);
sp -= 2;
#if MICROPY_PY_BUILTINS_SET
} else {
mp_obj_set_store(obj, sp[0]);
sp--;
#endif
}
DISPATCH();
}
ENTRY(MP_BC_UNPACK_SEQUENCE): {
MARK_EXC_IP_SELECTIVE();
DECODE_UINT;
......
......@@ -78,17 +78,15 @@ static const void *const entry_table[256] = {
[MP_BC_POP_EXCEPT] = &&entry_MP_BC_POP_EXCEPT,
[MP_BC_BUILD_TUPLE] = &&entry_MP_BC_BUILD_TUPLE,
[MP_BC_BUILD_LIST] = &&entry_MP_BC_BUILD_LIST,
[MP_BC_LIST_APPEND] = &&entry_MP_BC_LIST_APPEND,
[MP_BC_BUILD_MAP] = &&entry_MP_BC_BUILD_MAP,
[MP_BC_STORE_MAP] = &&entry_MP_BC_STORE_MAP,
[MP_BC_MAP_ADD] = &&entry_MP_BC_MAP_ADD,
#if MICROPY_PY_BUILTINS_SET
[MP_BC_BUILD_SET] = &&entry_MP_BC_BUILD_SET,
[MP_BC_SET_ADD] = &&entry_MP_BC_SET_ADD,
#endif
#if MICROPY_PY_BUILTINS_SLICE
[MP_BC_BUILD_SLICE] = &&entry_MP_BC_BUILD_SLICE,
#endif
[MP_BC_STORE_COMP] = &&entry_MP_BC_STORE_COMP,
[MP_BC_UNPACK_SEQUENCE] = &&entry_MP_BC_UNPACK_SEQUENCE,
[MP_BC_UNPACK_EX] = &&entry_MP_BC_UNPACK_EX,
[MP_BC_MAKE_FUNCTION] = &&entry_MP_BC_MAKE_FUNCTION,
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment