Skip to content

Commit adaf0d8

Browse files
committed
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.
1 parent a5624bf commit adaf0d8

File tree

5 files changed

+38
-60
lines changed

5 files changed

+38
-60
lines changed

py/bc0.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,11 @@
8282

8383
#define MP_BC_BUILD_TUPLE (0x50) // uint
8484
#define MP_BC_BUILD_LIST (0x51) // uint
85-
#define MP_BC_LIST_APPEND (0x52) // uint
8685
#define MP_BC_BUILD_MAP (0x53) // uint
8786
#define MP_BC_STORE_MAP (0x54)
88-
#define MP_BC_MAP_ADD (0x55) // uint
8987
#define MP_BC_BUILD_SET (0x56) // uint
90-
#define MP_BC_SET_ADD (0x57) // uint
9188
#define MP_BC_BUILD_SLICE (0x58) // uint
89+
#define MP_BC_STORE_COMP (0x57) // uint
9290
#define MP_BC_UNPACK_SEQUENCE (0x59) // uint
9391
#define MP_BC_UNPACK_EX (0x5a) // uint
9492

py/emitbc.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -862,21 +862,21 @@ void mp_emit_bc_build_slice(emit_t *emit, mp_uint_t n_args) {
862862
#endif
863863

864864
void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_stack_index) {
865+
int t;
865866
int n;
866-
byte opcode;
867867
if (kind == SCOPE_LIST_COMP) {
868-
n = -1;
869-
opcode = MP_BC_LIST_APPEND;
870-
} else if (MICROPY_PY_BUILTINS_SET && kind == SCOPE_SET_COMP) {
871-
n = -1;
872-
opcode = MP_BC_SET_ADD;
873-
} else {
874-
// scope == SCOPE_DICT_COMP
875-
n = -2;
876-
opcode = MP_BC_MAP_ADD;
868+
n = 0;
869+
t = 0;
870+
} else if (!MICROPY_PY_BUILTINS_SET || kind == SCOPE_DICT_COMP) {
871+
n = 1;
872+
t = 1;
873+
} else if (MICROPY_PY_BUILTINS_SET) {
874+
n = 0;
875+
t = 2;
877876
}
878-
emit_bc_pre(emit, n);
879-
emit_write_bytecode_byte_uint(emit, opcode, collection_stack_index);
877+
emit_bc_pre(emit, -1 - n);
878+
// the lower 2 bits of the opcode argument indicate the collection type
879+
emit_write_bytecode_byte_uint(emit, MP_BC_STORE_COMP, ((collection_stack_index + n) << 2) | t);
880880
}
881881

882882
void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args) {

py/showbc.c

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,6 @@ const byte *mp_bytecode_print_str(const byte *ip) {
409409
printf("BUILD_LIST " UINT_FMT, unum);
410410
break;
411411

412-
case MP_BC_LIST_APPEND:
413-
DECODE_UINT;
414-
printf("LIST_APPEND " UINT_FMT, unum);
415-
break;
416-
417412
case MP_BC_BUILD_MAP:
418413
DECODE_UINT;
419414
printf("BUILD_MAP " UINT_FMT, unum);
@@ -423,28 +418,23 @@ const byte *mp_bytecode_print_str(const byte *ip) {
423418
printf("STORE_MAP");
424419
break;
425420

426-
case MP_BC_MAP_ADD:
427-
DECODE_UINT;
428-
printf("MAP_ADD " UINT_FMT, unum);
429-
break;
430-
431421
case MP_BC_BUILD_SET:
432422
DECODE_UINT;
433423
printf("BUILD_SET " UINT_FMT, unum);
434424
break;
435425

436-
case MP_BC_SET_ADD:
437-
DECODE_UINT;
438-
printf("SET_ADD " UINT_FMT, unum);
439-
break;
440-
441426
#if MICROPY_PY_BUILTINS_SLICE
442427
case MP_BC_BUILD_SLICE:
443428
DECODE_UINT;
444429
printf("BUILD_SLICE " UINT_FMT, unum);
445430
break;
446431
#endif
447432

433+
case MP_BC_STORE_COMP:
434+
DECODE_UINT;
435+
printf("STORE_COMP " UINT_FMT, unum);
436+
break;
437+
448438
case MP_BC_UNPACK_SEQUENCE:
449439
DECODE_UINT;
450440
printf("UNPACK_SEQUENCE " UINT_FMT, unum);

py/vm.c

Lines changed: 19 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -777,15 +777,6 @@ unwind_jump:;
777777
DISPATCH();
778778
}
779779

780-
ENTRY(MP_BC_LIST_APPEND): {
781-
MARK_EXC_IP_SELECTIVE();
782-
DECODE_UINT;
783-
// I think it's guaranteed by the compiler that sp[unum] is a list
784-
mp_obj_list_append(sp[-unum], sp[0]);
785-
sp--;
786-
DISPATCH();
787-
}
788-
789780
ENTRY(MP_BC_BUILD_MAP): {
790781
MARK_EXC_IP_SELECTIVE();
791782
DECODE_UINT;
@@ -799,15 +790,6 @@ unwind_jump:;
799790
mp_obj_dict_store(sp[0], sp[2], sp[1]);
800791
DISPATCH();
801792

802-
ENTRY(MP_BC_MAP_ADD): {
803-
MARK_EXC_IP_SELECTIVE();
804-
DECODE_UINT;
805-
// I think it's guaranteed by the compiler that sp[-unum - 1] is a map
806-
mp_obj_dict_store(sp[-unum - 1], sp[0], sp[-1]);
807-
sp -= 2;
808-
DISPATCH();
809-
}
810-
811793
#if MICROPY_PY_BUILTINS_SET
812794
ENTRY(MP_BC_BUILD_SET): {
813795
MARK_EXC_IP_SELECTIVE();
@@ -816,15 +798,6 @@ unwind_jump:;
816798
SET_TOP(mp_obj_new_set(unum, sp));
817799
DISPATCH();
818800
}
819-
820-
ENTRY(MP_BC_SET_ADD): {
821-
MARK_EXC_IP_SELECTIVE();
822-
DECODE_UINT;
823-
// I think it's guaranteed by the compiler that sp[-unum] is a set
824-
mp_obj_set_store(sp[-unum], sp[0]);
825-
sp--;
826-
DISPATCH();
827-
}
828801
#endif
829802

830803
#if MICROPY_PY_BUILTINS_SLICE
@@ -845,6 +818,25 @@ unwind_jump:;
845818
}
846819
#endif
847820

821+
ENTRY(MP_BC_STORE_COMP): {
822+
MARK_EXC_IP_SELECTIVE();
823+
DECODE_UINT;
824+
mp_obj_t obj = sp[-(unum >> 2)];
825+
if ((unum & 3) == 0) {
826+
mp_obj_list_append(obj, sp[0]);
827+
sp--;
828+
} else if (!MICROPY_PY_BUILTINS_SET || (unum & 3) == 1) {
829+
mp_obj_dict_store(obj, sp[0], sp[-1]);
830+
sp -= 2;
831+
#if MICROPY_PY_BUILTINS_SET
832+
} else {
833+
mp_obj_set_store(obj, sp[0]);
834+
sp--;
835+
#endif
836+
}
837+
DISPATCH();
838+
}
839+
848840
ENTRY(MP_BC_UNPACK_SEQUENCE): {
849841
MARK_EXC_IP_SELECTIVE();
850842
DECODE_UINT;

py/vmentrytable.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,17 +78,15 @@ static const void *const entry_table[256] = {
7878
[MP_BC_POP_EXCEPT] = &&entry_MP_BC_POP_EXCEPT,
7979
[MP_BC_BUILD_TUPLE] = &&entry_MP_BC_BUILD_TUPLE,
8080
[MP_BC_BUILD_LIST] = &&entry_MP_BC_BUILD_LIST,
81-
[MP_BC_LIST_APPEND] = &&entry_MP_BC_LIST_APPEND,
8281
[MP_BC_BUILD_MAP] = &&entry_MP_BC_BUILD_MAP,
8382
[MP_BC_STORE_MAP] = &&entry_MP_BC_STORE_MAP,
84-
[MP_BC_MAP_ADD] = &&entry_MP_BC_MAP_ADD,
8583
#if MICROPY_PY_BUILTINS_SET
8684
[MP_BC_BUILD_SET] = &&entry_MP_BC_BUILD_SET,
87-
[MP_BC_SET_ADD] = &&entry_MP_BC_SET_ADD,
8885
#endif
8986
#if MICROPY_PY_BUILTINS_SLICE
9087
[MP_BC_BUILD_SLICE] = &&entry_MP_BC_BUILD_SLICE,
9188
#endif
89+
[MP_BC_STORE_COMP] = &&entry_MP_BC_STORE_COMP,
9290
[MP_BC_UNPACK_SEQUENCE] = &&entry_MP_BC_UNPACK_SEQUENCE,
9391
[MP_BC_UNPACK_EX] = &&entry_MP_BC_UNPACK_EX,
9492
[MP_BC_MAKE_FUNCTION] = &&entry_MP_BC_MAKE_FUNCTION,

0 commit comments

Comments
 (0)