py, compiler: When just bytecode, make explicit calls instead of table.
When just the bytecode emitter is needed there is no need to have a
dynamic method table for the emitter back-end, and we can instead
directly call the mp_emit_bc_XXX functions. This gives a significant
reduction in code size and a very slight performance boost for the
compiler.
This patch saves 1160 bytes code on Thumb2 and 972 bytes on x86, when
native emitters are disabled.
Overall savings in code over the last 3 commits are:
bare-arm: 1664 bytes.
minimal: 2136 bytes.
stmhal: 584 bytes (it has native emitter enabled).
cc3200: 1736 bytes.
diff --git a/py/compile.c b/py/compile.c
index a41851c..62b6f05 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -49,6 +49,11 @@
PN_const_object, // special node for a constant, generic Python object
} pn_kind_t;
+#define NEED_METHOD_TABLE (MICROPY_EMIT_CPYTHON || MICROPY_EMIT_NATIVE)
+
+#if NEED_METHOD_TABLE
+
+// we need a method table to do the lookup for the emitter functions
#define EMIT(fun) (comp->emit_method_table->fun(comp->emit))
#define EMIT_ARG(fun, ...) (comp->emit_method_table->fun(comp->emit, __VA_ARGS__))
#define EMIT_LOAD_FAST(qst, local_num) (comp->emit_method_table->load_id.fast(comp->emit, qst, local_num))
@@ -56,6 +61,16 @@
#define EMIT_INLINE_ASM(fun) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm))
#define EMIT_INLINE_ASM_ARG(fun, ...) (comp->emit_inline_asm_method_table->fun(comp->emit_inline_asm, __VA_ARGS__))
+#else
+
+// if we only have the bytecode emitter enabled then we can do a direct call to the functions
+#define EMIT(fun) (mp_emit_bc_##fun(comp->emit))
+#define EMIT_ARG(fun, ...) (mp_emit_bc_##fun(comp->emit, __VA_ARGS__))
+#define EMIT_LOAD_FAST(qst, local_num) (mp_emit_bc_load_fast(comp->emit, qst, local_num))
+#define EMIT_LOAD_GLOBAL(qst) (mp_emit_bc_load_global(comp->emit, qst))
+
+#endif
+
// elements in this struct are ordered to make it compact
typedef struct _compiler_t {
qstr source_file;
@@ -83,7 +98,9 @@
scope_t *scope_cur;
emit_t *emit; // current emitter
+ #if NEED_METHOD_TABLE
const emit_method_table_t *emit_method_table; // current emit method table
+ #endif
#if MICROPY_EMIT_INLINE_THUMB
emit_inline_asm_t *emit_inline_asm; // current emitter for inline asm
@@ -406,7 +423,11 @@
if (comp->pass == MP_PASS_SCOPE) {
mp_emit_common_get_id_for_load(comp->scope_cur, qst);
} else {
+ #if NEED_METHOD_TABLE
mp_emit_common_id_op(comp->emit, &comp->emit_method_table->load_id, comp->scope_cur, qst);
+ #else
+ mp_emit_common_id_op(comp->emit, &mp_emit_bc_method_table_load_id_ops, comp->scope_cur, qst);
+ #endif
}
}
@@ -414,7 +435,11 @@
if (comp->pass == MP_PASS_SCOPE) {
mp_emit_common_get_id_for_modification(comp->scope_cur, qst);
} else {
+ #if NEED_METHOD_TABLE
mp_emit_common_id_op(comp->emit, &comp->emit_method_table->store_id, comp->scope_cur, qst);
+ #else
+ mp_emit_common_id_op(comp->emit, &mp_emit_bc_method_table_store_id_ops, comp->scope_cur, qst);
+ #endif
}
}
@@ -422,7 +447,11 @@
if (comp->pass == MP_PASS_SCOPE) {
mp_emit_common_get_id_for_modification(comp->scope_cur, qst);
} else {
+ #if NEED_METHOD_TABLE
mp_emit_common_id_op(comp->emit, &comp->emit_method_table->delete_id, comp->scope_cur, qst);
+ #else
+ mp_emit_common_id_op(comp->emit, &mp_emit_bc_method_table_delete_id_ops, comp->scope_cur, qst);
+ #endif
}
}
@@ -2963,7 +2992,7 @@
}
} else {
mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)pn;
- EMIT_ARG(set_line_number, pns->source_line);
+ EMIT_ARG(set_source_line, pns->source_line);
compile_function_t f = compile_function[MP_PARSE_NODE_STRUCT_KIND(pns)];
if (f == NULL) {
#if MICROPY_DEBUG_PRINTERS
@@ -3660,8 +3689,10 @@
comp->emit_method_table = &emit_cpython_method_table;
#else
comp->emit = emit_bc;
+ #if MICROPY_EMIT_NATIVE
comp->emit_method_table = &emit_bc_method_table;
#endif
+ #endif
#if MICROPY_EMIT_INLINE_THUMB
comp->emit_inline_asm = NULL;
comp->emit_inline_asm_method_table = NULL;
@@ -3765,7 +3796,9 @@
default:
comp->emit = emit_bc;
+ #if MICROPY_EMIT_NATIVE
comp->emit_method_table = &emit_bc_method_table;
+ #endif
break;
}
#endif // !MICROPY_EMIT_CPYTHON