py/emit: Remove logic to detect last-emit-was-return-value.
This optimisation to remove dead code is not as good as it could be. Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
0db046b67b
commit
e85a096302
24
py/compile.c
24
py/compile.c
@ -1330,12 +1330,8 @@ STATIC void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
// optimisation: don't jump over non-existent elif/else blocks
|
||||||
// optimisation: don't jump over non-existent elif/else blocks
|
if (!(MP_PARSE_NODE_IS_NULL(pns->nodes[2]) && MP_PARSE_NODE_IS_NULL(pns->nodes[3]))) {
|
||||||
!(MP_PARSE_NODE_IS_NULL(pns->nodes[2]) && MP_PARSE_NODE_IS_NULL(pns->nodes[3]))
|
|
||||||
// optimisation: don't jump if last instruction was return
|
|
||||||
&& !EMIT(last_emit_was_return_value)
|
|
||||||
) {
|
|
||||||
// jump over elif/else blocks
|
// jump over elif/else blocks
|
||||||
EMIT_ARG(jump, l_end);
|
EMIT_ARG(jump, l_end);
|
||||||
}
|
}
|
||||||
@ -1362,10 +1358,7 @@ STATIC void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
// optimisation: don't jump if last instruction was return
|
EMIT_ARG(jump, l_end);
|
||||||
if (!EMIT(last_emit_was_return_value)) {
|
|
||||||
EMIT_ARG(jump, l_end);
|
|
||||||
}
|
|
||||||
EMIT_ARG(label_assign, l_fail);
|
EMIT_ARG(label_assign, l_fail);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1580,9 +1573,7 @@ STATIC void compile_for_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||||||
EMIT_ARG(for_iter, pop_label);
|
EMIT_ARG(for_iter, pop_label);
|
||||||
c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
|
c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable
|
||||||
compile_node(comp, pns->nodes[2]); // body
|
compile_node(comp, pns->nodes[2]); // body
|
||||||
if (!EMIT(last_emit_was_return_value)) {
|
EMIT_ARG(jump, continue_label);
|
||||||
EMIT_ARG(jump, continue_label);
|
|
||||||
}
|
|
||||||
EMIT_ARG(label_assign, pop_label);
|
EMIT_ARG(label_assign, pop_label);
|
||||||
EMIT(for_iter_end);
|
EMIT(for_iter_end);
|
||||||
|
|
||||||
@ -3048,11 +3039,8 @@ STATIC bool compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compile_node(comp, pns->nodes[3]); // 3 is function body
|
compile_node(comp, pns->nodes[3]); // 3 is function body
|
||||||
// emit return if it wasn't the last opcode
|
EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
|
||||||
if (!EMIT(last_emit_was_return_value)) {
|
EMIT(return_value);
|
||||||
EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE);
|
|
||||||
EMIT(return_value);
|
|
||||||
}
|
|
||||||
} else if (scope->kind == SCOPE_LAMBDA) {
|
} else if (scope->kind == SCOPE_LAMBDA) {
|
||||||
assert(MP_PARSE_NODE_IS_STRUCT(scope->pn));
|
assert(MP_PARSE_NODE_IS_STRUCT(scope->pn));
|
||||||
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)scope->pn;
|
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)scope->pn;
|
||||||
|
@ -115,7 +115,6 @@ typedef struct _emit_method_table_t {
|
|||||||
|
|
||||||
void (*start_pass)(emit_t *emit, pass_kind_t pass, scope_t *scope);
|
void (*start_pass)(emit_t *emit, pass_kind_t pass, scope_t *scope);
|
||||||
bool (*end_pass)(emit_t *emit);
|
bool (*end_pass)(emit_t *emit);
|
||||||
bool (*last_emit_was_return_value)(emit_t *emit);
|
|
||||||
void (*adjust_stack_size)(emit_t *emit, mp_int_t delta);
|
void (*adjust_stack_size)(emit_t *emit, mp_int_t delta);
|
||||||
void (*set_source_line)(emit_t *emit, mp_uint_t line);
|
void (*set_source_line)(emit_t *emit, mp_uint_t line);
|
||||||
|
|
||||||
@ -227,7 +226,6 @@ void emit_native_xtensawin_free(emit_t *emit);
|
|||||||
|
|
||||||
void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope);
|
void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope);
|
||||||
bool mp_emit_bc_end_pass(emit_t *emit);
|
bool mp_emit_bc_end_pass(emit_t *emit);
|
||||||
bool mp_emit_bc_last_emit_was_return_value(emit_t *emit);
|
|
||||||
void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta);
|
void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta);
|
||||||
void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t line);
|
void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t line);
|
||||||
|
|
||||||
|
@ -47,7 +47,6 @@ struct _emit_t {
|
|||||||
byte dummy_data[DUMMY_DATA_SIZE];
|
byte dummy_data[DUMMY_DATA_SIZE];
|
||||||
|
|
||||||
pass_kind_t pass : 8;
|
pass_kind_t pass : 8;
|
||||||
mp_uint_t last_emit_was_return_value : 8;
|
|
||||||
|
|
||||||
int stack_size;
|
int stack_size;
|
||||||
|
|
||||||
@ -272,7 +271,6 @@ STATIC void emit_write_bytecode_byte_label(emit_t *emit, int stack_adj, byte b1,
|
|||||||
void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
|
void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
|
||||||
emit->pass = pass;
|
emit->pass = pass;
|
||||||
emit->stack_size = 0;
|
emit->stack_size = 0;
|
||||||
emit->last_emit_was_return_value = false;
|
|
||||||
emit->scope = scope;
|
emit->scope = scope;
|
||||||
emit->last_source_line_offset = 0;
|
emit->last_source_line_offset = 0;
|
||||||
emit->last_source_line = 1;
|
emit->last_source_line = 1;
|
||||||
@ -397,10 +395,6 @@ bool mp_emit_bc_end_pass(emit_t *emit) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool mp_emit_bc_last_emit_was_return_value(emit_t *emit) {
|
|
||||||
return emit->last_emit_was_return_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta) {
|
void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta) {
|
||||||
if (emit->pass == MP_PASS_SCOPE) {
|
if (emit->pass == MP_PASS_SCOPE) {
|
||||||
return;
|
return;
|
||||||
@ -410,7 +404,6 @@ void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta) {
|
|||||||
if (emit->stack_size > emit->scope->stack_size) {
|
if (emit->stack_size > emit->scope->stack_size) {
|
||||||
emit->scope->stack_size = emit->stack_size;
|
emit->scope->stack_size = emit->stack_size;
|
||||||
}
|
}
|
||||||
emit->last_emit_was_return_value = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) {
|
void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) {
|
||||||
@ -773,7 +766,6 @@ void mp_emit_bc_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_ke
|
|||||||
|
|
||||||
void mp_emit_bc_return_value(emit_t *emit) {
|
void mp_emit_bc_return_value(emit_t *emit) {
|
||||||
emit_write_bytecode_byte(emit, -1, MP_BC_RETURN_VALUE);
|
emit_write_bytecode_byte(emit, -1, MP_BC_RETURN_VALUE);
|
||||||
emit->last_emit_was_return_value = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) {
|
void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) {
|
||||||
@ -806,7 +798,6 @@ const emit_method_table_t emit_bc_method_table = {
|
|||||||
|
|
||||||
mp_emit_bc_start_pass,
|
mp_emit_bc_start_pass,
|
||||||
mp_emit_bc_end_pass,
|
mp_emit_bc_end_pass,
|
||||||
mp_emit_bc_last_emit_was_return_value,
|
|
||||||
mp_emit_bc_adjust_stack_size,
|
mp_emit_bc_adjust_stack_size,
|
||||||
mp_emit_bc_set_source_line,
|
mp_emit_bc_set_source_line,
|
||||||
|
|
||||||
|
@ -276,8 +276,6 @@ struct _emit_t {
|
|||||||
uint16_t n_info;
|
uint16_t n_info;
|
||||||
uint16_t n_cell;
|
uint16_t n_cell;
|
||||||
|
|
||||||
bool last_emit_was_return_value;
|
|
||||||
|
|
||||||
scope_t *scope;
|
scope_t *scope;
|
||||||
|
|
||||||
ASM_T *as;
|
ASM_T *as;
|
||||||
@ -370,7 +368,6 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
|
|||||||
emit->pass = pass;
|
emit->pass = pass;
|
||||||
emit->do_viper_types = scope->emit_options == MP_EMIT_OPT_VIPER;
|
emit->do_viper_types = scope->emit_options == MP_EMIT_OPT_VIPER;
|
||||||
emit->stack_size = 0;
|
emit->stack_size = 0;
|
||||||
emit->last_emit_was_return_value = false;
|
|
||||||
emit->scope = scope;
|
emit->scope = scope;
|
||||||
|
|
||||||
// allocate memory for keeping track of the types of locals
|
// allocate memory for keeping track of the types of locals
|
||||||
@ -733,10 +730,6 @@ STATIC bool emit_native_end_pass(emit_t *emit) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC bool emit_native_last_emit_was_return_value(emit_t *emit) {
|
|
||||||
return emit->last_emit_was_return_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
STATIC void ensure_extra_stack(emit_t *emit, size_t delta) {
|
STATIC void ensure_extra_stack(emit_t *emit, size_t delta) {
|
||||||
if (emit->stack_size + delta > emit->stack_info_alloc) {
|
if (emit->stack_size + delta > emit->stack_info_alloc) {
|
||||||
size_t new_alloc = (emit->stack_size + delta + 8) & ~3;
|
size_t new_alloc = (emit->stack_size + delta + 8) & ~3;
|
||||||
@ -793,7 +786,7 @@ STATIC void emit_native_set_source_line(emit_t *emit, mp_uint_t source_line) {
|
|||||||
|
|
||||||
// this must be called at start of emit functions
|
// this must be called at start of emit functions
|
||||||
STATIC void emit_native_pre(emit_t *emit) {
|
STATIC void emit_native_pre(emit_t *emit) {
|
||||||
emit->last_emit_was_return_value = false;
|
(void)emit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// depth==0 is top, depth==1 is before top, etc
|
// depth==0 is top, depth==1 is before top, etc
|
||||||
@ -917,7 +910,6 @@ STATIC void emit_fold_stack_top(emit_t *emit, int reg_dest) {
|
|||||||
// If stacked value is in a register and the register is not r1 or r2, then
|
// If stacked value is in a register and the register is not r1 or r2, then
|
||||||
// *reg_dest is set to that register. Otherwise the value is put in *reg_dest.
|
// *reg_dest is set to that register. Otherwise the value is put in *reg_dest.
|
||||||
STATIC void emit_pre_pop_reg_flexible(emit_t *emit, vtype_kind_t *vtype, int *reg_dest, int not_r1, int not_r2) {
|
STATIC void emit_pre_pop_reg_flexible(emit_t *emit, vtype_kind_t *vtype, int *reg_dest, int not_r1, int not_r2) {
|
||||||
emit->last_emit_was_return_value = false;
|
|
||||||
stack_info_t *si = peek_stack(emit, 0);
|
stack_info_t *si = peek_stack(emit, 0);
|
||||||
if (si->kind == STACK_REG && si->data.u_reg != not_r1 && si->data.u_reg != not_r2) {
|
if (si->kind == STACK_REG && si->data.u_reg != not_r1 && si->data.u_reg != not_r2) {
|
||||||
*vtype = si->vtype;
|
*vtype = si->vtype;
|
||||||
@ -930,12 +922,10 @@ STATIC void emit_pre_pop_reg_flexible(emit_t *emit, vtype_kind_t *vtype, int *re
|
|||||||
}
|
}
|
||||||
|
|
||||||
STATIC void emit_pre_pop_discard(emit_t *emit) {
|
STATIC void emit_pre_pop_discard(emit_t *emit) {
|
||||||
emit->last_emit_was_return_value = false;
|
|
||||||
adjust_stack(emit, -1);
|
adjust_stack(emit, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void emit_pre_pop_reg(emit_t *emit, vtype_kind_t *vtype, int reg_dest) {
|
STATIC void emit_pre_pop_reg(emit_t *emit, vtype_kind_t *vtype, int reg_dest) {
|
||||||
emit->last_emit_was_return_value = false;
|
|
||||||
emit_access_stack(emit, 1, vtype, reg_dest);
|
emit_access_stack(emit, 1, vtype, reg_dest);
|
||||||
adjust_stack(emit, -1);
|
adjust_stack(emit, -1);
|
||||||
}
|
}
|
||||||
@ -2771,7 +2761,6 @@ STATIC void emit_native_return_value(emit_t *emit) {
|
|||||||
|
|
||||||
// Do the unwinding jump to get to the return handler
|
// Do the unwinding jump to get to the return handler
|
||||||
emit_native_unwind_jump(emit, emit->exit_label, emit->exc_stack_size);
|
emit_native_unwind_jump(emit, emit->exit_label, emit->exc_stack_size);
|
||||||
emit->last_emit_was_return_value = true;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2809,7 +2798,6 @@ STATIC void emit_native_return_value(emit_t *emit) {
|
|||||||
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_RET_VAL(emit), REG_PARENT_RET);
|
ASM_MOV_LOCAL_REG(emit->as, LOCAL_IDX_RET_VAL(emit), REG_PARENT_RET);
|
||||||
}
|
}
|
||||||
emit_native_unwind_jump(emit, emit->exit_label, emit->exc_stack_size);
|
emit_native_unwind_jump(emit, emit->exit_label, emit->exc_stack_size);
|
||||||
emit->last_emit_was_return_value = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
STATIC void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) {
|
STATIC void emit_native_raise_varargs(emit_t *emit, mp_uint_t n_args) {
|
||||||
@ -2928,7 +2916,6 @@ const emit_method_table_t EXPORT_FUN(method_table) = {
|
|||||||
|
|
||||||
emit_native_start_pass,
|
emit_native_start_pass,
|
||||||
emit_native_end_pass,
|
emit_native_end_pass,
|
||||||
emit_native_last_emit_was_return_value,
|
|
||||||
emit_native_adjust_stack_size,
|
emit_native_adjust_stack_size,
|
||||||
emit_native_set_source_line,
|
emit_native_set_source_line,
|
||||||
|
|
||||||
|
@ -48,12 +48,12 @@ arg names:
|
|||||||
43 LOAD_CONST_NONE
|
43 LOAD_CONST_NONE
|
||||||
44 RETURN_VALUE
|
44 RETURN_VALUE
|
||||||
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 45\[46\] bytes)
|
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 45\[46\] bytes)
|
||||||
Raw bytecode (code_info_size=8\[46\], bytecode_size=370):
|
Raw bytecode (code_info_size=8\[46\], bytecode_size=372):
|
||||||
a8 12 9\[bf\] 03 05 60 60 26 22 24 64 22 24 25 25 24
|
a8 12 9\[bf\] 03 05 60 60 26 22 24 64 22 24 25 25 24
|
||||||
26 23 63 22 22 25 23 23 2f 6c 25 65 25 25 69 68
|
26 23 63 22 22 25 23 23 2f 6c 25 65 25 25 69 68
|
||||||
26 65 27 6a 62 20 23 62 2a 29 69 24 25 28 67 26
|
26 65 27 6a 62 20 23 62 2a 29 69 24 25 28 67 26
|
||||||
########
|
########
|
||||||
\.\+81 63
|
\.\+51 63
|
||||||
arg names:
|
arg names:
|
||||||
(N_STATE 22)
|
(N_STATE 22)
|
||||||
(N_EXC_STACK 2)
|
(N_EXC_STACK 2)
|
||||||
@ -403,6 +403,8 @@ arg names:
|
|||||||
367 RETURN_VALUE
|
367 RETURN_VALUE
|
||||||
368 LOAD_CONST_SMALL_INT 1
|
368 LOAD_CONST_SMALL_INT 1
|
||||||
369 RETURN_VALUE
|
369 RETURN_VALUE
|
||||||
|
370 LOAD_CONST_NONE
|
||||||
|
371 RETURN_VALUE
|
||||||
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 59 bytes)
|
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 59 bytes)
|
||||||
Raw bytecode (code_info_size=8, bytecode_size=51):
|
Raw bytecode (code_info_size=8, bytecode_size=51):
|
||||||
a8 10 0a 05 80 82 34 38 81 57 c0 57 c1 57 c2 57
|
a8 10 0a 05 80 82 34 38 81 57 c0 57 c1 57 c2 57
|
||||||
@ -621,9 +623,9 @@ arg names: *
|
|||||||
08 DELETE_DEREF 0
|
08 DELETE_DEREF 0
|
||||||
10 LOAD_CONST_NONE
|
10 LOAD_CONST_NONE
|
||||||
11 RETURN_VALUE
|
11 RETURN_VALUE
|
||||||
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 13 bytes)
|
File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 15 bytes)
|
||||||
Raw bytecode (code_info_size=8, bytecode_size=5):
|
Raw bytecode (code_info_size=8, bytecode_size=7):
|
||||||
9a 01 0a 05 03 08 80 8b b1 25 00 f2 63
|
9a 01 0a 05 03 08 80 8b b1 25 00 f2 63 51 63
|
||||||
arg names: * b
|
arg names: * b
|
||||||
(N_STATE 4)
|
(N_STATE 4)
|
||||||
(N_EXC_STACK 0)
|
(N_EXC_STACK 0)
|
||||||
@ -633,6 +635,8 @@ arg names: * b
|
|||||||
01 LOAD_DEREF 0
|
01 LOAD_DEREF 0
|
||||||
03 BINARY_OP 27 __add__
|
03 BINARY_OP 27 __add__
|
||||||
04 RETURN_VALUE
|
04 RETURN_VALUE
|
||||||
|
05 LOAD_CONST_NONE
|
||||||
|
06 RETURN_VALUE
|
||||||
mem: total=\\d\+, current=\\d\+, peak=\\d\+
|
mem: total=\\d\+, current=\\d\+, peak=\\d\+
|
||||||
stack: \\d\+ out of \\d\+
|
stack: \\d\+ out of \\d\+
|
||||||
GC: total: \\d\+, used: \\d\+, free: \\d\+
|
GC: total: \\d\+, used: \\d\+, free: \\d\+
|
||||||
|
Loading…
Reference in New Issue
Block a user