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 @@ ...@@ -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
......
...@@ -862,21 +862,21 @@ void mp_emit_bc_build_slice(emit_t *emit, mp_uint_t n_args) { ...@@ -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) {
......
...@@ -409,11 +409,6 @@ const byte *mp_bytecode_print_str(const byte *ip) { ...@@ -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) { ...@@ -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) { ...@@ -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);
......
...@@ -777,15 +777,6 @@ unwind_jump:; ...@@ -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:; ...@@ -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:; ...@@ -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:; ...@@ -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] = { ...@@ -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,
......
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