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.
This commit is contained in:
parent
a5624bf381
commit
adaf0d865c
4
py/bc0.h
4
py/bc0.h
|
@ -82,13 +82,11 @@
|
||||||
|
|
||||||
#define MP_BC_BUILD_TUPLE (0x50) // uint
|
#define MP_BC_BUILD_TUPLE (0x50) // uint
|
||||||
#define MP_BC_BUILD_LIST (0x51) // 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_BUILD_MAP (0x53) // uint
|
||||||
#define MP_BC_STORE_MAP (0x54)
|
#define MP_BC_STORE_MAP (0x54)
|
||||||
#define MP_BC_MAP_ADD (0x55) // uint
|
|
||||||
#define MP_BC_BUILD_SET (0x56) // 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_BUILD_SLICE (0x58) // uint
|
||||||
|
#define MP_BC_STORE_COMP (0x57) // uint
|
||||||
#define MP_BC_UNPACK_SEQUENCE (0x59) // uint
|
#define MP_BC_UNPACK_SEQUENCE (0x59) // uint
|
||||||
#define MP_BC_UNPACK_EX (0x5a) // uint
|
#define MP_BC_UNPACK_EX (0x5a) // uint
|
||||||
|
|
||||||
|
|
24
py/emitbc.c
24
py/emitbc.c
|
@ -862,21 +862,21 @@ void mp_emit_bc_build_slice(emit_t *emit, mp_uint_t n_args) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_stack_index) {
|
void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_stack_index) {
|
||||||
|
int t;
|
||||||
int n;
|
int n;
|
||||||
byte opcode;
|
|
||||||
if (kind == SCOPE_LIST_COMP) {
|
if (kind == SCOPE_LIST_COMP) {
|
||||||
n = -1;
|
n = 0;
|
||||||
opcode = MP_BC_LIST_APPEND;
|
t = 0;
|
||||||
} else if (MICROPY_PY_BUILTINS_SET && kind == SCOPE_SET_COMP) {
|
} else if (!MICROPY_PY_BUILTINS_SET || kind == SCOPE_DICT_COMP) {
|
||||||
n = -1;
|
n = 1;
|
||||||
opcode = MP_BC_SET_ADD;
|
t = 1;
|
||||||
} else {
|
} else if (MICROPY_PY_BUILTINS_SET) {
|
||||||
// scope == SCOPE_DICT_COMP
|
n = 0;
|
||||||
n = -2;
|
t = 2;
|
||||||
opcode = MP_BC_MAP_ADD;
|
|
||||||
}
|
}
|
||||||
emit_bc_pre(emit, n);
|
emit_bc_pre(emit, -1 - n);
|
||||||
emit_write_bytecode_byte_uint(emit, opcode, collection_stack_index);
|
// 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) {
|
void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args) {
|
||||||
|
|
20
py/showbc.c
20
py/showbc.c
|
@ -409,11 +409,6 @@ const byte *mp_bytecode_print_str(const byte *ip) {
|
||||||
printf("BUILD_LIST " UINT_FMT, unum);
|
printf("BUILD_LIST " UINT_FMT, unum);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_LIST_APPEND:
|
|
||||||
DECODE_UINT;
|
|
||||||
printf("LIST_APPEND " UINT_FMT, unum);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MP_BC_BUILD_MAP:
|
case MP_BC_BUILD_MAP:
|
||||||
DECODE_UINT;
|
DECODE_UINT;
|
||||||
printf("BUILD_MAP " UINT_FMT, unum);
|
printf("BUILD_MAP " UINT_FMT, unum);
|
||||||
|
@ -423,21 +418,11 @@ const byte *mp_bytecode_print_str(const byte *ip) {
|
||||||
printf("STORE_MAP");
|
printf("STORE_MAP");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_MAP_ADD:
|
|
||||||
DECODE_UINT;
|
|
||||||
printf("MAP_ADD " UINT_FMT, unum);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MP_BC_BUILD_SET:
|
case MP_BC_BUILD_SET:
|
||||||
DECODE_UINT;
|
DECODE_UINT;
|
||||||
printf("BUILD_SET " UINT_FMT, unum);
|
printf("BUILD_SET " UINT_FMT, unum);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MP_BC_SET_ADD:
|
|
||||||
DECODE_UINT;
|
|
||||||
printf("SET_ADD " UINT_FMT, unum);
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if MICROPY_PY_BUILTINS_SLICE
|
#if MICROPY_PY_BUILTINS_SLICE
|
||||||
case MP_BC_BUILD_SLICE:
|
case MP_BC_BUILD_SLICE:
|
||||||
DECODE_UINT;
|
DECODE_UINT;
|
||||||
|
@ -445,6 +430,11 @@ const byte *mp_bytecode_print_str(const byte *ip) {
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
case MP_BC_STORE_COMP:
|
||||||
|
DECODE_UINT;
|
||||||
|
printf("STORE_COMP " UINT_FMT, unum);
|
||||||
|
break;
|
||||||
|
|
||||||
case MP_BC_UNPACK_SEQUENCE:
|
case MP_BC_UNPACK_SEQUENCE:
|
||||||
DECODE_UINT;
|
DECODE_UINT;
|
||||||
printf("UNPACK_SEQUENCE " UINT_FMT, unum);
|
printf("UNPACK_SEQUENCE " UINT_FMT, unum);
|
||||||
|
|
46
py/vm.c
46
py/vm.c
|
@ -777,15 +777,6 @@ unwind_jump:;
|
||||||
DISPATCH();
|
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): {
|
ENTRY(MP_BC_BUILD_MAP): {
|
||||||
MARK_EXC_IP_SELECTIVE();
|
MARK_EXC_IP_SELECTIVE();
|
||||||
DECODE_UINT;
|
DECODE_UINT;
|
||||||
|
@ -799,15 +790,6 @@ unwind_jump:;
|
||||||
mp_obj_dict_store(sp[0], sp[2], sp[1]);
|
mp_obj_dict_store(sp[0], sp[2], sp[1]);
|
||||||
DISPATCH();
|
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
|
#if MICROPY_PY_BUILTINS_SET
|
||||||
ENTRY(MP_BC_BUILD_SET): {
|
ENTRY(MP_BC_BUILD_SET): {
|
||||||
MARK_EXC_IP_SELECTIVE();
|
MARK_EXC_IP_SELECTIVE();
|
||||||
|
@ -816,15 +798,6 @@ unwind_jump:;
|
||||||
SET_TOP(mp_obj_new_set(unum, sp));
|
SET_TOP(mp_obj_new_set(unum, sp));
|
||||||
DISPATCH();
|
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
|
#endif
|
||||||
|
|
||||||
#if MICROPY_PY_BUILTINS_SLICE
|
#if MICROPY_PY_BUILTINS_SLICE
|
||||||
|
@ -845,6 +818,25 @@ unwind_jump:;
|
||||||
}
|
}
|
||||||
#endif
|
#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): {
|
ENTRY(MP_BC_UNPACK_SEQUENCE): {
|
||||||
MARK_EXC_IP_SELECTIVE();
|
MARK_EXC_IP_SELECTIVE();
|
||||||
DECODE_UINT;
|
DECODE_UINT;
|
||||||
|
|
|
@ -78,17 +78,15 @@ static const void *const entry_table[256] = {
|
||||||
[MP_BC_POP_EXCEPT] = &&entry_MP_BC_POP_EXCEPT,
|
[MP_BC_POP_EXCEPT] = &&entry_MP_BC_POP_EXCEPT,
|
||||||
[MP_BC_BUILD_TUPLE] = &&entry_MP_BC_BUILD_TUPLE,
|
[MP_BC_BUILD_TUPLE] = &&entry_MP_BC_BUILD_TUPLE,
|
||||||
[MP_BC_BUILD_LIST] = &&entry_MP_BC_BUILD_LIST,
|
[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_BUILD_MAP] = &&entry_MP_BC_BUILD_MAP,
|
||||||
[MP_BC_STORE_MAP] = &&entry_MP_BC_STORE_MAP,
|
[MP_BC_STORE_MAP] = &&entry_MP_BC_STORE_MAP,
|
||||||
[MP_BC_MAP_ADD] = &&entry_MP_BC_MAP_ADD,
|
|
||||||
#if MICROPY_PY_BUILTINS_SET
|
#if MICROPY_PY_BUILTINS_SET
|
||||||
[MP_BC_BUILD_SET] = &&entry_MP_BC_BUILD_SET,
|
[MP_BC_BUILD_SET] = &&entry_MP_BC_BUILD_SET,
|
||||||
[MP_BC_SET_ADD] = &&entry_MP_BC_SET_ADD,
|
|
||||||
#endif
|
#endif
|
||||||
#if MICROPY_PY_BUILTINS_SLICE
|
#if MICROPY_PY_BUILTINS_SLICE
|
||||||
[MP_BC_BUILD_SLICE] = &&entry_MP_BC_BUILD_SLICE,
|
[MP_BC_BUILD_SLICE] = &&entry_MP_BC_BUILD_SLICE,
|
||||||
#endif
|
#endif
|
||||||
|
[MP_BC_STORE_COMP] = &&entry_MP_BC_STORE_COMP,
|
||||||
[MP_BC_UNPACK_SEQUENCE] = &&entry_MP_BC_UNPACK_SEQUENCE,
|
[MP_BC_UNPACK_SEQUENCE] = &&entry_MP_BC_UNPACK_SEQUENCE,
|
||||||
[MP_BC_UNPACK_EX] = &&entry_MP_BC_UNPACK_EX,
|
[MP_BC_UNPACK_EX] = &&entry_MP_BC_UNPACK_EX,
|
||||||
[MP_BC_MAKE_FUNCTION] = &&entry_MP_BC_MAKE_FUNCTION,
|
[MP_BC_MAKE_FUNCTION] = &&entry_MP_BC_MAKE_FUNCTION,
|
||||||
|
|
Loading…
Reference in New Issue