py/compile: Add support to select the native emitter at runtime.

pull/4588/head
Damien George 2019-03-09 10:59:25 +11:00
rodzic 0e4c24ec08
commit d9d92f27d7
6 zmienionych plików z 45 dodań i 3 usunięć

Wyświetl plik

@ -35,6 +35,7 @@
#include "py/compile.h"
#include "py/runtime.h"
#include "py/asmbase.h"
#include "py/persistentcode.h"
#if MICROPY_ENABLE_COMPILER
@ -78,7 +79,25 @@ typedef enum {
#endif
#if MICROPY_EMIT_NATIVE
#if MICROPY_EMIT_NATIVE && MICROPY_DYNAMIC_COMPILER
#define NATIVE_EMITTER(f) emit_native_table[mp_dynamic_compiler.native_arch]->emit_##f
#define NATIVE_EMITTER_TABLE emit_native_table[mp_dynamic_compiler.native_arch]
STATIC const emit_method_table_t *emit_native_table[] = {
NULL,
&emit_native_x86_method_table,
&emit_native_x64_method_table,
&emit_native_arm_method_table,
&emit_native_thumb_method_table,
&emit_native_thumb_method_table,
&emit_native_thumb_method_table,
&emit_native_thumb_method_table,
&emit_native_thumb_method_table,
&emit_native_xtensa_method_table,
};
#elif MICROPY_EMIT_NATIVE
// define a macro to access external native emitter
#if MICROPY_EMIT_X64
#define NATIVE_EMITTER(f) emit_native_x64_##f
@ -93,6 +112,7 @@ typedef enum {
#else
#error "unknown native emitter"
#endif
#define NATIVE_EMITTER_TABLE &NATIVE_EMITTER(method_table)
#endif
#if MICROPY_EMIT_INLINE_ASM
@ -3470,7 +3490,7 @@ mp_raw_code_t *mp_compile_to_raw_code(mp_parse_tree_t *parse_tree, qstr source_f
if (emit_native == NULL) {
emit_native = NATIVE_EMITTER(new)(&comp->compile_error, &comp->next_label, max_num_labels);
}
comp->emit_method_table = &NATIVE_EMITTER(method_table);
comp->emit_method_table = NATIVE_EMITTER_TABLE;
comp->emit = emit_native;
break;
#endif // MICROPY_EMIT_NATIVE

Wyświetl plik

@ -98,6 +98,11 @@ typedef struct _mp_emit_method_table_id_ops_t {
} mp_emit_method_table_id_ops_t;
typedef struct _emit_method_table_t {
#if MICROPY_DYNAMIC_COMPILER
emit_t *(*emit_new)(mp_obj_t *error_slot, uint *label_slot, mp_uint_t max_num_labels);
void (*emit_free)(emit_t *emit);
#endif
void (*start_pass)(emit_t *emit, pass_kind_t pass, scope_t *scope);
void (*end_pass)(emit_t *emit);
bool (*last_emit_was_return_value)(emit_t *emit);

Wyświetl plik

@ -909,6 +909,11 @@ void mp_emit_bc_end_except_handler(emit_t *emit) {
#if MICROPY_EMIT_NATIVE
const emit_method_table_t emit_bc_method_table = {
#if MICROPY_DYNAMIC_COMPILER
NULL,
NULL,
#endif
mp_emit_bc_start_pass,
mp_emit_bc_end_pass,
mp_emit_bc_last_emit_was_return_value,

Wyświetl plik

@ -2727,6 +2727,11 @@ STATIC void emit_native_end_except_handler(emit_t *emit) {
}
const emit_method_table_t EXPORT_FUN(method_table) = {
#if MICROPY_DYNAMIC_COMPILER
EXPORT_FUN(new),
EXPORT_FUN(free),
#endif
emit_native_start_pass,
emit_native_end_pass,
emit_native_last_emit_was_return_value,

Wyświetl plik

@ -46,6 +46,7 @@ typedef struct mp_dynamic_compiler_t {
uint8_t small_int_bits; // must be <= host small_int_bits
bool opt_cache_map_lookup_in_bytecode;
bool py_builtins_str_unicode;
uint8_t native_arch;
} mp_dynamic_compiler_t;
extern mp_dynamic_compiler_t mp_dynamic_compiler;
#endif

Wyświetl plik

@ -78,6 +78,12 @@
#define MPY_FEATURE_ARCH (MP_NATIVE_ARCH_NONE)
#endif
#if MICROPY_DYNAMIC_COMPILER
#define MPY_FEATURE_ARCH_DYNAMIC mp_dynamic_compiler.native_arch
#else
#define MPY_FEATURE_ARCH_DYNAMIC MPY_FEATURE_ARCH
#endif
#if MICROPY_PERSISTENT_CODE_LOAD || (MICROPY_PERSISTENT_CODE_SAVE && !MICROPY_DYNAMIC_COMPILER)
// The bytecode will depend on the number of bits in a small-int, and
// this function computes that (could make it a fixed constant, but it
@ -731,7 +737,7 @@ void mp_raw_code_save(mp_raw_code_t *rc, mp_print_t *print) {
#endif
};
if (mp_raw_code_has_native(rc)) {
header[2] |= MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH);
header[2] |= MPY_FEATURE_ENCODE_ARCH(MPY_FEATURE_ARCH_DYNAMIC);
}
mp_print_bytes(print, header, sizeof(header));
mp_print_uint(print, QSTR_WINDOW_SIZE);