dec 'push / pop rets (return values)' in auto gc
authoryu.dongliang <18588496441@163.com>
Sun, 13 Oct 2024 08:33:59 +0000 (16:33 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 13 Oct 2024 08:33:59 +0000 (16:33 +0800)
core/scf_auto_gc_3ac.c
core/scf_optimizer_auto_gc.c
core/scf_optimizer_generate_loads_saves.c

index 5006aef67d20c3e48e9ab18d1c6db8a34907a708..9362d8436b0e8519b38e541a546912ca342b0bfd 100644 (file)
@@ -167,6 +167,7 @@ static scf_3ac_code_t* _auto_gc_code_memset_array(scf_list_t* dag_list_head, scf
                return NULL;
        }
        v->data.i64 = 0;
+       v->const_literal_flag = 1;
        AUTO_GC_CODE_ADD_VAR();
 
        v = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
@@ -175,6 +176,7 @@ static scf_3ac_code_t* _auto_gc_code_memset_array(scf_list_t* dag_list_head, scf
                return NULL;
        }
        v->data.i64 = scf_variable_size(dn_array->var);
+       v->const_literal_flag = 1;
        AUTO_GC_CODE_ADD_VAR();
 
        return c;
@@ -216,6 +218,7 @@ static scf_3ac_code_t* _auto_gc_code_free_array(scf_list_t* dag_list_head, scf_a
                return NULL;
        }
        v->data.i64 = capacity;
+       v->const_literal_flag = 1;
        AUTO_GC_CODE_ADD_VAR();
 
        v = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
@@ -224,6 +227,7 @@ static scf_3ac_code_t* _auto_gc_code_free_array(scf_list_t* dag_list_head, scf_a
                return NULL;
        }
        v->data.i64 = nb_pointers;
+       v->const_literal_flag = 1;
        AUTO_GC_CODE_ADD_VAR();
 
        if (dn_array->var->type >= SCF_STRUCT) {
@@ -279,6 +283,7 @@ static scf_3ac_code_t* _auto_gc_code_freep_array(scf_list_t* dag_list_head, scf_
                return NULL;
        }
        v->data.i64 = nb_pointers;
+       v->const_literal_flag = 1;
 
        char buf[128];
        snprintf(buf, sizeof(buf) - 1, "%d", nb_pointers);
index 5ea1bf89d8e33ecdc34e499694655b0ad2463274..822c25a1e7b0f07cab9f39a16f8321dd63f9de81 100644 (file)
@@ -879,6 +879,74 @@ error:
        return ret;
 }
 
+static int _auto_gc_prev_dn_actives(scf_list_t* current, scf_list_t* sentinel)
+{
+       scf_basic_block_t* bb;
+       scf_dag_node_t*    dn;
+       scf_vector_t*      dn_actives;
+       scf_list_t*        l;
+
+       int ret;
+       int i;
+
+       dn_actives = scf_vector_alloc();
+       if (!dn_actives)
+               return -ENOMEM;
+
+       for (l = current; l != sentinel; l = scf_list_prev(l)) {
+               bb = scf_list_data(l, scf_basic_block_t, list);
+
+               ret = scf_basic_block_active_vars(bb);
+               if (ret < 0)
+                       goto error;
+
+               for (i = 0; i < dn_actives->size; i++) {
+                       dn =        dn_actives->data[i];
+
+                       ret = scf_vector_add_unique(bb->exit_dn_actives, dn);
+                       if (ret < 0)
+                               goto error;
+               }
+
+               for (i = 0; i < bb->entry_dn_actives->size; i++) {
+                       dn =        bb->entry_dn_actives->data[i];
+
+                       ret = scf_vector_add_unique(dn_actives, dn);
+                       if (ret < 0)
+                               goto error;
+               }
+       }
+
+       ret = 0;
+error:
+       scf_vector_free(dn_actives);
+       return ret;
+}
+
+static void _auto_gc_delete(scf_basic_block_t* bb, scf_basic_block_t* bb2)
+{
+       scf_basic_block_t* bb3;
+       scf_basic_block_t* bb4;
+
+       assert(1 == bb2->prevs->size);
+       assert(1 == bb ->nexts->size);
+
+       bb3 = bb2->prevs->data[0];
+       bb4 = bb ->nexts->data[0];
+
+       assert(1 == bb3->nexts->size);
+       assert(1 == bb4->prevs->size);
+
+       bb3->nexts->data[0] = bb4;
+       bb4->prevs->data[0] = bb3;
+
+       scf_list_del(&bb->list);
+       scf_list_del(&bb2->list);
+
+       scf_basic_block_free(bb);
+       scf_basic_block_free(bb2);
+}
+
 static int _optimize_auto_gc(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
 {
        if (!ast || !f)
@@ -892,9 +960,7 @@ static int _optimize_auto_gc(scf_ast_t* ast, scf_function_t* f, scf_vector_t* fu
        scf_basic_block_t* bb;
        scf_basic_block_t* bb2;
 
-       int ret;
-
-       ret = _auto_gc_last_free(ast, f);
+       int ret = _auto_gc_last_free(ast, f);
        if (ret < 0) {
                scf_loge("\n");
                return ret;
@@ -902,11 +968,8 @@ static int _optimize_auto_gc(scf_ast_t* ast, scf_function_t* f, scf_vector_t* fu
 
        for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) {
 
-               scf_dag_node_t* dn;
-               scf_vector_t*   dn_actives;
-
-               scf_list_t*     start = l;
-               scf_list_t*     l2;
+               scf_list_t*  start = l;
+               scf_list_t*  l2;
 
                bb = scf_list_data(l, scf_basic_block_t, list);
 
@@ -923,85 +986,28 @@ static int _optimize_auto_gc(scf_ast_t* ast, scf_function_t* f, scf_vector_t* fu
                        return ret;
                }
 
-               dn_actives = scf_vector_alloc();
-               if (!dn_actives)
-                       return -ENOMEM;
-
-               for (l2 = scf_list_prev(l); l2 != scf_list_prev(start); l2 = scf_list_prev(l2)) {
-                       bb  = scf_list_data(l2, scf_basic_block_t, list);
-
-                       ret = scf_basic_block_active_vars(bb);
-                       if (ret < 0) {
-                               scf_loge("\n");
-                               return ret;
-                       }
-
-                       int i;
-                       for (i = 0; i < dn_actives->size; i++) {
-                               dn =        dn_actives->data[i];
-
-                               ret = scf_vector_add_unique(bb->exit_dn_actives, dn);
-                               if (ret < 0) {
-                                       scf_vector_free(dn_actives);
-                                       return ret;
-                               }
-                       }
-
-                       for (i = 0; i < bb->entry_dn_actives->size; i++) {
-                               dn =        bb->entry_dn_actives->data[i];
-
-                               ret = scf_vector_add_unique(dn_actives, dn);
-                               if (ret < 0) {
-                                       scf_vector_free(dn_actives);
-                                       return ret;
-                               }
-                       }
-               }
-
-               scf_vector_free(dn_actives);
-               dn_actives = NULL;
+               ret = _auto_gc_prev_dn_actives(scf_list_prev(l), scf_list_prev(start));
+               if (ret < 0)
+                       return ret;
 
                for (l2 = scf_list_prev(l); l2 != scf_list_prev(start); ) {
-
                        bb  = scf_list_data(l2, scf_basic_block_t, list);
                        l2  = scf_list_prev(l2);
-#if 1
-                       if (l2 != start && scf_list_prev(l) != &bb->list) {
 
+                       if (l2 != start && scf_list_prev(l) != &bb->list) {
                                bb2 = scf_list_data(l2, scf_basic_block_t, list);
 
                                if (bb->auto_free_flag
                                                && bb2->auto_ref_flag
                                                && 0 == scf_ds_cmp_same_indexes(bb->ds_auto_gc, bb2->ds_auto_gc)) {
 
-                                       scf_basic_block_t* bb3;
-                                       scf_basic_block_t* bb4;
-
-                                       assert(1 == bb2->prevs->size);
-                                       assert(1 == bb ->nexts->size);
-
-                                       bb3 = bb2->prevs->data[0];
-                                       bb4 = bb ->nexts->data[0];
-
-                                       assert(1 == bb3->nexts->size);
-                                       assert(1 == bb4->prevs->size);
-
-                                       bb3->nexts->data[0] = bb4;
-                                       bb4->prevs->data[0] = bb3;
-
                                        l2 = scf_list_prev(l2);
 
-                                       scf_list_del(&bb->list);
-                                       scf_list_del(&bb2->list);
-
-                                       scf_basic_block_free(bb);
-                                       scf_basic_block_free(bb2);
-                                       bb  = NULL;
-                                       bb2 = NULL;
+                                       _auto_gc_delete(bb, bb2);
                                        continue;
                                }
                        }
-#endif
+
                        ret = scf_basic_block_loads_saves(bb, bb_list_head);
                        if (ret < 0)
                                return ret;
index cb026e85e2baeeb484a69f664743ab0c1ffffac8..ce0c00bb9504f1d3b0d8ef387d6c8155fcb5b009 100644 (file)
@@ -25,6 +25,7 @@ static int _optimize_generate_loads_saves(scf_ast_t* ast, scf_function_t* f, scf
 
        scf_list_t*        l;
        scf_basic_block_t* bb;
+       scf_basic_block_t* bb_auto_gc;
        scf_basic_block_t* post;
        scf_bb_group_t*    bbg;
 
@@ -63,6 +64,8 @@ static int _optimize_generate_loads_saves(scf_ast_t* ast, scf_function_t* f, scf
 
        f->nb_basic_blocks = 0;
 
+       bb_auto_gc = NULL;
+
        for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); l = scf_list_next(l)) {
                bb = scf_list_data(l, scf_basic_block_t, list);
 
@@ -109,19 +112,38 @@ static int _optimize_generate_loads_saves(scf_ast_t* ast, scf_function_t* f, scf
                                scf_list_add_front(&bb->code_list_head, &save->list);
                        }
                }
-
-               if (bb->auto_ref_flag || bb->auto_free_flag) {
 #if 1
-                       scf_3ac_code_t* c0 = scf_3ac_code_alloc();
-                       scf_3ac_code_t* c1 = scf_3ac_code_alloc();
+               if (bb->auto_ref_flag || bb->auto_free_flag) {
 
-                       c0->op = scf_3ac_find_operator(SCF_OP_3AC_PUSH_RETS);
-                       c1->op = scf_3ac_find_operator(SCF_OP_3AC_POP_RETS);
+                       if (!bb_auto_gc) {
+                               c = scf_3ac_code_alloc();
+                               if (!c) {
+                                       scf_loge("\n");
+                                       return -ENOMEM;
+                               }
+                               c->op          = scf_3ac_find_operator(SCF_OP_3AC_PUSH_RETS);
+                               c->basic_block = bb;
 
-                       scf_list_add_front(&bb->code_list_head, &c0->list);
-                       scf_list_add_tail(&bb->code_list_head,  &c1->list);
-#endif
+                               scf_list_add_front(&bb->code_list_head, &c->list);
+                       }
+
+                       bb_auto_gc = bb;
+
+               } else {
+                       if (bb_auto_gc) {
+                               c = scf_3ac_code_alloc();
+                               if (!c) {
+                                       scf_loge("\n");
+                                       return -ENOMEM;
+                               }
+                               c->op          = scf_3ac_find_operator(SCF_OP_3AC_POP_RETS);
+                               c->basic_block = bb_auto_gc;
+
+                               scf_list_add_tail(&bb_auto_gc->code_list_head, &c->list);
+                               bb_auto_gc = NULL;
+                       }
                }
+#endif
 
 #if 1
                scf_logd("bb: %p, bb->index: %d\n", bb, bb->index);
@@ -144,7 +166,9 @@ static int _optimize_generate_loads_saves(scf_ast_t* ast, scf_function_t* f, scf
 
                                for (l = scf_list_tail(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); l = scf_list_prev(l)) {
                                        c  = scf_list_data(l, scf_3ac_code_t, list);
-                                       assert(c->active_vars);
+
+                                       if (!c->active_vars)
+                                               continue;
 
                                        ds = scf_vector_find_cmp(c->active_vars, dn, scf_dn_status_cmp);
                                        if (ds)
@@ -160,7 +184,9 @@ static int _optimize_generate_loads_saves(scf_ast_t* ast, scf_function_t* f, scf
 
                                for (l = scf_list_tail(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); l = scf_list_prev(l)) {
                                        c  = scf_list_data(l, scf_3ac_code_t, list);
-                                       assert(c->active_vars);
+
+                                       if (!c->active_vars)
+                                               continue;
 
                                        ds = scf_vector_find_cmp(c->active_vars, dn, scf_dn_status_cmp);
                                        if (ds)
@@ -183,7 +209,9 @@ static int _optimize_generate_loads_saves(scf_ast_t* ast, scf_function_t* f, scf
 
                        for (l = scf_list_tail(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); l = scf_list_prev(l)) {
                                c  = scf_list_data(l, scf_3ac_code_t, list);
-                               assert(c->active_vars);
+
+                               if (!c->active_vars)
+                                       continue;
 
                                int n;
                                for (n = 0; n < bbg->posts->size; n++) {