]> Nishi Git Mirror - gwion.git/commitdiff
:art: Improve autoloop readability
authorJérémie Astor <fennecdjay@gmail.com>
Wed, 3 Nov 2021 17:36:07 +0000 (18:36 +0100)
committerJérémie Astor <fennecdjay@gmail.com>
Wed, 3 Nov 2021 17:36:07 +0000 (18:36 +0100)
src/emit/emit.c
src/lib/array.c
src/vm/vm.c

index 087a3a56dfab9b03dae101c55dd14e59d1b67005..f029649395051320e49987ea5861a88251b8b581 100644 (file)
@@ -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 =
index fe91e8629f9192d5217fe8110254a6945ad2377f..fad912e18fa1aaa1619832b154e2b571f8df5725 100644 (file)
@@ -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))
index b618e9df708017d9c3273f548f01cff4e991b6f7..f9338f4af374109d4e37b183f3ab434034f60e89 100644 (file)
@@ -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;