fix: auto gc error for '../examples/str.c'
authoryu.dongliang <18588496441@163.com>
Sun, 19 Nov 2023 16:07:00 +0000 (00:07 +0800)
committeryu.dongliang <18588496441@163.com>
Sun, 19 Nov 2023 16:07:00 +0000 (00:07 +0800)
core/scf_optimizer_auto_gc_find.c
examples/str.c [new file with mode: 0644]

index 8db422bf90b4fc3cb27929579ae20dd92a4f7248..60e7d063f9748cab44713aae7c233c55a192e601 100644 (file)
@@ -1,6 +1,16 @@
 #include"scf_optimizer.h"
 #include"scf_pointer_alias.h"
 
+static int _bb_find_ds(scf_basic_block_t* bb, scf_dn_status_t* ds_obj)
+{
+       if (scf_vector_find_cmp(bb->ds_freed, ds_obj, scf_dn_status_cmp_same_dn_indexes))
+               return 0;
+
+       if (scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_dn_status_cmp_same_dn_indexes))
+               return 1;
+       return 0;
+}
+
 static int _bb_add_ds(scf_basic_block_t* bb, scf_dn_status_t* ds_obj)
 {
        scf_dn_status_t*   ds2;
@@ -403,6 +413,149 @@ error:
                scf_list_add_front(&parent->list, &child->list); \
        } while (0)
 
+static int _auto_gc_find_argv_out(scf_basic_block_t* cur_bb, scf_3ac_code_t* c)
+{
+       assert(c->srcs->size > 0);
+
+       scf_3ac_operand_t* src = c->srcs->data[0];
+       scf_function_t*    f2  = src->dag_node->var->func_ptr;
+       scf_dag_node_t*    dn;
+       scf_variable_t*    v0;
+       scf_variable_t*    v1;
+       scf_dn_status_t*   ds_obj;
+
+       int count = 0;
+       int ret;
+       int i;
+
+       for (i  = 1; i < c->srcs->size; i++) {
+               src =        c->srcs->data[i];
+
+               dn  = src->dag_node;
+               v0  = dn->var;
+
+               while (dn) {
+                       if (SCF_OP_TYPE_CAST == dn->type)
+                               dn = dn->childs->data[0];
+
+                       else if (SCF_OP_EXPR == dn->type)
+                               dn = dn->childs->data[0];
+                       else
+                               break;
+               }
+
+               if (v0->nb_pointers + v0->nb_dimentions + (v0->type >= SCF_STRUCT) < 2)
+                       continue;
+
+               if (i - 1 >= f2->argv->size)
+                       continue;
+
+               v1 = f2->argv->data[i - 1];
+               if (!v1->auto_gc_flag)
+                       continue;
+
+               scf_logd("f2: %s, v0: %s, v1: %s\n", f2->node.w->text->data, v0->w->text->data, v1->w->text->data);
+
+               ds_obj = NULL;
+               if (SCF_OP_ADDRESS_OF == dn->type)
+
+                       ret = scf_ds_for_dn(&ds_obj, dn->childs->data[0]);
+               else
+                       ret = scf_ds_for_dn(&ds_obj, dn);
+               if (ret < 0)
+                       return ret;
+
+               if (ds_obj->dag_node->var->arg_flag)
+                       ds_obj->ret = 1;
+
+               if (scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node) < 0) {
+
+                       scf_dn_status_free(ds_obj);
+                       ds_obj = NULL;
+                       return -ENOMEM;
+               }
+
+               ret = _bb_add_ds_for_call(cur_bb, ds_obj, f2, v1);
+
+               scf_dn_status_free(ds_obj);
+               ds_obj = NULL;
+               if (ret < 0)
+                       return ret;
+
+               count++;
+       }
+
+       return count;
+}
+
+static int _auto_gc_find_argv_in(scf_basic_block_t* cur_bb, scf_3ac_code_t* c)
+{
+       scf_3ac_operand_t* src;
+       scf_dag_node_t*    dn;
+       scf_variable_t*    v;
+
+       int i;
+
+       for (i  = 1; i < c->srcs->size; i++) {
+               src =        c->srcs->data[i];
+
+               dn  = src->dag_node;
+
+               while (dn) {
+                       if (SCF_OP_TYPE_CAST == dn->type)
+                               dn = dn->childs->data[0];
+
+                       else if (SCF_OP_EXPR == dn->type)
+                               dn = dn->childs->data[0];
+
+                       else if (SCF_OP_POINTER == dn->type)
+                               dn = dn->childs->data[0];
+                       else
+                               break;
+               }
+
+               v = dn->var;
+
+               if (v->nb_pointers + v->nb_dimentions + (v->type >= SCF_STRUCT) < 2)
+                       continue;
+
+               scf_logw("v: %s\n", v->w->text->data);
+
+               if (scf_vector_add_unique(cur_bb->dn_reloads, dn) < 0)
+                       return -ENOMEM;
+       }
+
+       return 0;
+}
+
+static int _auto_gc_find_ret(scf_basic_block_t* cur_bb, scf_3ac_code_t* c)
+{
+       assert(c->srcs->size > 0);
+
+       scf_3ac_operand_t* dst;
+       scf_3ac_operand_t* src = c->srcs->data[0];
+       scf_function_t*    f2  = src->dag_node->var->func_ptr;
+       scf_variable_t*    ret = f2->rets->data[0];
+       scf_variable_t*    v;
+       scf_dn_status_t*   ds_obj;
+
+       if (ret->auto_gc_flag) {
+               dst = c->dsts->data[0];
+               v   = dst->dag_node->var;
+
+               if (!scf_variable_may_malloced(v))
+                       return 0;
+
+               ds_obj = scf_dn_status_alloc(dst->dag_node);
+               if (!ds_obj)
+                       return -ENOMEM;
+
+               _bb_add_ds(cur_bb, ds_obj);
+       }
+
+       return 0;
+}
+
 static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f)
 {
        scf_list_t*     l;
@@ -427,7 +580,6 @@ static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f)
                scf_3ac_operand_t* src;
                scf_dn_status_t*   ds_obj;
                scf_dn_status_t*   ds;
-               scf_dn_status_t*   ds2;
                scf_dag_node_t*    dn;
                scf_variable_t*    v0;
 
@@ -535,85 +687,20 @@ static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f)
 
                        scf_dag_node_t* dn_pf = src->dag_node;
                        scf_function_t* f2    = dn_pf->var->func_ptr;
-                       scf_variable_t* ret   = f2->rets->data[0];
-
-                       int i;
-                       for (i  = 1; i < c->srcs->size; i++) {
 
-                               src = c->srcs->data[i];
-                               dn  = src->dag_node;
-                               v0  = dn->var;
-
-                               while (dn) {
-                                       if (SCF_OP_TYPE_CAST == dn->type)
-                                               dn = dn->childs->data[0];
-
-                                       else if (SCF_OP_EXPR == dn->type)
-                                               dn = dn->childs->data[0];
-                                       else
-                                               break;
-                               }
-
-                               if (v0->nb_pointers + v0->nb_dimentions + (v0->type >= SCF_STRUCT) < 2) {
-                                       continue;
-                               }
-
-                               if (i - 1 >= f2->argv->size)
-                                       continue;
-
-                               scf_variable_t* v1 = f2->argv->data[i - 1];
-
-                               scf_logw("f2: %s, v0: %s, v1: %s\n",
-                                               f2->node.w->text->data, v0->w->text->data, v1->w->text->data);
-
-                               if (!v1->auto_gc_flag)
-                                       continue;
-
-                               ds_obj  = NULL;
-
-                               int ret;
-                               if (SCF_OP_ADDRESS_OF == dn->type)
-
-                                       ret = scf_ds_for_dn(&ds_obj, dn->childs->data[0]);
-                               else
-                                       ret = scf_ds_for_dn(&ds_obj, dn);
-
-                               if (ret < 0)
-                                       return ret;
-
-                               if (ds_obj->dag_node->var->arg_flag)
-                                       ds_obj->ret = 1;
-
-                               if (scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node) < 0) {
-
-                                       scf_dn_status_free(ds_obj);
-                                       ds_obj = NULL;
-                                       return -ENOMEM;
-                               }
-
-                               ret = _bb_add_ds_for_call(cur_bb, ds_obj, f2, v1);
-
-                               scf_dn_status_free(ds_obj);
-                               ds_obj = NULL;
-                               if (ret < 0)
-                                       return ret;
-
-                               count++;
-                       }
-
-                       if (ret->auto_gc_flag) {
-                               dst = c->dsts->data[0];
-                               v0  = dst->dag_node->var;
+                       int ret = _auto_gc_find_argv_out(cur_bb, c);
+                       if (ret < 0)
+                               return ret;
+                       count += ret;
 
-                               if (!scf_variable_may_malloced(v0))
-                                       goto _end;
+                       ret = _auto_gc_find_argv_in(cur_bb, c);
+                       if (ret < 0)
+                               return ret;
 
-                               ds_obj = scf_dn_status_alloc(dst->dag_node);
-                               if (!ds_obj)
-                                       return -ENOMEM;
+                       ret = _auto_gc_find_ret(cur_bb, c);
+                       if (ret < 0)
+                               return ret;
 
-                               _bb_add_ds(cur_bb, ds_obj);
-                       }
                        goto _end;
                } else
                        goto _end;
diff --git a/examples/str.c b/examples/str.c
new file mode 100644 (file)
index 0000000..f204d72
--- /dev/null
@@ -0,0 +1,42 @@
+
+include "../lib/scf_capi.c";
+
+struct str
+{
+       uint8_t* data;
+       int      len;
+       int      capacity;
+
+       int __init(str* this)
+       {
+               this->len      = 0;
+               this->capacity = 16;
+
+               this->data = scf__auto_malloc(16);
+               if (!this->data)
+                       return -1;
+
+               strncpy(this->data, "hello", 5);
+               return 0;
+       }
+
+       void __release(str* this)
+       {
+               if (this->data)
+                       scf__auto_freep(&this->data, NULL);
+       }
+};
+
+
+int main()
+{
+       str* p0;
+       str* p1;
+       int  i;
+
+       p0 = create str();
+
+       printf("%s\n", p0->data);
+       return 0;
+}
+