Skip to content

Commit a210c77

Browse files
committed
py, compiler: Remove emit_pass1 code, using emit_bc to do its job.
First pass for the compiler is computing the scope (eg if an identifier is local or not) and originally had an entire table of methods dedicated to this, most of which did nothing. With changes from previous commit, this set of methods can be removed and the methods from the bytecode emitter used instead, with very little modification -- this is what is done in this commit. This factoring has little to no impact on the speed of the compiler (tested by compiling 3763 Python scripts and timing it). This factoring reduces code size by about 270-300 bytes on Thumb2 archs, and 400 bytes on x86.
1 parent 542bd6b commit a210c77

6 files changed

Lines changed: 69 additions & 163 deletions

File tree

py/compile.c

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3647,9 +3647,21 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
36473647
module_scope->pn = fold_constants(comp, module_scope->pn, &consts);
36483648
mp_map_deinit(&consts);
36493649

3650+
// create standard emitter; it's used at least for MP_PASS_SCOPE
3651+
#if MICROPY_EMIT_CPYTHON
3652+
emit_t *emit_cpython = emit_cpython_new();
3653+
#else
3654+
emit_t *emit_bc = emit_bc_new();
3655+
#endif
3656+
36503657
// compile pass 1
3651-
comp->emit = NULL;
3652-
comp->emit_method_table = &emit_pass1_method_table;
3658+
#if MICROPY_EMIT_CPYTHON
3659+
comp->emit = emit_cpython;
3660+
comp->emit_method_table = &emit_cpython_method_table;
3661+
#else
3662+
comp->emit = emit_bc;
3663+
comp->emit_method_table = &emit_bc_method_table;
3664+
#endif
36533665
#if MICROPY_EMIT_INLINE_THUMB
36543666
comp->emit_inline_asm = NULL;
36553667
comp->emit_inline_asm_method_table = NULL;
@@ -3676,9 +3688,15 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
36763688
scope_compute_things(s);
36773689
}
36783690

3691+
// set max number of labels now that it's calculated
3692+
#if MICROPY_EMIT_CPYTHON
3693+
emit_cpython_set_max_num_labels(emit_cpython, max_num_labels);
3694+
#else
3695+
emit_bc_set_max_num_labels(emit_bc, max_num_labels);
3696+
#endif
3697+
36793698
// compile pass 2 and 3
36803699
#if !MICROPY_EMIT_CPYTHON
3681-
emit_t *emit_bc = NULL;
36823700
#if MICROPY_EMIT_NATIVE
36833701
emit_t *emit_native = NULL;
36843702
#endif
@@ -3711,7 +3729,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
37113729
// choose the emit type
37123730

37133731
#if MICROPY_EMIT_CPYTHON
3714-
comp->emit = emit_cpython_new(max_num_labels);
3732+
comp->emit = emit_cpython;
37153733
comp->emit_method_table = &emit_cpython_method_table;
37163734
#else
37173735
switch (s->emit_options) {
@@ -3746,9 +3764,6 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
37463764
#endif // MICROPY_EMIT_NATIVE
37473765

37483766
default:
3749-
if (emit_bc == NULL) {
3750-
emit_bc = emit_bc_new(max_num_labels);
3751-
}
37523767
comp->emit = emit_bc;
37533768
comp->emit_method_table = &emit_bc_method_table;
37543769
break;
@@ -3771,10 +3786,11 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
37713786
}
37723787

37733788
// free the emitters
3774-
#if !MICROPY_EMIT_CPYTHON
3775-
if (emit_bc != NULL) {
3776-
emit_bc_free(emit_bc);
3777-
}
3789+
3790+
#if MICROPY_EMIT_CPYTHON
3791+
emit_cpython_free(emit_cpython);
3792+
#else
3793+
emit_bc_free(emit_bc);
37783794
#if MICROPY_EMIT_NATIVE
37793795
if (emit_native != NULL) {
37803796
#if MICROPY_EMIT_X64
@@ -3793,7 +3809,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
37933809
emit_inline_thumb_free(emit_inline_thumb);
37943810
}
37953811
#endif
3796-
#endif // !MICROPY_EMIT_CPYTHON
3812+
#endif // MICROPY_EMIT_CPYTHON
37973813

37983814
// free the parse tree
37993815
mp_parse_node_free(module_scope->pn);

py/emit.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -159,21 +159,24 @@ void mp_emit_common_get_id_for_load(scope_t *scope, qstr qst);
159159
void mp_emit_common_get_id_for_modification(scope_t *scope, qstr qst);
160160
void mp_emit_common_id_op(emit_t *emit, const mp_emit_method_table_id_ops_t *emit_method_table, scope_t *scope, qstr qst);
161161

162-
extern const emit_method_table_t emit_pass1_method_table;
163162
extern const emit_method_table_t emit_cpython_method_table;
164163
extern const emit_method_table_t emit_bc_method_table;
165164
extern const emit_method_table_t emit_native_x64_method_table;
166165
extern const emit_method_table_t emit_native_x86_method_table;
167166
extern const emit_method_table_t emit_native_thumb_method_table;
168167
extern const emit_method_table_t emit_native_arm_method_table;
169168

170-
emit_t *emit_cpython_new(mp_uint_t max_num_labels);
171-
emit_t *emit_bc_new(mp_uint_t max_num_labels);
169+
emit_t *emit_cpython_new(void);
170+
emit_t *emit_bc_new(void);
172171
emit_t *emit_native_x64_new(mp_uint_t max_num_labels);
173172
emit_t *emit_native_x86_new(mp_uint_t max_num_labels);
174173
emit_t *emit_native_thumb_new(mp_uint_t max_num_labels);
175174
emit_t *emit_native_arm_new(mp_uint_t max_num_labels);
176175

176+
void emit_cpython_set_max_num_labels(emit_t* emit, mp_uint_t max_num_labels);
177+
void emit_bc_set_max_num_labels(emit_t* emit, mp_uint_t max_num_labels);
178+
179+
void emit_cpython_free(emit_t *emit);
177180
void emit_bc_free(emit_t *emit);
178181
void emit_native_x64_free(emit_t *emit);
179182
void emit_native_x86_free(emit_t *emit);

py/emitbc.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,14 @@ struct _emit_t {
6565
STATIC void emit_bc_rot_two(emit_t *emit);
6666
STATIC void emit_bc_rot_three(emit_t *emit);
6767

68-
emit_t *emit_bc_new(mp_uint_t max_num_labels) {
68+
emit_t *emit_bc_new(void) {
6969
emit_t *emit = m_new0(emit_t, 1);
70+
return emit;
71+
}
72+
73+
void emit_bc_set_max_num_labels(emit_t* emit, mp_uint_t max_num_labels) {
7074
emit->max_num_labels = max_num_labels;
7175
emit->label_offsets = m_new(mp_uint_t, emit->max_num_labels);
72-
return emit;
7376
}
7477

7578
void emit_bc_free(emit_t *emit) {
@@ -338,6 +341,10 @@ STATIC void emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
338341
}
339342

340343
STATIC void emit_bc_end_pass(emit_t *emit) {
344+
if (emit->pass == MP_PASS_SCOPE) {
345+
return;
346+
}
347+
341348
// check stack is back to zero size
342349
if (emit->stack_size != 0) {
343350
printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
@@ -403,6 +410,9 @@ STATIC void emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) {
403410
}
404411

405412
STATIC void emit_bc_pre(emit_t *emit, mp_int_t stack_size_delta) {
413+
if (emit->pass == MP_PASS_SCOPE) {
414+
return;
415+
}
406416
assert((mp_int_t)emit->stack_size + stack_size_delta >= 0);
407417
emit->stack_size += stack_size_delta;
408418
if (emit->stack_size > emit->scope->stack_size) {
@@ -413,6 +423,9 @@ STATIC void emit_bc_pre(emit_t *emit, mp_int_t stack_size_delta) {
413423

414424
STATIC void emit_bc_label_assign(emit_t *emit, mp_uint_t l) {
415425
emit_bc_pre(emit, 0);
426+
if (emit->pass == MP_PASS_SCOPE) {
427+
return;
428+
}
416429
assert(l < emit->max_num_labels);
417430
if (emit->pass < MP_PASS_EMIT) {
418431
// assign label offset

py/emitcpy.c

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,19 @@ struct _emit_t {
4747
mp_uint_t *label_offsets;
4848
};
4949

50-
emit_t *emit_cpython_new(mp_uint_t max_num_labels) {
51-
emit_t *emit = m_new(emit_t, 1);
50+
emit_t *emit_cpython_new(void) {
51+
emit_t *emit = m_new0(emit_t, 1);
52+
return emit;
53+
}
54+
55+
void emit_cpython_set_max_num_labels(emit_t* emit, mp_uint_t max_num_labels) {
5256
emit->max_num_labels = max_num_labels;
5357
emit->label_offsets = m_new(mp_uint_t, max_num_labels);
54-
return emit;
58+
}
59+
60+
void emit_cpython_free(emit_t *emit) {
61+
m_del(mp_uint_t, emit->label_offsets, emit->max_num_labels);
62+
m_del_obj(emit_t, emit);
5563
}
5664

5765
STATIC void emit_cpy_set_native_type(emit_t *emit, mp_uint_t op, mp_uint_t arg1, qstr arg2) {
@@ -69,6 +77,9 @@ STATIC void emit_cpy_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope)
6977
}
7078

7179
STATIC void emit_cpy_end_pass(emit_t *emit) {
80+
if (emit->pass == MP_PASS_SCOPE) {
81+
return;
82+
}
7283
// check stack is back to zero size
7384
if (emit->stack_size != 0) {
7485
printf("ERROR: stack size not back to zero; got %d\n", emit->stack_size);
@@ -88,6 +99,9 @@ STATIC void emit_cpy_set_source_line(emit_t *emit, mp_uint_t source_line) {
8899

89100
// TODO: module-polymorphic function (read: name clash if made global)
90101
static void emit_pre(emit_t *emit, int stack_size_delta, int bytecode_size) {
102+
if (emit->pass == MP_PASS_SCOPE) {
103+
return;
104+
}
91105
emit->stack_size += stack_size_delta;
92106
if (emit->stack_size > emit->scope->stack_size) {
93107
emit->scope->stack_size = emit->stack_size;
@@ -105,6 +119,9 @@ static void emit_pre(emit_t *emit, int stack_size_delta, int bytecode_size) {
105119

106120
STATIC void emit_cpy_label_assign(emit_t *emit, mp_uint_t l) {
107121
emit_pre(emit, 0, 0);
122+
if (emit->pass == MP_PASS_SCOPE) {
123+
return;
124+
}
108125
assert(l < emit->max_num_labels);
109126
if (emit->pass < MP_PASS_EMIT) {
110127
// assign label offset

py/emitpass1.c

Lines changed: 0 additions & 142 deletions
This file was deleted.

py/py.mk

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ PY_O_BASENAME = \
3131
scope.o \
3232
compile.o \
3333
emitcommon.o \
34-
emitpass1.o \
3534
emitcpy.o \
3635
emitbc.o \
3736
asmx64.o \

0 commit comments

Comments
 (0)