From 93865e9dedfca516a72a3ae558cf271c63a888f9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=A9mie=20Astor?= Date: Wed, 19 May 2021 13:16:48 +0200 Subject: [PATCH] :art: Optimized loop instructions --- include/env/value.h | 4 ++++ include/opcode.h | 6 ++++++ opcode.txt | 3 +++ src/emit/emit.c | 41 ++++++++++++++++++++--------------------- src/parse/check.c | 2 +- src/parse/scan1.c | 2 +- src/vm/vm.c | 15 +++++++++++---- src/vm/vm_code.c | 7 ++++--- util | 2 +- 9 files changed, 51 insertions(+), 31 deletions(-) diff --git a/include/env/value.h b/include/env/value.h index 5796979a..ec3ebf05 100644 --- a/include/env/value.h +++ b/include/env/value.h @@ -44,4 +44,8 @@ FLAG_FUNC(Value, v) ANEW ANN Value new_value(MemPool p, const Type type, const m_str name); ANN void valuefrom(const Env, struct ValueFrom_*, const loc_t loc); + +ANN static inline void defined_here(const Value v) { + gwerr_secondary(_("defined here"), v->from->filename, v->from->loc); +} #endif diff --git a/include/opcode.h b/include/opcode.h index d0e695d1..f7343533 100644 --- a/include/opcode.h +++ b/include/opcode.h @@ -25,6 +25,9 @@ enum { eStructMemberOther, eStructMemberAddr, eMemSetImm, + eMemAddImm, + eRepeatIdx, + eRepeat, eRegPushMe, eRegPushMaybe, eFuncReturn, @@ -222,6 +225,9 @@ enum { #define StructMemberOther (f_instr)eStructMemberOther #define StructMemberAddr (f_instr)eStructMemberAddr #define MemSetImm (f_instr)eMemSetImm +#define MemAddImm (f_instr)eMemAddImm +#define RepeatIdx (f_instr)eRepeatIdx +#define Repeat (f_instr)eRepeat #define RegPushMe (f_instr)eRegPushMe #define RegPushMaybe (f_instr)eRegPushMaybe #define FuncReturn (f_instr)eFuncReturn diff --git a/opcode.txt b/opcode.txt index 73536e3a..efce167a 100644 --- a/opcode.txt +++ b/opcode.txt @@ -22,6 +22,9 @@ StructMemberFloat StructMemberOther StructMemberAddr MemSetImm +MemAddImm +RepeatIdx +Repeat RegPushMe RegPushMaybe FuncReturn diff --git a/src/emit/emit.c b/src/emit/emit.c index 6f23c45f..1b3f5825 100644 --- a/src/emit/emit.c +++ b/src/emit/emit.c @@ -1751,28 +1751,27 @@ ANN static m_bool emit_stmt_for(const Emitter emit, const Stmt_For stmt) { struct Looper; +typedef Instr (*f_looper_init)(const Emitter, const struct Looper *); typedef void (*f_looper)(const Emitter, const struct Looper *); struct Looper { const Stmt stmt; /*const */m_uint offset; const m_uint n; - const f_looper roll; + const f_looper_init roll; const f_looper unroll; }; ANN static inline m_bool roll(const Emitter emit, const struct Looper *loop) { - if(loop->roll) - loop->roll(emit, loop); - const Instr instr = emit_add_instr(emit, BranchEqInt); + const Instr instr = loop->roll(emit, loop); CHECK_BB(scoped_stmt(emit, loop->stmt, 1)); instr->m_val = emit_code_size(emit) + 1; // pass after goto return GW_OK; } -ANN static void stmt_each_roll(const Emitter emit, const struct Looper *loop) { +ANN static Instr stmt_each_roll(const Emitter emit, const struct Looper *loop) { const Instr instr = emit_add_instr(emit, AutoLoop); - instr->m_val = loop->offset + SZ_INT; - regpush(emit, SZ_INT); + instr->m_val2 = loop->offset + SZ_INT; + return instr; } ANN static inline void unroll_init(const Emitter emit, const m_uint n) { @@ -1860,28 +1859,28 @@ ANN static m_bool emit_stmt_each(const Emitter emit, const Stmt_Each stmt) { return ret; } -ANN static void stmt_loop_roll(const Emitter emit, const struct Looper *loop) { - const Instr counter = emit_add_instr(emit, RegPushMem4); - counter->m_val = loop->offset; - emit_add_instr(emit, int_post_dec); +ANN static Instr stmt_loop_roll(const Emitter emit, const struct Looper *loop) { + const Instr eq = emit_add_instr(emit, Repeat); + eq->m_val2 = loop->offset; + return eq; } -ANN static void stmt_loop_roll_idx(const Emitter emit, const struct Looper *loop) { - const Instr target = emit_add_instr(emit, RegPushMem); - target->m_val = loop->offset + SZ_INT; - const Instr counter = emit_add_instr(emit, RegPushMem4); - counter->m_val = loop->offset; - emit_add_instr(emit, int_post_inc); - emit_add_instr(emit, int_minus); +ANN static Instr stmt_loop_roll_idx(const Emitter emit, const struct Looper *loop) { + const Instr instr = emit_add_instr(emit, RepeatIdx); + instr->m_val2 = loop->offset; + return instr; } -ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt, m_uint *index) { +ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt, + m_uint *index) { const uint n = emit->info->unroll; if(n) unroll_init(emit, n); const m_uint offset = emit_local(emit, emit->gwion->type[et_int]); - if(stmt->idx) - emit_local(emit, emit->gwion->type[et_int]); + if(stmt->idx) { + const Instr instr = emit_add_instr(emit, MemSetImm); + instr->m_val = stmt->idx->v->from->offset = emit_local(emit, emit->gwion->type[et_int]); + } CHECK_BB(emit_exp_pop_next(emit, stmt->cond)); regpop(emit, SZ_INT); const Instr tomem = emit_add_instr(emit, Reg2Mem); diff --git a/src/parse/check.c b/src/parse/check.c index 68100dec..27e4ead5 100644 --- a/src/parse/check.c +++ b/src/parse/check.c @@ -50,7 +50,7 @@ ANN static inline m_bool check_exp_decl_parent(const Env env, const Var_Decl var if(value) { env_err(env, var->pos, _("Value defined in parent class")); - gwerr_secondary(_("defined here"), value->from->filename, value->from->loc); + defined_here(value); return GW_ERROR; } return GW_OK; diff --git a/src/parse/scan1.c b/src/parse/scan1.c index 1df28fda..34d05424 100644 --- a/src/parse/scan1.c +++ b/src/parse/scan1.c @@ -305,7 +305,7 @@ ANN static inline m_bool stmt_each_defined(const restrict Env env, const Stmt_Ea ANN static inline m_bool shadow_err(const Env env, const Value v, const loc_t loc) { gwerr_basic(_("shadowing a previously defined variable"), NULL, NULL, env->name, loc, 0); - gwerr_secondary(_("defined here"), v->from->filename, v->from->loc); + defined_here(v); env->context->error = true; return GW_ERROR; } diff --git a/src/vm/vm.c b/src/vm/vm.c index 902013ac..bc7118eb 100644 --- a/src/vm/vm.c +++ b/src/vm/vm.c @@ -372,7 +372,7 @@ ANN void vm_run(const VM* vm) { // lgtm [cpp/use-of-goto] &&baseint, &&basefloat, &&baseother, &&baseaddr, &®toreg, &®toregother, &®toregaddr, &®toregderef, &&structmember, &&structmemberfloat, &&structmemberother, &&structmemberaddr, - &&memsetimm, + &&memsetimm, &&memaddimm, &&repeatidx, &&repeat, &®pushme, &®pushmaybe, &&funcreturn, &&_goto, @@ -529,6 +529,14 @@ structmemberaddr: memsetimm: *(m_uint*)(mem+VAL) = VAL2; DISPATCH(); +memaddimm: + *(m_int*)(mem+VAL) += (m_int)VAL2; +// (*(m_int*)(mem+VAL))--; + DISPATCH(); +repeatidx: + BRANCH_DISPATCH(*(m_int*)(mem+VAL2+SZ_INT) == ++(*(m_int*)(mem+VAL2))); +repeat: + BRANCH_DISPATCH(!--*(m_uint*)(mem+VAL2)); regpushme: *(M_Object*)reg = shred->info->me; reg += SZ_INT; @@ -817,9 +825,8 @@ autounrollinit: *(m_uint*)(mem + VAL) = m_vector_size(ARRAY(*(M_Object*)(mem+VAL+SZ_INT))); DISPATCH() autoloop: - *(m_bit**)(mem + VAL + SZ_INT) = m_vector_addr(ARRAY(*(M_Object*)(mem+VAL-SZ_INT)), *(m_uint*)(mem + VAL) + 1); - *(m_uint*)reg = m_vector_size(ARRAY(*(M_Object*)(mem+VAL-SZ_INT))) - (*(m_uint*)(mem + VAL))++ -1; - DISPATCH() + *(m_bit**)(mem + VAL2 + SZ_INT) = m_vector_addr(ARRAY(*(M_Object*)(mem+VAL2-SZ_INT)), *(m_uint*)(mem + VAL2) + 1); + BRANCH_DISPATCH(m_vector_size(ARRAY(*(M_Object*)(mem+VAL2-SZ_INT))) == ++*(m_uint*)(mem + VAL2)); arraytop: if(*(m_uint*)(reg - SZ_INT * 2) < *(m_uint*)(reg-SZ_INT)) goto newobj; diff --git a/src/vm/vm_code.c b/src/vm/vm_code.c index 453bc295..77418999 100644 --- a/src/vm/vm_code.c +++ b/src/vm/vm_code.c @@ -42,10 +42,11 @@ ANN void free_vmcode(VM_Code a, Gwion gwion) { } static inline uint isgoto(const unsigned opcode) { - return opcode == eGoto || opcode == eArrayTop || - opcode == eBranchEqInt || opcode == eBranchNeqInt || + return opcode == eGoto || opcode == eArrayTop || + opcode == eBranchEqInt || opcode == eBranchNeqInt || opcode == eBranchEqFloat || opcode == eBranchNeqFloat || - opcode == eHandleEffect; + opcode == eHandleEffect || opcode == eRepeat || + opcode == eRepeatIdx || opcode == eAutoLoop; } ANN static inline void setpc(const m_bit *data, const m_uint i) { diff --git a/util b/util index 7f657c4d..4e08843b 160000 --- a/util +++ b/util @@ -1 +1 @@ -Subproject commit 7f657c4d12c8a4362d26b1976ddca5de2324d60a +Subproject commit 4e08843bd4c85578e1965ffd81c41fc36f42358d -- 2.43.0