From d3439d0c6065bc60a9c4c915f4a1a3ffa796cf33 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 2 Jun 2014 19:37:55 +0300 Subject: [PATCH 1/3] py: Instead of having "debug on" var, have "optimization level" var. This allows to have multiple "optimization" levels (CPython has two (-OO removes docstrings), we can have more). --- py/lexer.c | 9 ++------- py/lexer.h | 2 ++ py/runtime.c | 5 +++-- py/runtime.h | 2 -- unix/main.c | 12 +++++++++--- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/py/lexer.c b/py/lexer.c index 4a7ac071b4..26993922eb 100644 --- a/py/lexer.c +++ b/py/lexer.c @@ -64,12 +64,7 @@ struct _mp_lexer_t { mp_token_t tok_cur; }; -// debug flag for __debug__ constant -STATIC mp_token_kind_t mp_debug_value; - -void mp_set_debug(bool value) { - mp_debug_value = value ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE; -} +uint mp_optimise_value; // TODO replace with a call to a standard function bool str_strn_equal(const char *str, const char *strn, int len) { @@ -703,7 +698,7 @@ STATIC void mp_lexer_next_token_into(mp_lexer_t *lex, mp_token_t *tok, bool firs if (str_strn_equal(tok_kw[i], tok->str, tok->len)) { if (i == ARRAY_SIZE(tok_kw) - 1) { // tok_kw[ARRAY_SIZE(tok_kw) - 1] == "__debug__" - tok->kind = mp_debug_value; + tok->kind = (mp_optimise_value == 0 ? MP_TOKEN_KW_TRUE : MP_TOKEN_KW_FALSE); } else { tok->kind = MP_TOKEN_KW_FALSE + i; } diff --git a/py/lexer.h b/py/lexer.h index b302cb2db1..24cae1e252 100644 --- a/py/lexer.h +++ b/py/lexer.h @@ -176,3 +176,5 @@ typedef enum { mp_import_stat_t mp_import_stat(const char *path); mp_lexer_t *mp_lexer_new_from_file(const char *filename); + +extern uint mp_optimise_value; diff --git a/py/runtime.c b/py/runtime.c index ecaf40deb4..27a5ed5439 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -45,6 +45,7 @@ #include "bc.h" #include "smallint.h" #include "objgenerator.h" +#include "lexer.h" #if 0 // print debugging info #define DEBUG_PRINT (1) @@ -74,8 +75,8 @@ void mp_init(void) { MICROPY_PORT_INIT_FUNC; #endif - // __debug__ enabled by default - mp_set_debug(true); + // optimization disabled by default + mp_optimise_value = 0; // init global module stuff mp_module_init(); diff --git a/py/runtime.h b/py/runtime.h index 3c79b48ed0..dbd413180b 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -54,8 +54,6 @@ typedef struct _mp_arg_t { void mp_init(void); void mp_deinit(void); -void mp_set_debug(bool value); // sets the value of __debug__; see lexer.c - void mp_arg_check_num(uint n_args, uint n_kw, uint n_args_min, uint n_args_max, bool takes_kw); void mp_arg_parse_all(uint n_pos, const mp_obj_t *pos, mp_map_t *kws, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); void mp_arg_parse_all_kw_array(uint n_pos, uint n_kw, const mp_obj_t *args, uint n_allowed, const mp_arg_t *allowed, mp_arg_val_t *out_vals); diff --git a/unix/main.c b/unix/main.c index 992ea1fec5..7c3fbf6aa1 100644 --- a/unix/main.c +++ b/unix/main.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -188,6 +189,7 @@ int usage(char **argv) { "usage: %s [] [-X ] [-c ] []\n" "Options:\n" "-v : verbose (trace various operations); can be multiple\n" +"-O[N] : apply bytecode optimizations of level N\n" "\n" "Implementation specific options:\n", argv[0] ); @@ -346,9 +348,13 @@ int main(int argc, char **argv) { a += 1; } else if (strcmp(argv[a], "-v") == 0) { mp_verbose_flag++; - } else if (strcmp(argv[a], "-O") == 0) { - // optimisation; sets __debug__ to False - mp_set_debug(false); + } else if (strncmp(argv[a], "-O", 2) == 0) { + if (isdigit(argv[a][2])) { + mp_optimise_value = argv[a][2] & 0xf; + } else { + mp_optimise_value = 0; + for (char *p = argv[a] + 1; *p && *p == 'O'; p++, mp_optimise_value++); + } } else { return usage(argv); } From b8f117dd32aae6d2d8108ba101961d00df123e4f Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 2 Jun 2014 19:39:15 +0300 Subject: [PATCH 2/3] py: For optimization level -O3 and higher, remove lineno info from bytecode. --- py/emitbc.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/py/emitbc.c b/py/emitbc.c index cfaea7c88a..841dd4aabb 100644 --- a/py/emitbc.c +++ b/py/emitbc.c @@ -352,6 +352,10 @@ STATIC void emit_bc_adjust_stack_size(emit_t *emit, int delta) { STATIC void emit_bc_set_source_line(emit_t *emit, int source_line) { //printf("source: line %d -> %d offset %d -> %d\n", emit->last_source_line, source_line, emit->last_source_line_offset, emit->bytecode_offset); #if MICROPY_ENABLE_SOURCE_LINE + if (mp_optimise_value >= 3) { + // If we compile with -O3, don't store line numbers. + return; + } if (source_line > emit->last_source_line) { uint bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset; uint lines_to_skip = source_line - emit->last_source_line; From 411732e93bcbeb529bc5f9722015b61c63eef3c5 Mon Sep 17 00:00:00 2001 From: Paul Sokolovsky Date: Mon, 2 Jun 2014 18:24:34 +0300 Subject: [PATCH 3/3] vm: If there's no lineno info, set lineno in traceback to 0, not 1. To clearly signify that lineno is not known. --- py/vm.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/py/vm.c b/py/vm.c index cfb390bae7..d57fbf17e3 100644 --- a/py/vm.c +++ b/py/vm.c @@ -1042,12 +1042,16 @@ exception_handler: machine_uint_t code_info_size = code_info[0] | (code_info[1] << 8) | (code_info[2] << 16) | (code_info[3] << 24); qstr source_file = code_info[4] | (code_info[5] << 8) | (code_info[6] << 16) | (code_info[7] << 24); qstr block_name = code_info[8] | (code_info[9] << 8) | (code_info[10] << 16) | (code_info[11] << 24); - machine_uint_t source_line = 1; + machine_uint_t source_line = 0; machine_uint_t bc = code_state->ip - code_info - code_info_size; //printf("find %lu %d %d\n", bc, code_info[12], code_info[13]); - for (const byte* ci = code_info + 12; *ci && bc >= ((*ci) & 31); ci++) { - bc -= *ci & 31; - source_line += *ci >> 5; + const byte* ci = code_info + 12; + if (*ci) { + source_line = 1; + for (; *ci && bc >= ((*ci) & 31); ci++) { + bc -= *ci & 31; + source_line += *ci >> 5; + } } mp_obj_exception_add_traceback(nlr.ret_val, source_file, source_line, block_name); }