From e85a096302e8b186b82c74e7da4e1a29ef62d9c6 Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 17 Jun 2022 23:06:24 +1000 Subject: [PATCH] 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 --- py/compile.c | 24 ++++++------------------ py/emit.h | 2 -- py/emitbc.c | 9 --------- py/emitnative.c | 15 +-------------- tests/cmdline/cmd_showbc.py.exp | 14 +++++++++----- 5 files changed, 16 insertions(+), 48 deletions(-) diff --git a/py/compile.c b/py/compile.c index 9cca5df401..ff3e5ffc6d 100644 --- a/py/compile.c +++ b/py/compile.c @@ -1330,12 +1330,8 @@ STATIC void compile_if_stmt(compiler_t *comp, mp_parse_node_struct_t *pns) { goto done; } - if ( - // optimisation: don't jump over non-existent elif/else blocks - !(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) - ) { + // 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]))) { // jump over elif/else blocks 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; } - // optimisation: don't jump if last instruction was return - if (!EMIT(last_emit_was_return_value)) { - EMIT_ARG(jump, l_end); - } + EMIT_ARG(jump, l_end); 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); c_assign(comp, pns->nodes[0], ASSIGN_STORE); // variable 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(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 - // emit return if it wasn't the last opcode - if (!EMIT(last_emit_was_return_value)) { - EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); - EMIT(return_value); - } + EMIT_ARG(load_const_tok, MP_TOKEN_KW_NONE); + EMIT(return_value); } else if (scope->kind == SCOPE_LAMBDA) { assert(MP_PARSE_NODE_IS_STRUCT(scope->pn)); mp_parse_node_struct_t *pns = (mp_parse_node_struct_t *)scope->pn; diff --git a/py/emit.h b/py/emit.h index 608734552a..4e8a55e77a 100644 --- a/py/emit.h +++ b/py/emit.h @@ -115,7 +115,6 @@ typedef struct _emit_method_table_t { void (*start_pass)(emit_t *emit, pass_kind_t pass, scope_t *scope); 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 (*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); 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_set_source_line(emit_t *emit, mp_uint_t line); diff --git a/py/emitbc.c b/py/emitbc.c index 2007975c5e..9c0d78d790 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -47,7 +47,6 @@ struct _emit_t { byte dummy_data[DUMMY_DATA_SIZE]; pass_kind_t pass : 8; - mp_uint_t last_emit_was_return_value : 8; 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) { emit->pass = pass; emit->stack_size = 0; - emit->last_emit_was_return_value = false; emit->scope = scope; emit->last_source_line_offset = 0; emit->last_source_line = 1; @@ -397,10 +395,6 @@ bool mp_emit_bc_end_pass(emit_t *emit) { 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) { if (emit->pass == MP_PASS_SCOPE) { 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) { 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) { @@ -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) { 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) { @@ -806,7 +798,6 @@ const emit_method_table_t emit_bc_method_table = { mp_emit_bc_start_pass, mp_emit_bc_end_pass, - mp_emit_bc_last_emit_was_return_value, mp_emit_bc_adjust_stack_size, mp_emit_bc_set_source_line, diff --git a/py/emitnative.c b/py/emitnative.c index 6683ea4202..5b695a22a7 100644 --- a/py/emitnative.c +++ b/py/emitnative.c @@ -276,8 +276,6 @@ struct _emit_t { uint16_t n_info; uint16_t n_cell; - bool last_emit_was_return_value; - scope_t *scope; 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->do_viper_types = scope->emit_options == MP_EMIT_OPT_VIPER; emit->stack_size = 0; - emit->last_emit_was_return_value = false; emit->scope = scope; // 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; } -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) { if (emit->stack_size + delta > emit->stack_info_alloc) { 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 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 @@ -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 // *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) { - emit->last_emit_was_return_value = false; 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) { *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) { - emit->last_emit_was_return_value = false; adjust_stack(emit, -1); } 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); 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 emit_native_unwind_jump(emit, emit->exit_label, emit->exc_stack_size); - emit->last_emit_was_return_value = true; 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); } 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) { @@ -2928,7 +2916,6 @@ const emit_method_table_t EXPORT_FUN(method_table) = { emit_native_start_pass, emit_native_end_pass, - emit_native_last_emit_was_return_value, emit_native_adjust_stack_size, emit_native_set_source_line, diff --git a/tests/cmdline/cmd_showbc.py.exp b/tests/cmdline/cmd_showbc.py.exp index 45a1d169b6..2eeb8eadd0 100644 --- a/tests/cmdline/cmd_showbc.py.exp +++ b/tests/cmdline/cmd_showbc.py.exp @@ -48,12 +48,12 @@ arg names: 43 LOAD_CONST_NONE 44 RETURN_VALUE 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 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 ######## -\.\+81 63 +\.\+51 63 arg names: (N_STATE 22) (N_EXC_STACK 2) @@ -403,6 +403,8 @@ arg names: 367 RETURN_VALUE 368 LOAD_CONST_SMALL_INT 1 369 RETURN_VALUE +370 LOAD_CONST_NONE +371 RETURN_VALUE File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 59 bytes) 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 @@ -621,9 +623,9 @@ arg names: * 08 DELETE_DEREF 0 10 LOAD_CONST_NONE 11 RETURN_VALUE -File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 13 bytes) -Raw bytecode (code_info_size=8, bytecode_size=5): - 9a 01 0a 05 03 08 80 8b b1 25 00 f2 63 +File cmdline/cmd_showbc.py, code block 'f' (descriptor: \.\+, bytecode @\.\+ 15 bytes) +Raw bytecode (code_info_size=8, bytecode_size=7): + 9a 01 0a 05 03 08 80 8b b1 25 00 f2 63 51 63 arg names: * b (N_STATE 4) (N_EXC_STACK 0) @@ -633,6 +635,8 @@ arg names: * b 01 LOAD_DEREF 0 03 BINARY_OP 27 __add__ 04 RETURN_VALUE +05 LOAD_CONST_NONE +06 RETURN_VALUE mem: total=\\d\+, current=\\d\+, peak=\\d\+ stack: \\d\+ out of \\d\+ GC: total: \\d\+, used: \\d\+, free: \\d\+