From: Jérémie Astor Date: Wed, 3 Nov 2021 17:36:07 +0000 (+0100) Subject: :art: Improve autoloop readability X-Git-Tag: nightly~417 X-Git-Url: http://10.10.0.4:5575/?a=commitdiff_plain;h=c7595de221d685aecf43c38cd5b670384b294938;p=gwion.git :art: Improve autoloop readability --- diff --git a/src/emit/emit.c b/src/emit/emit.c index 087a3a56..f0296493 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -2223,12 +2223,16 @@ struct Looper; typedef Instr (*f_looper_init)(const Emitter, const struct Looper *); typedef void (*f_looper)(const Emitter, const struct Looper *); struct Looper { + const Exp exp; const Stmt stmt; /*const */ m_uint offset; const m_uint n; const f_looper_init roll; const f_looper_init unroll; - struct Vector_ unroll_v; +// union { + struct Vector_ unroll_v; + Instr instr; +// }; }; ANN static inline m_bool roll(const Emitter emit, struct Looper *const loop) { @@ -2239,9 +2243,16 @@ ANN static inline m_bool roll(const Emitter emit, struct Looper *const loop) { } ANN static Instr stmt_each_roll(const Emitter emit, const struct Looper *loop) { - const Instr instr = emit_add_instr(emit, AutoLoop); - instr->m_val2 = loop->offset + SZ_INT; - return instr; +// const Instr instr = emit_add_instr(emit, AutoLoop); +// instr->m_val2 = loop->offset + SZ_INT; +// return instr; + struct Op_Import opi = { + .lhs = loop->exp->type, + .op = insert_symbol("@autoloop"), + .data = (m_uint)loop + }; + CHECK_BO(op_emit(emit, &opi)); + return loop->instr; } ANN static inline void unroll_init(const Emitter emit, const m_uint n) { @@ -2290,9 +2301,16 @@ ANN static m_bool unroll(const Emitter emit, struct Looper *loop) { } ANN static Instr stmt_each_unroll(const Emitter emit, const struct Looper *loop) { - const Instr instr = emit_add_instr(emit, AutoLoop); - instr->m_val2 = loop->offset + SZ_INT * 2; - return instr; + struct Op_Import opi = { + .lhs = loop->exp->type, + .op = insert_symbol("@autoloop"), + .data = (m_uint)loop + }; + CHECK_BO(op_emit(emit, &opi)); + return loop->instr; +// const Instr instr = emit_add_instr(emit, AutoLoop); +// instr->m_val2 = loop->offset + SZ_INT * 2; +// return instr; } ANN static inline m_bool looper_run(const Emitter emit, @@ -2326,7 +2344,8 @@ ANN static m_bool _emit_stmt_each(const Emitter emit, const Stmt_Each stmt, instr->m_val = offset - SZ_INT; } const m_uint ini_pc = emit_code_size(emit); - struct Looper loop = {.stmt = stmt->body, + struct Looper loop = {.exp = stmt->exp, + .stmt = stmt->body, .offset = offset, .n = n, .roll = stmt_each_roll, @@ -2378,7 +2397,8 @@ ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt, const Instr tomem = emit_add_instr(emit, Reg2Mem); tomem->m_val = offset + (!stmt->idx ? 0 : SZ_INT); *index = emit_code_size(emit); - struct Looper loop = {.stmt = stmt->body, + struct Looper loop = {.exp = stmt->cond, + .stmt = stmt->body, .offset = offset, .n = n, .roll = diff --git a/src/lib/array.c b/src/lib/array.c index fe91e862..fad912e1 100644 --- a/src/lib/array.c +++ b/src/lib/array.c @@ -725,6 +725,35 @@ static OP_CHECK(opck_array_implicit) { return imp->t; } +struct Looper; +typedef Instr (*f_looper_init)(const Emitter, const struct Looper *); +typedef void (*f_looper)(const Emitter, const struct Looper *); +struct Looper { + const Exp exp; + const Stmt stmt; + /*const */ m_uint offset; + const m_uint n; + const f_looper_init roll; + const f_looper_init unroll; +// union { + struct Vector_ unroll_v; + Instr instr; +// }; +}; + +static OP_EMIT(opem_array_autoloop) { + struct Looper *loop = (struct Looper *)data; + const Instr instr = emit_add_instr(emit, AutoLoop); + if(!loop->n) { + instr->m_val2 = loop->offset + SZ_INT; + } else { + instr->m_val2 = loop->offset + SZ_INT*2; + vector_add(&loop->unroll_v, (m_uint)instr); + } + loop->instr = instr; + return GW_OK; +} + ANN static void prepare_run(m_bit *const byte, const f_instr ini, const f_instr end) { *(unsigned *)byte = eOP_MAX; @@ -848,6 +877,9 @@ GWION_IMPORT(array) { GWI_BB(gwi_oper_add(gwi, opck_array)) GWI_BB(gwi_oper_emi(gwi, opem_array_access)) GWI_BB(gwi_oper_end(gwi, "@array", NULL)) + GWI_BB(gwi_oper_ini(gwi, "@Array", NULL, "int")) + GWI_BB(gwi_oper_emi(gwi, opem_array_autoloop)) + GWI_BB(gwi_oper_end(gwi, "@autoloop", NULL)) GWI_BB(gwi_oper_ini(gwi, "@Array", NULL, NULL)) GWI_BB(gwi_oper_add(gwi, opck_array_scan)) GWI_BB(gwi_oper_end(gwi, "@scan", NULL)) diff --git a/src/vm/vm.c b/src/vm/vm.c index b618e9df..f9338f4a 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -1034,13 +1034,12 @@ vm_run(const VM *vm) { // lgtm [cpp/use-of-goto] *(m_uint *)(mem + VAL) = m_vector_size(ARRAY(*(M_Object *)(mem + VAL + SZ_INT))); DISPATCH() - autoloop: + autoloop: { + const M_Vector array = ARRAY(*(M_Object *)(mem + VAL2 - SZ_INT)); *(m_bit **)(mem + VAL2 + SZ_INT) = - m_vector_addr(ARRAY(*(M_Object *)(mem + VAL2 - SZ_INT)), - ++*(m_uint *)(mem + VAL2)); - BRANCH_DISPATCH( - m_vector_size(ARRAY(*(M_Object *)(mem + VAL2 - SZ_INT))) == - *(m_uint *)(mem + VAL2)); + m_vector_addr(array, ++*(m_uint *)(mem + VAL2)); + BRANCH_DISPATCH(m_vector_size(array) == *(m_uint *)(mem + VAL2)); + } arraytop: if (*(m_uint *)(reg - SZ_INT * 2) < *(m_uint *)(reg - SZ_INT)) goto newobj;