From d53e7cf732b214b9aa6b84ae6ed5411814809bb6 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Sun, 13 Oct 2024 16:33:59 +0800 Subject: [PATCH] dec 'push / pop rets (return values)' in auto gc --- core/scf_auto_gc_3ac.c | 5 + core/scf_optimizer_auto_gc.c | 148 +++++++++++----------- core/scf_optimizer_generate_loads_saves.c | 52 ++++++-- 3 files changed, 122 insertions(+), 83 deletions(-) diff --git a/core/scf_auto_gc_3ac.c b/core/scf_auto_gc_3ac.c index 5006aef..9362d84 100644 --- a/core/scf_auto_gc_3ac.c +++ b/core/scf_auto_gc_3ac.c @@ -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); diff --git a/core/scf_optimizer_auto_gc.c b/core/scf_optimizer_auto_gc.c index 5ea1bf8..822c25a 100644 --- a/core/scf_optimizer_auto_gc.c +++ b/core/scf_optimizer_auto_gc.c @@ -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; diff --git a/core/scf_optimizer_generate_loads_saves.c b/core/scf_optimizer_generate_loads_saves.c index cb026e8..ce0c00b 100644 --- a/core/scf_optimizer_generate_loads_saves.c +++ b/core/scf_optimizer_generate_loads_saves.c @@ -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++) { -- 2.25.1