make auto gc module more clearly, move some repeated into a function
authoryu.dongliang <18588496441@163.com>
Thu, 10 Oct 2024 14:25:59 +0000 (22:25 +0800)
committeryu.dongliang <18588496441@163.com>
Thu, 10 Oct 2024 14:25:59 +0000 (22:25 +0800)
core/scf_auto_gc_3ac.c [new file with mode: 0644]
core/scf_auto_gc_find.c [new file with mode: 0644]
core/scf_basic_block.c
core/scf_basic_block.h
core/scf_optimizer_auto_gc.c
core/scf_optimizer_auto_gc_find.c
core/scf_optimizer_call.c
core/scf_optimizer_dominators.c
core/scf_optimizer_loop.c
core/scf_optimizer_pointer_alias.c
core/scf_pointer_alias.c

diff --git a/core/scf_auto_gc_3ac.c b/core/scf_auto_gc_3ac.c
new file mode 100644 (file)
index 0000000..ca34c27
--- /dev/null
@@ -0,0 +1,1130 @@
+#include"scf_optimizer.h"
+#include"scf_pointer_alias.h"
+
+static scf_3ac_operand_t* _auto_gc_operand_alloc_pf(scf_list_t* dag_list_head, scf_ast_t* ast, scf_function_t* f)
+{
+       scf_3ac_operand_t* src;
+       scf_dag_node_t*    dn;
+       scf_variable_t*    v;
+       scf_type_t*        t = NULL;
+
+       int ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR);
+       assert(0 == ret);
+       assert(t);
+
+       if (f)
+               v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
+       else
+               v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 1, 1, NULL);
+
+       if (!v)
+               return NULL;
+       v->const_literal_flag = 1;
+
+       dn = scf_dag_node_alloc(v->type, v, (scf_node_t*)f);
+
+       scf_variable_free(v);
+       v = NULL;
+       if (!dn)
+               return NULL;
+
+       src = scf_3ac_operand_alloc();
+       if (!src) {
+               scf_dag_node_free(dn);
+               return NULL;
+       }
+
+       src->node     = (scf_node_t*)f;
+       src->dag_node = dn;
+
+       scf_list_add_tail(dag_list_head, &dn->list);
+       return src;
+}
+
+static scf_3ac_code_t* _auto_gc_code_ref(scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn)
+{
+       scf_3ac_operand_t* src;
+       scf_3ac_code_t*    c;
+       scf_function_t*    f = NULL;
+       scf_variable_t*    v;
+       scf_type_t*        t;
+
+       int ret = scf_ast_find_function(&f, ast, "scf__auto_ref");
+       if (!f)
+               return NULL;
+
+       c = scf_3ac_code_alloc();
+       if (!c)
+               return NULL;
+
+       c->srcs = scf_vector_alloc();
+       if (!c->srcs) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       c->op = scf_3ac_find_operator(SCF_OP_CALL);
+
+#define AUTO_GC_CODE_ADD_FUNCPTR() \
+       do { \
+               src = _auto_gc_operand_alloc_pf(dag_list_head, ast, f); \
+               if (!src) { \
+                       scf_3ac_code_free(c); \
+                       return NULL; \
+               } \
+               \
+               if (scf_vector_add(c->srcs, src) < 0) { \
+                       scf_3ac_operand_free(src); \
+                       scf_3ac_code_free(c); \
+                       return NULL; \
+               } \
+       } while (0)
+
+       AUTO_GC_CODE_ADD_FUNCPTR();
+
+#define AUTO_GC_CODE_ADD_DN() \
+       do { \
+               src = scf_3ac_operand_alloc(); \
+               if (!src) { \
+                       scf_3ac_code_free(c); \
+                       return NULL; \
+               } \
+               src->node     = dn->node; \
+               src->dag_node = dn; \
+               \
+               if (scf_vector_add(c->srcs, src) < 0) { \
+                       scf_3ac_operand_free(src); \
+                       scf_3ac_code_free(c); \
+                       return NULL; \
+               } \
+       } while (0)
+
+       AUTO_GC_CODE_ADD_DN();
+
+       return c;
+}
+
+static scf_3ac_code_t* _auto_gc_code_memset_array(scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn_array)
+{
+       scf_3ac_operand_t* src;
+       scf_3ac_code_t*    c;
+       scf_dag_node_t*    dn;
+       scf_function_t*    f;
+       scf_variable_t*    v;
+       scf_type_t*        t = NULL;
+
+       int ret = scf_ast_find_type_type(&t, ast, SCF_VAR_INTPTR);
+       assert(0 == ret);
+       assert(t);
+
+       c = scf_3ac_code_alloc();
+       if (!c)
+               return NULL;
+
+       c->srcs = scf_vector_alloc();
+       if (!c->srcs) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       c->op = scf_3ac_find_operator(SCF_OP_3AC_MEMSET);
+
+       dn = dn_array;
+       AUTO_GC_CODE_ADD_DN();
+
+#define AUTO_GC_CODE_ADD_VAR() \
+       do { \
+               dn = scf_dag_node_alloc(v->type, v, NULL); \
+               \
+               scf_variable_free(v); \
+               v = NULL; \
+               \
+               if (!dn) { \
+                       scf_3ac_code_free(c); \
+                       return NULL; \
+               } \
+               src = scf_3ac_operand_alloc(); \
+               if (!src) { \
+                       scf_dag_node_free(dn); \
+                       scf_3ac_code_free(c); \
+                       return NULL; \
+               } \
+               \
+               if (scf_vector_add(c->srcs, src) < 0) { \
+                       scf_3ac_operand_free(src); \
+                       scf_dag_node_free(dn); \
+                       scf_3ac_code_free(c); \
+                       return NULL; \
+               } \
+               \
+               src->node     = dn->node; \
+               src->dag_node = dn; \
+               scf_list_add_tail(dag_list_head, &dn->list); \
+       } while (0)
+
+       v = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       v->data.i64 = 0;
+       AUTO_GC_CODE_ADD_VAR();
+
+       v = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       v->data.i64 = scf_variable_size(dn_array->var);
+       AUTO_GC_CODE_ADD_VAR();
+
+       return c;
+}
+
+static scf_3ac_code_t* _auto_gc_code_free_array(scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn_array, int capacity, int nb_pointers)
+{
+       scf_3ac_operand_t* src;
+       scf_3ac_code_t*    c;
+       scf_dag_node_t*    dn;
+       scf_function_t*    f = NULL;
+       scf_variable_t*    v;
+       scf_type_t*        t;
+
+       int ret = scf_ast_find_function(&f, ast, "scf__auto_free_array");
+       if (!f)
+               return NULL;
+
+       c = scf_3ac_code_alloc();
+       if (!c)
+               return NULL;
+
+       c->srcs = scf_vector_alloc();
+       if (!c->srcs) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       c->op = scf_3ac_find_operator(SCF_OP_CALL);
+
+       AUTO_GC_CODE_ADD_FUNCPTR();
+
+       dn = dn_array;
+       AUTO_GC_CODE_ADD_DN();
+
+       t = scf_block_find_type_type(ast->current_block, SCF_VAR_INTPTR);
+       v = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       v->data.i64 = capacity;
+       AUTO_GC_CODE_ADD_VAR();
+
+       v = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       v->data.i64 = nb_pointers;
+       AUTO_GC_CODE_ADD_VAR();
+
+       if (dn_array->var->type >= SCF_STRUCT) {
+               t   = NULL;
+               ret = scf_ast_find_type_type(&t, ast, dn_array->var->type);
+               assert(0 == ret);
+               assert(t);
+
+               f = scf_scope_find_function(t->scope, "__release");
+       } else
+               f = NULL;
+       AUTO_GC_CODE_ADD_FUNCPTR();
+
+       return c;
+}
+
+static scf_3ac_code_t* _auto_gc_code_freep_array(scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn_array, int nb_pointers)
+{
+       scf_3ac_operand_t* src;
+       scf_3ac_code_t*    c;
+       scf_dag_node_t*    dn;
+       scf_function_t*    f = NULL;
+       scf_variable_t*    v;
+       scf_type_t*        t;
+
+       int ret = scf_ast_find_function(&f, ast, "scf__auto_freep_array");
+       if (!f)
+               return NULL;
+
+       c = scf_3ac_code_alloc();
+       if (!c)
+               return NULL;
+
+       c->srcs = scf_vector_alloc();
+       if (!c->srcs) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       c->op = scf_3ac_find_operator(SCF_OP_CALL);
+
+       AUTO_GC_CODE_ADD_FUNCPTR();
+
+       dn = dn_array;
+       AUTO_GC_CODE_ADD_DN();
+
+       t   = NULL;
+       ret = scf_ast_find_type_type(&t, ast, SCF_VAR_INTPTR);
+       assert(0 == ret);
+       assert(t);
+       v = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       v->data.i64 = nb_pointers;
+
+       char buf[128];
+       snprintf(buf, sizeof(buf) - 1, "%d", nb_pointers);
+
+       if (scf_string_cat_cstr(v->w->text, buf) < 0) {
+               scf_variable_free(v);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       AUTO_GC_CODE_ADD_VAR();
+
+       if (dn_array->var->type >= SCF_STRUCT) {
+               t   = NULL;
+               ret = scf_ast_find_type_type(&t, ast, dn_array->var->type);
+               assert(0 == ret);
+               assert(t);
+
+               f = scf_scope_find_function(t->scope, "__release");
+       } else
+               f = NULL;
+       AUTO_GC_CODE_ADD_FUNCPTR();
+
+       return c;
+}
+
+static scf_3ac_code_t* _code_alloc_address(scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn)
+{
+       scf_3ac_operand_t*  src;
+       scf_3ac_operand_t*  dst;
+       scf_3ac_code_t*     c;
+       scf_variable_t*     v;
+       scf_lex_word_t*     w;
+       scf_string_t*       s;
+       scf_type_t*         t = NULL;
+
+       c = scf_3ac_code_alloc();
+       if (!c)
+               return NULL;
+
+       c->srcs = scf_vector_alloc();
+       if (!c->srcs) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       c->dsts = scf_vector_alloc();
+       if (!c->dsts) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       src = scf_3ac_operand_alloc();
+       if (!src) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       if (scf_vector_add(c->srcs, src) < 0) {
+               scf_3ac_operand_free(src);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       src->node     = dn->node;
+       src->dag_node = dn;
+
+       dst = scf_3ac_operand_alloc();
+       if (!dst) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       if (scf_vector_add(c->dsts, dst) < 0) {
+               scf_3ac_operand_free(dst);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       c->op = scf_3ac_find_operator(SCF_OP_ADDRESS_OF);
+
+       w = scf_lex_word_alloc(dn->var->w->file, 0, 0, SCF_LEX_WORD_ID);
+       if (!w) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       w->text = scf_string_cstr("&");
+       if (!w->text) {
+               scf_lex_word_free(w);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       int ret = scf_ast_find_type_type(&t, ast, dn->var->type);
+       assert(0 == ret);
+       assert(t);
+
+       v = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn->var->nb_pointers + 1, NULL);
+       scf_lex_word_free(w);
+       w = NULL;
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       dst->dag_node = scf_dag_node_alloc(v->type, v, NULL);
+       scf_variable_free(v);
+       v = NULL;
+       if (!dst->dag_node) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       scf_list_add_tail(dag_list_head, &dst->dag_node->list);
+       return c;
+}
+
+static scf_3ac_code_t* _code_alloc_dereference(scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn)
+{
+       scf_3ac_operand_t*  src;
+       scf_3ac_operand_t*  dst;
+       scf_3ac_code_t*     c;
+       scf_variable_t*     v;
+       scf_lex_word_t*     w;
+       scf_string_t*       s;
+       scf_type_t*         t = NULL;
+
+       c = scf_3ac_code_alloc();
+       if (!c)
+               return NULL;
+
+       c->srcs = scf_vector_alloc();
+       if (!c->srcs) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       c->dsts = scf_vector_alloc();
+       if (!c->dsts) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       src = scf_3ac_operand_alloc();
+       if (!src) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       if (scf_vector_add(c->srcs, src) < 0) {
+               scf_3ac_operand_free(src);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       src->node     = dn->node;
+       src->dag_node = dn;
+
+       dst = scf_3ac_operand_alloc();
+       if (!dst) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       if (scf_vector_add(c->dsts, dst) < 0) {
+               scf_3ac_operand_free(dst);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       c->op = scf_3ac_find_operator(SCF_OP_DEREFERENCE);
+
+       w = scf_lex_word_alloc(dn->var->w->file, 0, 0, SCF_LEX_WORD_ID);
+       if (!w) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       w->text = scf_string_cstr("*");
+       if (!w->text) {
+               scf_lex_word_free(w);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       int ret = scf_ast_find_type_type(&t, ast, dn->var->type);
+       assert(0 == ret);
+       assert(t);
+
+       v = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn->var->nb_pointers - 1, NULL);
+       scf_lex_word_free(w);
+       w = NULL;
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       dst->dag_node = scf_dag_node_alloc(v->type, v, NULL);
+       scf_variable_free(v);
+       v = NULL;
+       if (!dst->dag_node) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       scf_list_add_tail(dag_list_head, &dst->dag_node->list);
+       return c;
+}
+
+static scf_3ac_code_t* _code_alloc_member(scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn_base, scf_dag_node_t* dn_member)
+{
+       scf_3ac_operand_t*  base;
+       scf_3ac_operand_t*  member;
+       scf_3ac_operand_t*  dst;
+       scf_3ac_code_t*     c;
+       scf_variable_t*     v;
+       scf_lex_word_t*     w;
+       scf_string_t*       s;
+       scf_type_t*         t = NULL;
+
+       c = scf_3ac_code_alloc();
+       if (!c)
+               return NULL;
+
+       c->srcs = scf_vector_alloc();
+       if (!c->srcs) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       c->dsts = scf_vector_alloc();
+       if (!c->dsts) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       base = scf_3ac_operand_alloc();
+       if (!base) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       if (scf_vector_add(c->srcs, base) < 0) {
+               scf_3ac_operand_free(base);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       base->node     = dn_base->node;
+       base->dag_node = dn_base;
+
+       member = scf_3ac_operand_alloc();
+       if (!member) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       if (scf_vector_add(c->srcs, member) < 0) {
+               scf_3ac_operand_free(member);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       member->node     = dn_member->node;
+       member->dag_node = dn_member;
+
+       dst = scf_3ac_operand_alloc();
+       if (!dst) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       if (scf_vector_add(c->dsts, dst) < 0) {
+               scf_3ac_operand_free(dst);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       c->op = scf_3ac_find_operator(SCF_OP_POINTER);
+
+       w = scf_lex_word_alloc(dn_base->var->w->file, 0, 0, SCF_LEX_WORD_ID);
+       if (!w) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       w->text = scf_string_cstr("->");
+       if (!w->text) {
+               scf_lex_word_free(w);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       int ret = scf_ast_find_type_type(&t, ast, dn_member->var->type);
+       assert(0 == ret);
+       assert(t);
+
+       v = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn_member->var->nb_pointers, NULL);
+       scf_lex_word_free(w);
+       w = NULL;
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       dst->dag_node = scf_dag_node_alloc(v->type, v, NULL);
+       scf_variable_free(v);
+       v = NULL;
+       if (!dst->dag_node) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       scf_list_add_tail(dag_list_head, &dst->dag_node->list);
+       return c;
+}
+
+static scf_3ac_code_t* _code_alloc_member_address(scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn_base, scf_dag_node_t* dn_member)
+{
+       scf_3ac_operand_t*  base;
+       scf_3ac_operand_t*  member;
+       scf_3ac_operand_t*  dst;
+       scf_3ac_code_t*     c;
+       scf_variable_t*     v;
+       scf_lex_word_t*     w;
+       scf_string_t*       s;
+       scf_type_t*         t = NULL;
+
+       c = scf_3ac_code_alloc();
+       if (!c)
+               return NULL;
+
+       c->srcs = scf_vector_alloc();
+       if (!c->srcs) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       c->dsts = scf_vector_alloc();
+       if (!c->dsts) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       base = scf_3ac_operand_alloc();
+       if (!base) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       if (scf_vector_add(c->srcs, base) < 0) {
+               scf_3ac_operand_free(base);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       base->node     = dn_base->node;
+       base->dag_node = dn_base;
+
+       member = scf_3ac_operand_alloc();
+       if (!member) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       if (scf_vector_add(c->srcs, member) < 0) {
+               scf_3ac_operand_free(member);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       member->node     = dn_member->node;
+       member->dag_node = dn_member;
+
+       dst = scf_3ac_operand_alloc();
+       if (!dst) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       if (scf_vector_add(c->dsts, dst) < 0) {
+               scf_3ac_operand_free(dst);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       c->op = scf_3ac_find_operator(SCF_OP_3AC_ADDRESS_OF_POINTER);
+
+       w = scf_lex_word_alloc(dn_base->var->w->file, 0, 0, SCF_LEX_WORD_ID);
+       if (!w) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       w->text = scf_string_cstr("&->");
+       if (!w->text) {
+               scf_lex_word_free(w);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       int ret = scf_ast_find_type_type(&t, ast, dn_member->var->type);
+       assert(0 == ret);
+       assert(t);
+
+       v = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn_member->var->nb_pointers + 1, NULL);
+       scf_lex_word_free(w);
+       w = NULL;
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       dst->dag_node = scf_dag_node_alloc(v->type, v, NULL);
+       scf_variable_free(v);
+       v = NULL;
+       if (!dst->dag_node) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       dst->dag_node->var->nb_dimentions = dn_base->var->nb_dimentions;
+
+       scf_list_add_tail(dag_list_head, &dst->dag_node->list);
+       return c;
+}
+
+static scf_3ac_code_t* _code_alloc_array_member_address(scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn_base, scf_dag_node_t* dn_index, scf_dag_node_t* dn_scale)
+{
+       scf_3ac_operand_t*  base;
+       scf_3ac_operand_t*  index;
+       scf_3ac_operand_t*  scale;
+       scf_3ac_operand_t*  dst;
+       scf_3ac_code_t*     c;
+       scf_variable_t*     v;
+       scf_lex_word_t*     w;
+       scf_string_t*       s;
+       scf_type_t*         t = NULL;
+
+       c = scf_3ac_code_alloc();
+       if (!c)
+               return NULL;
+
+       c->srcs = scf_vector_alloc();
+       if (!c->srcs) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       c->dsts = scf_vector_alloc();
+       if (!c->dsts) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       base = scf_3ac_operand_alloc();
+       if (!base) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       if (scf_vector_add(c->srcs, base) < 0) {
+               scf_3ac_operand_free(base);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       base->node     = dn_base->node;
+       base->dag_node = dn_base;
+
+       index = scf_3ac_operand_alloc();
+       if (!index) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       if (scf_vector_add(c->srcs, index) < 0) {
+               scf_3ac_operand_free(index);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       index->node     = dn_index->node;
+       index->dag_node = dn_index;
+
+       scale = scf_3ac_operand_alloc();
+       if (!scale) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       if (scf_vector_add(c->srcs, scale) < 0) {
+               scf_3ac_operand_free(scale);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       scale->node      = dn_scale->node;
+       scale->dag_node  = dn_scale;
+
+       dst = scf_3ac_operand_alloc();
+       if (!dst) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       if (scf_vector_add(c->dsts, dst) < 0) {
+               scf_3ac_operand_free(dst);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       c->op = scf_3ac_find_operator(SCF_OP_3AC_ADDRESS_OF_ARRAY_INDEX);
+
+       w = scf_lex_word_alloc(dn_base->var->w->file, 0, 0, SCF_LEX_WORD_ID);
+       if (!w) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       w->text = scf_string_cstr("&[]");
+       if (!w->text) {
+               scf_lex_word_free(w);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       int ret = scf_ast_find_type_type(&t, ast, dn_base->var->type);
+       assert(0 == ret);
+       assert(t);
+
+       v = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn_base->var->nb_pointers, NULL);
+       scf_lex_word_free(w);
+       w = NULL;
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       dst->dag_node = scf_dag_node_alloc(v->type, v, NULL);
+       scf_variable_free(v);
+       v = NULL;
+       if (!dst->dag_node) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       dst->dag_node->var->nb_dimentions = dn_base->var->nb_dimentions;
+
+       scf_list_add_tail(dag_list_head, &dst->dag_node->list);
+       return c;
+}
+
+static scf_3ac_code_t* _code_alloc_array_member(scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn_base, scf_dag_node_t* dn_index, scf_dag_node_t* dn_scale)
+{
+       scf_3ac_operand_t*  base;
+       scf_3ac_operand_t*  index;
+       scf_3ac_operand_t*  scale;
+       scf_3ac_operand_t*  dst;
+       scf_3ac_code_t*     c;
+       scf_variable_t*     v;
+       scf_lex_word_t*     w;
+       scf_string_t*       s;
+       scf_type_t*         t = NULL;
+
+       c = scf_3ac_code_alloc();
+       if (!c)
+               return NULL;
+
+       c->srcs = scf_vector_alloc();
+       if (!c->srcs) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       c->dsts = scf_vector_alloc();
+       if (!c->dsts) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       base = scf_3ac_operand_alloc();
+       if (!base) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       if (scf_vector_add(c->srcs, base) < 0) {
+               scf_3ac_operand_free(base);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       base->node     = dn_base->node;
+       base->dag_node = dn_base;
+
+       index = scf_3ac_operand_alloc();
+       if (!index) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       if (scf_vector_add(c->srcs, index) < 0) {
+               scf_3ac_operand_free(index);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       index->node     = dn_index->node;
+       index->dag_node = dn_index;
+
+       scale = scf_3ac_operand_alloc();
+       if (!scale) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       if (scf_vector_add(c->srcs, scale) < 0) {
+               scf_3ac_operand_free(scale);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       scale->node      = dn_scale->node;
+       scale->dag_node  = dn_scale;
+
+       dst = scf_3ac_operand_alloc();
+       if (!dst) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       if (scf_vector_add(c->dsts, dst) < 0) {
+               scf_3ac_operand_free(dst);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+       c->op = scf_3ac_find_operator(SCF_OP_ARRAY_INDEX);
+
+       w = scf_lex_word_alloc(dn_base->var->w->file, 0, 0, SCF_LEX_WORD_ID);
+       if (!w) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       w->text = scf_string_cstr("[]");
+       if (!w->text) {
+               scf_lex_word_free(w);
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       int ret = scf_ast_find_type_type(&t, ast, dn_base->var->type);
+       assert(0 == ret);
+       assert(t);
+
+       v = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn_base->var->nb_pointers, NULL);
+       scf_lex_word_free(w);
+       w = NULL;
+       if (!v) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       dst->dag_node = scf_dag_node_alloc(v->type, v, NULL);
+       scf_variable_free(v);
+       v = NULL;
+       if (!dst->dag_node) {
+               scf_3ac_code_free(c);
+               return NULL;
+       }
+
+       dst->dag_node->var->nb_dimentions = dn_base->var->nb_dimentions;
+
+       scf_list_add_tail(dag_list_head, &dst->dag_node->list);
+       return c;
+}
+
+static int _auto_gc_code_list_ref(scf_list_t* h, scf_list_t* dag_list_head, scf_ast_t* ast, scf_dn_status_t* ds)
+{
+       scf_dag_node_t*    dn = ds->dag_node;
+       scf_3ac_code_t*    c;
+       scf_3ac_operand_t* dst;
+
+       if (ds->dn_indexes) {
+
+               int i;
+               for (i = ds->dn_indexes->size - 1; i >= 0; i--) {
+
+                       scf_dn_index_t* di = ds->dn_indexes->data[i];
+
+                       if (di->member) {
+                               assert(di->dn);
+
+                               c = _code_alloc_member(dag_list_head, ast, dn, di->dn);
+
+                       } else {
+                               assert(di->index >= 0 || -1 == di->index);
+                               assert(di->dn_scale);
+
+                               c = _code_alloc_array_member(dag_list_head, ast, dn, di->dn, di->dn_scale);
+                       }
+
+                       scf_list_add_tail(h, &c->list);
+
+                       dst = c->dsts->data[0];
+                       dn  = dst->dag_node;
+               }
+       }
+
+       c = _auto_gc_code_ref(dag_list_head, ast, dn);
+
+       scf_list_add_tail(h, &c->list);
+       return 0;
+}
+
+static int _auto_gc_code_list_freep(scf_list_t* h, scf_list_t* dag_list_head, scf_ast_t* ast, scf_dn_status_t* ds)
+{
+       scf_dag_node_t*    dn = ds->dag_node;
+       scf_3ac_code_t*    c;
+       scf_3ac_operand_t* dst;
+
+       if (ds->dn_indexes) {
+
+               scf_dn_index_t* di;
+               int i;
+
+               for (i = ds->dn_indexes->size - 1; i >= 1; i--) {
+                       di = ds->dn_indexes->data[i];
+
+                       if (di->member) {
+                               assert(di->dn);
+
+                               c = _code_alloc_member(dag_list_head, ast, dn, di->dn);
+
+                       } else {
+                               assert(di->index >= 0);
+
+                               assert(0 == di->index);
+
+                               c = _code_alloc_dereference(dag_list_head, ast, dn);
+                       }
+
+                       scf_list_add_tail(h, &c->list);
+
+                       dst = c->dsts->data[0];
+                       dn  = dst->dag_node;
+               }
+
+               di = ds->dn_indexes->data[0];
+
+               if (di->member) {
+                       assert(di->dn);
+
+                       c = _code_alloc_member_address(dag_list_head, ast, dn, di->dn);
+
+               } else {
+                       assert(di->index >= 0 || -1 == di->index);
+                       assert(di->dn_scale);
+
+                       c = _code_alloc_array_member_address(dag_list_head, ast, dn, di->dn, di->dn_scale);
+               }
+
+               scf_list_add_tail(h, &c->list);
+
+               dst = c->dsts->data[0];
+               dn  = dst->dag_node;
+
+       } else {
+               c = _code_alloc_address(dag_list_head, ast, dn);
+
+               scf_list_add_tail(h, &c->list);
+
+               dst = c->dsts->data[0];
+               dn  = dst->dag_node;
+       }
+
+       int nb_pointers = scf_variable_nb_pointers(dn->var);
+
+       assert(nb_pointers >= 2);
+
+       c = _auto_gc_code_freep_array(dag_list_head, ast, dn, nb_pointers - 1);
+
+       scf_list_add_tail(h, &c->list);
+       return 0;
+}
+
+static int _auto_gc_code_list_free_array(scf_list_t* h, scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn_array)
+{
+       scf_3ac_code_t* c;
+
+       assert(dn_array->var->nb_dimentions > 0);
+       assert(dn_array->var->capacity      > 0);
+
+       c = _auto_gc_code_free_array(dag_list_head, ast, dn_array, dn_array->var->capacity, dn_array->var->nb_pointers);
+
+       scf_list_add_tail(h, &c->list);
+       return 0;
+}
+
+static int _auto_gc_code_list_memset_array(scf_list_t* h, scf_list_t* dag_list_head, scf_ast_t* ast, scf_dag_node_t* dn_array)
+{
+       scf_3ac_code_t*    c;
+
+       assert(dn_array->var->capacity > 0);
+
+       c = _auto_gc_code_memset_array(dag_list_head, ast, dn_array);
+
+       scf_list_add_tail(h, &c->list);
+       return 0;
+}
+
+static int _bb_add_gc_code_ref(scf_list_t* dag_list_head, scf_ast_t* ast, scf_basic_block_t* bb, scf_dn_status_t* ds)
+{
+       scf_list_t     h;
+       scf_list_init(&h);
+
+       if (scf_vector_add_unique(bb->dn_reloads, ds->dag_node) < 0)
+               return -ENOMEM;
+
+       int ret = _auto_gc_code_list_ref(&h, dag_list_head, ast, ds);
+       if (ret < 0)
+               return ret;
+
+       scf_basic_block_add_code(bb, &h);
+       return 0;
+}
+
+static int _bb_add_gc_code_freep(scf_list_t* dag_list_head, scf_ast_t* ast, scf_basic_block_t* bb, scf_dn_status_t* ds)
+{
+       scf_list_t     h;
+       scf_list_init(&h);
+
+       if (scf_vector_add_unique(bb->dn_reloads, ds->dag_node) < 0)
+               return -ENOMEM;
+
+       int ret = _auto_gc_code_list_freep(&h, dag_list_head, ast, ds);
+       if (ret < 0)
+               return ret;
+
+       scf_basic_block_add_code(bb, &h);
+       return 0;
+}
+
+static int _bb_add_gc_code_memset_array(scf_list_t* dag_list_head, scf_ast_t* ast, scf_basic_block_t* bb, scf_dag_node_t* dn_array)
+{
+       scf_list_t     h;
+       scf_list_init(&h);
+
+       if (scf_vector_add_unique(bb->dn_reloads, dn_array) < 0)
+               return -ENOMEM;
+
+       int ret = _auto_gc_code_list_memset_array(&h, dag_list_head, ast, dn_array);
+       if (ret < 0)
+               return ret;
+
+       scf_basic_block_add_code(bb, &h);
+       return 0;
+}
+
+static int _bb_add_gc_code_free_array(scf_list_t* dag_list_head, scf_ast_t* ast, scf_basic_block_t* bb, scf_dag_node_t* dn_array)
+{
+       scf_list_t     h;
+       scf_list_init(&h);
+
+       if (scf_vector_add_unique(bb->dn_reloads, dn_array) < 0)
+               return -ENOMEM;
+
+       int ret = _auto_gc_code_list_free_array(&h, dag_list_head, ast, dn_array);
+       if (ret < 0)
+               return ret;
+
+       scf_basic_block_add_code(bb, &h);
+       return 0;
+}
diff --git a/core/scf_auto_gc_find.c b/core/scf_auto_gc_find.c
new file mode 100644 (file)
index 0000000..8e8d595
--- /dev/null
@@ -0,0 +1,303 @@
+#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_ds_cmp_same_indexes))
+               return 0;
+
+       if (scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_ds_cmp_same_indexes))
+               return 1;
+       return 0;
+}
+
+static int __ds_append_index_n(scf_dn_status_t* dst, scf_dn_status_t* src, int n)
+{
+       scf_dn_index_t* di;
+       int j;
+
+       assert(n <= src->dn_indexes->size);
+
+       for (j = 0; j < n; j++) {
+               di = src->dn_indexes->data[j];
+
+               int ret = scf_vector_add_front(dst->dn_indexes, di);
+               if (ret < 0)
+                       return ret;
+               di->refs++;
+       }
+
+       return 0;
+}
+
+int __bb_find_ds_alias(scf_vector_t* aliases, scf_dn_status_t* ds_obj, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+{
+       scf_vector_t*    tmp;
+       scf_dn_status_t* ds2;
+       scf_dn_status_t* ds;
+       scf_dn_index_t*  di;
+       scf_3ac_code_t*  c2 = scf_list_data(scf_list_prev(&c->list), scf_3ac_code_t, list);
+
+       int ndi = 0;
+       int ret = 0;
+       int j;
+
+       tmp = scf_vector_alloc();
+       if (!tmp)
+               return -ENOMEM;
+
+       ds = scf_dn_status_clone(ds_obj);
+       if (!ds) {
+               scf_vector_free(tmp);
+               return -ENOMEM;
+       }
+
+       while (1) {
+               ret = scf_pointer_alias_ds(tmp, ds, c2, bb, bb_list_head);
+               if (ret < 0) {
+                       if (SCF_POINTER_NOT_INIT == ret)
+                               break;
+                       goto error;
+               }
+
+               for (j = 0; j < tmp->size; j++) {
+                       ds2       = tmp->data[j];
+
+                       SCF_XCHG(ds2->dn_indexes, ds2->alias_indexes);
+                       SCF_XCHG(ds2->dag_node,   ds2->alias);
+
+                       if (ds_obj->dn_indexes) {
+
+                               if (!ds2->dn_indexes) {
+                                       ds2 ->dn_indexes = scf_vector_alloc();
+                                       if (!ds2->dn_indexes) {
+                                               ret = -ENOMEM;
+                                               goto error;
+                                       }
+                               }
+
+                               ret = __ds_append_index_n(ds2, ds_obj, ndi);
+                               if (ret < 0)
+                                       goto error;
+                       }
+
+                       ret = scf_vector_add(aliases, ds2);
+                       if (ret < 0)
+                               goto error;
+
+                       scf_dn_status_ref(ds2);
+                       ds2 = NULL;
+               }
+
+               scf_vector_clear(tmp, ( void (*)(void*) )scf_dn_status_free);
+
+               if (ds->dn_indexes) {
+                       assert(ds->dn_indexes->size > 0);
+                       di =   ds->dn_indexes->data[0];
+
+                       assert(0 == scf_vector_del(ds->dn_indexes, di));
+
+                       scf_dn_index_free(di);
+                       di = NULL;
+
+                       ndi++;
+
+                       if (0 == ds->dn_indexes->size) {
+                               scf_vector_free(ds->dn_indexes);
+                               ds->dn_indexes = NULL;
+                       }
+               } else
+                       break;
+       }
+
+       ret = 0;
+error:
+       scf_dn_status_free(ds);
+       scf_vector_clear(tmp, ( void (*)(void*) )scf_dn_status_free);
+       scf_vector_free(tmp);
+       return ret;
+}
+
+static int _bb_find_ds_alias(scf_dn_status_t* ds_obj, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+{
+       scf_dn_status_t* ds_obj2;
+       scf_dn_status_t* ds;
+       scf_dn_index_t*  di;
+       scf_vector_t*    aliases;
+       int i;
+
+       aliases = scf_vector_alloc();
+       if (!aliases)
+               return -ENOMEM;
+
+       int ret = __bb_find_ds_alias(aliases, ds_obj, c, bb, bb_list_head);
+       if (ret < 0)
+               return ret;
+
+       int need = 0;
+       for (i = 0; i < aliases->size; i++) {
+               ds =        aliases->data[i];
+
+               scf_logd("ds: %#lx, ds->refs: %d\n", 0xffff & (uintptr_t)ds, ds->refs);
+               if (!ds->dag_node)
+                       continue;
+
+               if (scf_vector_find_cmp(bb->ds_malloced, ds, scf_ds_cmp_same_indexes)
+               && !scf_vector_find_cmp(bb->ds_freed,    ds, scf_ds_cmp_same_indexes)) {
+                       need = 1;
+                       break;
+               }
+       }
+
+       if (scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_ds_cmp_same_indexes)
+       && !scf_vector_find_cmp(bb->ds_freed,    ds_obj, scf_ds_cmp_same_indexes)) {
+               need = 1;
+       }
+
+       ret = need;
+error:
+       scf_vector_clear(aliases, ( void (*)(void*) ) scf_dn_status_free);
+       scf_vector_free (aliases);
+       return ret;
+}
+
+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_logd("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_bb_next_find(scf_basic_block_t* bb, void* data, scf_vector_t* queue)
+{
+       scf_basic_block_t* next_bb;
+       scf_dn_status_t*   ds;
+       scf_dn_status_t*   ds2;
+
+       int count = 0;
+       int ret;
+       int j;
+
+       for (j = 0; j < bb->nexts->size; j++) {
+               next_bb   = bb->nexts->data[j];
+
+               int k;
+               for (k = 0; k < bb->ds_malloced->size; k++) {
+                       ds =        bb->ds_malloced->data[k];
+
+                       if (scf_vector_find_cmp(bb->ds_freed, ds, scf_ds_cmp_same_indexes))
+                               continue;
+
+                       if (scf_vector_find_cmp(next_bb->ds_freed, ds, scf_ds_cmp_same_indexes))
+                               continue;
+
+                       ds2 = scf_vector_find_cmp(next_bb->ds_malloced, ds, scf_ds_cmp_like_indexes);
+                       if (ds2) {
+                               uint32_t tmp = ds2->ret;
+
+                               ds2->ret |= ds->ret;
+
+                               if (tmp != ds2->ret)
+                                       count++;
+                               continue;
+                       }
+
+                       ds2 = scf_dn_status_clone(ds);
+                       if (!ds2)
+                               return -ENOMEM;
+
+                       ret = scf_vector_add(next_bb->ds_malloced, ds2);
+                       if (ret < 0) {
+                               scf_dn_status_free(ds2);
+                               return ret;
+                       }
+                       ++count;
+               }
+
+               ret = scf_vector_add(queue, next_bb);
+               if (ret < 0)
+                       return ret;
+       }
+       return count;
+}
+
+static int _bfs_sort_function(scf_vector_t* fqueue, scf_vector_t* functions)
+{
+       scf_function_t* fmalloc = NULL;
+       scf_function_t* f;
+       scf_function_t* f2;
+       int i;
+       int j;
+
+       for (i = 0; i < functions->size; i++) {
+               f  =        functions->data[i];
+
+               f->visited_flag = 0;
+
+               if (!fmalloc && !strcmp(f->node.w->text->data, "scf__auto_malloc"))
+                       fmalloc = f;
+       }
+
+       if (!fmalloc)
+               return 0;
+
+       int ret = scf_vector_add(fqueue, fmalloc);
+       if (ret < 0)
+               return ret;
+
+       for (i = 0; i < fqueue->size; i++) {
+               f  =        fqueue->data[i];
+
+               if (f->visited_flag)
+                       continue;
+
+               scf_logd("f: %p, %s\n", f, f->node.w->text->data);
+
+               f->visited_flag = 1;
+
+               for (j = 0; j < f->caller_functions->size; j++) {
+                       f2 =        f->caller_functions->data[j];
+
+                       if (f2->visited_flag)
+                               continue;
+
+                       ret = scf_vector_add(fqueue, f2);
+                       if (ret < 0)
+                               return ret;
+               }
+       }
+
+       return 0;
+}
index c91480515c63e550d10ad81e39f1d3f75b585580..3ea1b5f40f434e3ef90a2a82050359c6018b726c 100644 (file)
@@ -134,6 +134,38 @@ error_prevs:
        return NULL;
 }
 
+scf_basic_block_t* scf_basic_block_jcc(scf_basic_block_t* to, scf_function_t* f, int jcc)
+{
+       scf_basic_block_t* bb;
+       scf_3ac_operand_t* dst;
+       scf_3ac_code_t*    c;
+
+       bb = scf_basic_block_alloc();
+       if (!bb)
+               return NULL;
+
+       c = scf_3ac_jmp_code(jcc, NULL, NULL);
+       if (!c) {
+               scf_basic_block_free(bb);
+               return NULL;
+       }
+
+       scf_list_add_tail(&bb->code_list_head, &c->list);
+
+       if (scf_vector_add(f->jmps, c) < 0) {
+               scf_basic_block_free(bb);
+               return NULL;
+       }
+
+       dst     = c->dsts->data[0];
+       dst->bb = to;
+
+       c->basic_block = bb;
+
+       bb->jmp_flag = 1;
+       return bb;
+}
+
 void scf_basic_block_free(scf_basic_block_t* bb)
 {
        if (bb) {
@@ -1190,23 +1222,6 @@ int scf_basic_block_split(scf_basic_block_t* bb_parent, scf_basic_block_t** pbb_
        return 0;
 }
 
-void scf_basic_block_mov_code(scf_list_t* start, scf_basic_block_t* bb_dst, scf_basic_block_t* bb_src)
-{
-       scf_list_t*     l;
-       scf_3ac_code_t* c;
-
-       for (l = start; l != scf_list_sentinel(&bb_src->code_list_head); ) {
-
-               c  = scf_list_data(l, scf_3ac_code_t, list);
-               l  = scf_list_next(l);
-
-               scf_list_del(&c->list);
-               scf_list_add_tail(&bb_dst->code_list_head, &c->list);
-
-               c->basic_block = bb_dst;
-       }
-}
-
 int scf_basic_block_search_bfs(scf_basic_block_t* root, scf_basic_block_bfs_pt find, void* data)
 {
        if (!root)
@@ -1271,12 +1286,12 @@ int scf_basic_block_search_dfs_prev(scf_basic_block_t* root, scf_basic_block_dfs
 
        assert(!root->jmp_flag);
 
-       root->visited_flag = 1;
+       root->visit_flag = 1;
 
        for (i = 0; i < root->prevs->size; ++i) {
                bb =        root->prevs->data[i];
 
-               if (bb->visited_flag)
+               if (bb->visit_flag)
                        continue;
 
                ret = find(bb, data);
@@ -1288,7 +1303,7 @@ int scf_basic_block_search_dfs_prev(scf_basic_block_t* root, scf_basic_block_dfs
                        if (ret < 0)
                                return ret;
 
-                       bb->visited_flag = 1;
+                       bb->visit_flag = 1;
                        continue;
                }
 
@@ -1358,3 +1373,37 @@ int scf_basic_block_loads_saves(scf_basic_block_t* bb, scf_list_t* bb_list_head)
 
        return 0;
 }
+
+void scf_basic_block_mov_code(scf_basic_block_t* to, scf_list_t* start, scf_basic_block_t* from)
+{
+       scf_list_t*     l;
+       scf_3ac_code_t* c;
+
+       for (l = start; l != scf_list_sentinel(&from->code_list_head); ) {
+
+               c  = scf_list_data(l, scf_3ac_code_t, list);
+               l  = scf_list_next(l);
+
+               scf_list_del(&c->list);
+               scf_list_add_tail(&to->code_list_head, &c->list);
+
+               c->basic_block = to;
+       }
+}
+
+void scf_basic_block_add_code(scf_basic_block_t* bb, scf_list_t* h)
+{
+       scf_3ac_code_t* c;
+       scf_list_t*     l;
+
+       for (l = scf_list_head(h); l != scf_list_sentinel(h); ) {
+
+               c  = scf_list_data(l, scf_3ac_code_t, list);
+               l  = scf_list_next(l);
+
+               scf_list_del(&c->list);
+               scf_list_add_tail(&bb->code_list_head, &c->list);
+
+               c->basic_block = bb;
+       }
+}
index ad02ed3c90a0413e6ee68895b839db7d2be5590b..49c12801a09366e94166801de74c13cc55de6bdd 100644 (file)
@@ -1,9 +1,9 @@
 #ifndef SCF_BASIC_BLOCK_H
 #define SCF_BASIC_BLOCK_H
 
+#include"scf_core_types.h"
 #include"scf_list.h"
 #include"scf_vector.h"
-#include"scf_graph.h"
 
 typedef struct scf_basic_block_s  scf_basic_block_t;
 
@@ -100,7 +100,7 @@ struct scf_basic_block_s
        uint32_t        back_flag   :1;
        uint32_t        loop_flag   :1;
        uint32_t        group_flag  :1;
-       uint32_t        visited_flag:1;
+       uint32_t        visit_flag  :1;
        uint32_t        native_flag :1;
 };
 
@@ -112,6 +112,7 @@ int                 scf_basic_block_search_dfs_prev(scf_basic_block_t* root, scf
 
 
 scf_basic_block_t*  scf_basic_block_alloc();
+scf_basic_block_t*  scf_basic_block_jcc (scf_basic_block_t* to, scf_function_t* f, int jcc);
 void                scf_basic_block_free(scf_basic_block_t* bb);
 
 scf_bb_group_t*     scf_bb_group_alloc();
@@ -133,8 +134,22 @@ int                 scf_basic_block_connect(scf_basic_block_t* prev_bb, scf_basi
 
 int                 scf_basic_block_split(scf_basic_block_t* bb_parent, scf_basic_block_t** pbb_child);
 
-void                scf_basic_block_mov_code(scf_list_t* start, scf_basic_block_t* bb_dst, scf_basic_block_t* bb_src);
-
 int                 scf_basic_block_inited_by3ac(scf_basic_block_t* bb);
 
+void                scf_basic_block_mov_code(scf_basic_block_t* to, scf_list_t* start, scf_basic_block_t* from);
+void                scf_basic_block_add_code(scf_basic_block_t* bb, scf_list_t* h);
+
+static inline void scf_basic_block_visit_flag(scf_list_t* h, int visit_flag)
+{
+       scf_basic_block_t* bb;
+       scf_list_t*        l;
+
+       for (l = scf_list_head(h); l != scf_list_sentinel(h); l = scf_list_next(l)) {
+
+               bb = scf_list_data(l, scf_basic_block_t, list);
+
+               bb->visit_flag = visit_flag;
+       }
+}
+
 #endif
index dbbb96c67ed39880f2b94260b50297de97112f2b..c0b6cd2603f5f748fff30dea7d4fbba470719df5 100644 (file)
@@ -1,672 +1,7 @@
 #include"scf_optimizer.h"
 #include"scf_pointer_alias.h"
 
-static scf_3ac_operand_t* _auto_gc_operand_alloc_pf(scf_ast_t* ast, scf_function_t* f)
-{
-       scf_3ac_operand_t* src;
-       scf_dag_node_t*    dn;
-       scf_variable_t*    v;
-       scf_type_t*        t;
-
-       t = NULL;
-       int ret = scf_ast_find_type_type(&t, ast, SCF_FUNCTION_PTR);
-       assert(0 == ret);
-       assert(t);
-
-       if (f)
-               v = SCF_VAR_ALLOC_BY_TYPE(f->node.w, t, 1, 1, f);
-       else
-               v = SCF_VAR_ALLOC_BY_TYPE(NULL, t, 1, 1, NULL);
-
-       if (!v)
-               return NULL;
-       v->const_literal_flag = 1;
-
-       dn = scf_dag_node_alloc(v->type, v, (scf_node_t*)f);
-       if (!dn) {
-               scf_variable_free(v);
-               return NULL;
-       }
-       scf_variable_free(v);
-
-       src = scf_3ac_operand_alloc();
-       if (!src) {
-               scf_dag_node_free(dn);
-               return NULL;
-       }
-
-       src->node     = (scf_node_t*)f;
-       src->dag_node = dn;
-       return src;
-}
-
-static scf_3ac_code_t* _auto_gc_code_ref(scf_ast_t* ast, scf_dag_node_t* dn)
-{
-       scf_3ac_operand_t* src;
-       scf_3ac_code_t*    c;
-       scf_function_t*    f;
-       scf_variable_t*    v;
-       scf_type_t*        t;
-
-       c = scf_3ac_code_alloc();
-       if (!c)
-               return NULL;
-       c->op   = scf_3ac_find_operator(SCF_OP_CALL);
-
-       c->srcs = scf_vector_alloc();
-       if (!c->srcs) {
-               scf_3ac_code_free(c);
-               return NULL;
-       }
-
-       f = NULL;
-       int ret = scf_ast_find_function(&f, ast, "scf__auto_ref");
-       assert(0 == ret);
-       assert(f);
-
-#define AUTO_GC_CODE_ADD_FUNCPTR() \
-       do { \
-               src = _auto_gc_operand_alloc_pf(ast, f); \
-               if (!src) { \
-                       scf_3ac_code_free(c); \
-                       return NULL; \
-               } \
-               \
-               if (scf_vector_add(c->srcs, src) < 0) { \
-                       scf_3ac_operand_free(src); \
-                       scf_3ac_code_free(c); \
-                       return NULL; \
-               } \
-       } while (0)
-
-       AUTO_GC_CODE_ADD_FUNCPTR();
-
-#define AUTO_GC_CODE_ADD_VAR() \
-       do { \
-               src = scf_3ac_operand_alloc(); \
-               if (!src) { \
-                       scf_3ac_code_free(c); \
-                       return NULL; \
-               } \
-               src->node     = dn->node; \
-               src->dag_node = dn; \
-               \
-               if (scf_vector_add(c->srcs, src) < 0) { \
-                       scf_3ac_operand_free(src); \
-                       scf_3ac_code_free(c); \
-                       return NULL; \
-               } \
-       } while (0)
-
-       AUTO_GC_CODE_ADD_VAR();
-
-       return c;
-}
-
-static scf_3ac_code_t* _auto_gc_code_memset_array(scf_ast_t* ast, scf_dag_node_t* dn_array)
-{
-       scf_3ac_operand_t* src;
-       scf_3ac_code_t*    c;
-       scf_dag_node_t*    dn;
-       scf_function_t*    f;
-       scf_variable_t*    v;
-       scf_type_t*        t;
-
-       c = scf_3ac_code_alloc();
-       if (!c)
-               return NULL;
-       c->op   = scf_3ac_find_operator(SCF_OP_3AC_MEMSET);
-
-       c->srcs = scf_vector_alloc();
-       if (!c->srcs) {
-               scf_3ac_code_free(c);
-               return NULL;
-       }
-
-       dn = dn_array;
-       AUTO_GC_CODE_ADD_VAR();
-
-       t = NULL;
-       int ret = scf_ast_find_type_type(&t, ast, SCF_VAR_INTPTR);
-       assert(0 == ret);
-       assert(t);
-
-       v = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
-       assert(v);
-       v->data.i64 = 0;
-
-       dn = scf_dag_node_alloc(v->type, v, NULL);
-       assert(dn);
-       AUTO_GC_CODE_ADD_VAR();
-
-
-       v   = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
-       assert(v);
-       v->data.i64 = scf_variable_size(dn_array->var);
-
-       dn = scf_dag_node_alloc(v->type, v, NULL);
-       assert(dn);
-       AUTO_GC_CODE_ADD_VAR();
-
-       return c;
-}
-
-static scf_3ac_code_t* _auto_gc_code_free_array(scf_ast_t* ast, scf_dag_node_t* dn_array, int capacity, int nb_pointers)
-{
-       scf_3ac_operand_t* src;
-       scf_3ac_code_t*    c;
-       scf_dag_node_t*    dn;
-       scf_function_t*    f;
-       scf_variable_t*    v;
-       scf_type_t*        t;
-
-       c = scf_3ac_code_alloc();
-       if (!c)
-               return NULL;
-       c->op   = scf_3ac_find_operator(SCF_OP_CALL);
-
-       c->srcs = scf_vector_alloc();
-       if (!c->srcs) {
-               scf_3ac_code_free(c);
-               return NULL;
-       }
-
-       f = NULL;
-       int ret = scf_ast_find_function(&f, ast, "scf__auto_free_array");
-       assert(0 == ret);
-       assert(f);
-       AUTO_GC_CODE_ADD_FUNCPTR();
-
-       dn = dn_array;
-       AUTO_GC_CODE_ADD_VAR();
-
-       t   = scf_block_find_type_type(ast->current_block, SCF_VAR_INTPTR);
-       v   = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
-       assert(v);
-       v->data.i64 = capacity;
-
-       dn = scf_dag_node_alloc(v->type, v, NULL);
-       assert(dn);
-       AUTO_GC_CODE_ADD_VAR();
-
-
-       v   = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
-       assert(v);
-       v->data.i64 = nb_pointers;
-
-       dn = scf_dag_node_alloc(v->type, v, NULL);
-       assert(dn);
-       AUTO_GC_CODE_ADD_VAR();
-
-
-       if (dn_array->var->type >= SCF_STRUCT) {
-
-               t   = NULL;
-               ret = scf_ast_find_type_type(&t, ast, dn_array->var->type);
-               assert(0 == ret);
-               assert(t);
-
-               f   = scf_scope_find_function(t->scope, "__release");
-       } else
-               f = NULL;
-       AUTO_GC_CODE_ADD_FUNCPTR();
-
-       return c;
-}
-
-static scf_3ac_code_t* _auto_gc_code_freep_array(scf_ast_t* ast, scf_dag_node_t* dn_array, int nb_pointers)
-{
-       scf_3ac_operand_t* src;
-       scf_3ac_code_t*    c;
-       scf_dag_node_t*    dn;
-       scf_function_t*    f;
-       scf_variable_t*    v;
-       scf_type_t*        t;
-
-       c = scf_3ac_code_alloc();
-       if (!c)
-               return NULL;
-       c->op   = scf_3ac_find_operator(SCF_OP_CALL);
-
-       c->srcs = scf_vector_alloc();
-       if (!c->srcs) {
-               scf_3ac_code_free(c);
-               return NULL;
-       }
-
-       f = NULL;
-       int ret = scf_ast_find_function(&f, ast, "scf__auto_freep_array");
-       assert(0 == ret);
-       assert(f);
-       AUTO_GC_CODE_ADD_FUNCPTR();
-
-       dn = dn_array;
-       AUTO_GC_CODE_ADD_VAR();
-
-       t   = NULL;
-       ret = scf_ast_find_type_type(&t, ast, SCF_VAR_INTPTR);
-       assert(0 == ret);
-       assert(t);
-       v = SCF_VAR_ALLOC_BY_TYPE(dn_array->var->w, t, 1, 0, NULL);
-       assert(v);
-       v->data.i64 = nb_pointers;
-
-       char buf[128];
-       snprintf(buf, sizeof(buf) - 1, "%d", nb_pointers);
-       scf_string_cat_cstr(v->w->text, buf);
-
-       dn = scf_dag_node_alloc(v->type, v, NULL);
-       assert(dn);
-       AUTO_GC_CODE_ADD_VAR();
-
-       if (dn_array->var->type >= SCF_STRUCT) {
-
-               t = NULL;
-               int ret = scf_ast_find_type_type(&t, ast, dn_array->var->type);
-               assert(0 == ret);
-               assert(t);
-
-               f = scf_scope_find_function(t->scope, "__release");
-
-               scf_logw("f: %p, t->name: %p\n", f, t->name->data);
-       } else
-               f = NULL;
-       AUTO_GC_CODE_ADD_FUNCPTR();
-
-       return c;
-}
-
-static scf_3ac_code_t* _code_alloc_address(scf_ast_t* ast, scf_dag_node_t* dn)
-{
-       scf_string_t*   s;
-       scf_lex_word_t* w;
-       scf_3ac_code_t* c    = scf_3ac_code_alloc();
-       scf_vector_t*   srcs = scf_vector_alloc();
-       scf_vector_t*   dsts = scf_vector_alloc();
-
-       scf_3ac_operand_t*   src0  = scf_3ac_operand_alloc();
-       scf_vector_add(srcs, src0);
-
-       src0->node     = dn->node;
-       src0->dag_node = dn;
-
-       scf_3ac_operand_t*   dst0 = scf_3ac_operand_alloc();
-       scf_vector_add(dsts, dst0);
-
-       c->srcs = srcs;
-       c->dsts = dsts;
-       c->op   = scf_3ac_find_operator(SCF_OP_ADDRESS_OF);
-
-       w = scf_lex_word_alloc(dn->var->w->file, 0, 0, SCF_LEX_WORD_ID);
-       w->text = scf_string_cstr("&");
-
-       scf_type_t* t = NULL;
-       int ret = scf_ast_find_type_type(&t, ast, dn->var->type);
-       assert(0 == ret);
-       assert(t);
-
-       scf_variable_t* v   = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn->var->nb_pointers + 1, NULL);
-       scf_dag_node_t* dn2 = scf_dag_node_alloc(v->type, v, NULL);
-
-       dst0->dag_node = dn2;
-
-       return c;
-}
-
-static scf_3ac_code_t* _code_alloc_dereference(scf_ast_t* ast, scf_dag_node_t* dn)
-{
-       scf_string_t*   s;
-       scf_lex_word_t* w;
-       scf_3ac_code_t* c    = scf_3ac_code_alloc();
-       scf_vector_t*   srcs = scf_vector_alloc();
-       scf_vector_t*   dsts = scf_vector_alloc();
-
-       scf_3ac_operand_t*   src0  = scf_3ac_operand_alloc();
-       scf_vector_add(srcs, src0);
-
-       src0->node     = dn->node;
-       src0->dag_node = dn;
-
-       scf_3ac_operand_t*   dst0 = scf_3ac_operand_alloc();
-       scf_vector_add(dsts, dst0);
-
-       c->srcs = srcs;
-       c->dsts = dsts;
-       c->op   = scf_3ac_find_operator(SCF_OP_DEREFERENCE);
-
-       w = scf_lex_word_alloc(dn->var->w->file, 0, 0, SCF_LEX_WORD_ID);
-       w->text = scf_string_cstr("*");
-
-       scf_type_t* t = NULL;
-       int ret = scf_ast_find_type_type(&t, ast, dn->var->type);
-       assert(0 == ret);
-       assert(t);
-
-       scf_variable_t* v   = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn->var->nb_pointers - 1, NULL);
-       scf_dag_node_t* dn2 = scf_dag_node_alloc(v->type, v, NULL);
-
-       dst0->dag_node = dn2;
-
-       return c;
-}
-
-static scf_3ac_code_t* _code_alloc_member(scf_ast_t* ast, scf_dag_node_t* dn_base, scf_dag_node_t* dn_member)
-{
-       scf_string_t*   s;
-       scf_lex_word_t* w;
-       scf_3ac_code_t* c    = scf_3ac_code_alloc();
-       scf_vector_t*   srcs = scf_vector_alloc();
-       scf_vector_t*   dsts = scf_vector_alloc();
-
-       scf_3ac_operand_t*   base   = scf_3ac_operand_alloc();
-       scf_3ac_operand_t*   member = scf_3ac_operand_alloc();
-       scf_vector_add(srcs, base);
-       scf_vector_add(srcs, member);
-
-       base->node       = dn_base->node;
-       base->dag_node   = dn_base;
-
-       member->node     = dn_member->node;
-       member->dag_node = dn_member;
-
-       scf_3ac_operand_t*   dst0 = scf_3ac_operand_alloc();
-       scf_vector_add(dsts, dst0);
-
-       c->srcs = srcs;
-       c->dsts = dsts;
-       c->op   = scf_3ac_find_operator(SCF_OP_POINTER);
-
-       w = scf_lex_word_alloc(dn_base->var->w->file, 0, 0, SCF_LEX_WORD_ID);
-       w->text = scf_string_cstr("->");
-
-       scf_type_t* t = NULL;
-       int ret = scf_ast_find_type_type(&t, ast, dn_member->var->type);
-       assert(0 == ret);
-       assert(t);
-
-       scf_variable_t* v   = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn_member->var->nb_pointers, NULL);
-       scf_dag_node_t* dn2 = scf_dag_node_alloc(v->type, v, NULL);
-
-       dst0->dag_node = dn2;
-
-       return c;
-}
-
-static scf_3ac_code_t* _code_alloc_member_address(scf_ast_t* ast, scf_dag_node_t* dn_base, scf_dag_node_t* dn_member)
-{
-       scf_string_t*   s;
-       scf_lex_word_t* w;
-       scf_3ac_code_t* c    = scf_3ac_code_alloc();
-       scf_vector_t*   srcs = scf_vector_alloc();
-       scf_vector_t*   dsts = scf_vector_alloc();
-
-       scf_3ac_operand_t*   base   = scf_3ac_operand_alloc();
-       scf_3ac_operand_t*   member = scf_3ac_operand_alloc();
-       scf_vector_add(srcs, base);
-       scf_vector_add(srcs, member);
-
-       base->node       = dn_base->node;
-       base->dag_node   = dn_base;
-
-       member->node     = dn_member->node;
-       member->dag_node = dn_member;
-
-       scf_3ac_operand_t*   dst0 = scf_3ac_operand_alloc();
-       scf_vector_add(dsts, dst0);
-
-       c->srcs = srcs;
-       c->dsts = dsts;
-       c->op   = scf_3ac_find_operator(SCF_OP_3AC_ADDRESS_OF_POINTER);
-
-       w = scf_lex_word_alloc(dn_base->var->w->file, 0, 0, SCF_LEX_WORD_ID);
-       w->text = scf_string_cstr("&->");
-
-       scf_type_t* t = NULL;
-       int ret = scf_ast_find_type_type(&t, ast, dn_member->var->type);
-       assert(0 == ret);
-       assert(t);
-
-       scf_variable_t* v   = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn_member->var->nb_pointers + 1, NULL);
-       scf_dag_node_t* dn2 = scf_dag_node_alloc(v->type, v, NULL);
-
-       dn2->var->nb_dimentions = dn_base->var->nb_dimentions;
-
-       dst0->dag_node = dn2;
-
-       return c;
-}
-
-static scf_3ac_code_t* _code_alloc_array_member_address(scf_ast_t* ast, scf_dag_node_t* dn_base, scf_dag_node_t* dn_index, scf_dag_node_t* dn_scale)
-{
-       scf_string_t*   s;
-       scf_lex_word_t* w;
-       scf_3ac_code_t* c    = scf_3ac_code_alloc();
-       scf_vector_t*   srcs = scf_vector_alloc();
-       scf_vector_t*   dsts = scf_vector_alloc();
-
-       scf_3ac_operand_t*   base   = scf_3ac_operand_alloc();
-       scf_3ac_operand_t*   index  = scf_3ac_operand_alloc();
-       scf_3ac_operand_t*   scale  = scf_3ac_operand_alloc();
-       scf_vector_add(srcs, base);
-       scf_vector_add(srcs, index);
-       scf_vector_add(srcs, scale);
-
-       base->node       = dn_base->node;
-       base->dag_node   = dn_base;
-
-       index->node      = dn_index->node;
-       index->dag_node  = dn_index;
-
-       scale->node      = dn_scale->node;
-       scale->dag_node  = dn_scale;
-
-       scf_3ac_operand_t*   dst0 = scf_3ac_operand_alloc();
-       scf_vector_add(dsts, dst0);
-
-       c->srcs = srcs;
-       c->dsts = dsts;
-       c->op   = scf_3ac_find_operator(SCF_OP_3AC_ADDRESS_OF_ARRAY_INDEX);
-
-       w = scf_lex_word_alloc(dn_base->var->w->file, 0, 0, SCF_LEX_WORD_ID);
-       w->text = scf_string_cstr("&[]");
-
-       scf_type_t* t = NULL;
-       int ret = scf_ast_find_type_type(&t, ast, dn_base->var->type);
-       assert(0 == ret);
-       assert(t);
-
-       scf_variable_t* v   = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn_base->var->nb_pointers, NULL);
-       scf_dag_node_t* dn2 = scf_dag_node_alloc(v->type, v, NULL);
-
-       dn2->var->nb_dimentions = dn_base->var->nb_dimentions;
-
-       dst0->dag_node = dn2;
-
-       return c;
-}
-
-static scf_3ac_code_t* _code_alloc_array_member(scf_ast_t* ast, scf_dag_node_t* dn_base, scf_dag_node_t* dn_index, scf_dag_node_t* dn_scale)
-{
-       scf_string_t*   s;
-       scf_lex_word_t* w;
-       scf_3ac_code_t* c    = scf_3ac_code_alloc();
-       scf_vector_t*   srcs = scf_vector_alloc();
-       scf_vector_t*   dsts = scf_vector_alloc();
-
-       scf_3ac_operand_t*   base   = scf_3ac_operand_alloc();
-       scf_3ac_operand_t*   index  = scf_3ac_operand_alloc();
-       scf_3ac_operand_t*   scale  = scf_3ac_operand_alloc();
-       scf_vector_add(srcs, base);
-       scf_vector_add(srcs, index);
-       scf_vector_add(srcs, scale);
-
-       base->node       = dn_base->node;
-       base->dag_node   = dn_base;
-
-       index->node      = dn_index->node;
-       index->dag_node  = dn_index;
-
-       scale->node      = dn_scale->node;
-       scale->dag_node  = dn_scale;
-
-       scf_3ac_operand_t*   dst0 = scf_3ac_operand_alloc();
-       scf_vector_add(dsts, dst0);
-
-       c->srcs = srcs;
-       c->dsts = dsts;
-       c->op   = scf_3ac_find_operator(SCF_OP_ARRAY_INDEX);
-
-       w = scf_lex_word_alloc(dn_base->var->w->file, 0, 0, SCF_LEX_WORD_ID);
-       w->text = scf_string_cstr("[]");
-
-       scf_type_t* t = NULL;
-       int ret = scf_ast_find_type_type(&t, ast, dn_base->var->type);
-       assert(0 == ret);
-       assert(t);
-
-       scf_variable_t* v   = SCF_VAR_ALLOC_BY_TYPE(w, t, 0, dn_base->var->nb_pointers, NULL);
-       scf_dag_node_t* dn2 = scf_dag_node_alloc(v->type, v, NULL);
-
-       dn2->var->nb_dimentions = dn_base->var->nb_dimentions;
-
-       dst0->dag_node = dn2;
-
-       return c;
-}
-
-static int _auto_gc_code_list_ref(scf_list_t* h, scf_ast_t* ast, scf_dn_status_t* ds)
-{
-       scf_dag_node_t*    dn = ds->dag_node;
-       scf_3ac_code_t*    c;
-       scf_3ac_operand_t* dst;
-
-       if (ds->dn_indexes) {
-
-               int i;
-               for (i = ds->dn_indexes->size - 1; i >= 0; i--) {
-
-                       scf_dn_index_t* di = ds->dn_indexes->data[i];
-
-                       if (di->member) {
-                               assert(di->dn);
-
-                               c = _code_alloc_member(ast, dn, di->dn);
-
-                       } else {
-                               assert(di->index >= 0 || -1 == di->index);
-                               assert(di->dn_scale);
-
-                               c = _code_alloc_array_member(ast, dn, di->dn, di->dn_scale);
-                       }
-
-                       scf_list_add_tail(h, &c->list);
-
-                       dst = c->dsts->data[0];
-                       dn  = dst->dag_node;
-               }
-       }
-
-       c = _auto_gc_code_ref(ast, dn);
-
-       scf_list_add_tail(h, &c->list);
-       return 0;
-}
-
-static int _auto_gc_code_list_freep(scf_list_t* h, scf_ast_t* ast, scf_dn_status_t* ds)
-{
-       scf_dag_node_t*    dn = ds->dag_node;
-       scf_3ac_code_t*    c;
-       scf_3ac_operand_t* dst;
-
-       if (ds->dn_indexes) {
-
-               scf_dn_index_t* di;
-               int i;
-
-               for (i = ds->dn_indexes->size - 1; i >= 1; i--) {
-                       di = ds->dn_indexes->data[i];
-
-                       if (di->member) {
-                               assert(di->dn);
-
-                               c = _code_alloc_member(ast, dn, di->dn);
-
-                       } else {
-                               assert(di->index >= 0);
-
-                               assert(0 == di->index);
-
-                               c = _code_alloc_dereference(ast, dn);
-                       }
-
-                       scf_list_add_tail(h, &c->list);
-
-                       dst = c->dsts->data[0];
-                       dn  = dst->dag_node;
-               }
-
-               di = ds->dn_indexes->data[0];
-
-               if (di->member) {
-                       assert(di->dn);
-
-                       c = _code_alloc_member_address(ast, dn, di->dn);
-
-               } else {
-                       assert(di->index >= 0 || -1 == di->index);
-                       assert(di->dn_scale);
-
-                       c = _code_alloc_array_member_address(ast, dn, di->dn, di->dn_scale);
-               }
-
-               scf_list_add_tail(h, &c->list);
-
-               dst = c->dsts->data[0];
-               dn  = dst->dag_node;
-
-       } else {
-               c = _code_alloc_address(ast, dn);
-
-               scf_list_add_tail(h, &c->list);
-
-               dst = c->dsts->data[0];
-               dn  = dst->dag_node;
-       }
-
-       int nb_pointers = scf_variable_nb_pointers(dn->var);
-
-       assert(nb_pointers >= 2);
-
-       c = _auto_gc_code_freep_array(ast, dn, nb_pointers - 1);
-
-       scf_list_add_tail(h, &c->list);
-       return 0;
-}
-
-static int _auto_gc_code_list_free_array(scf_list_t* h, scf_ast_t* ast, scf_dag_node_t* dn_array)
-{
-       scf_3ac_code_t* c;
-
-       assert(dn_array->var->nb_dimentions > 0);
-       assert(dn_array->var->capacity      > 0);
-
-       c = _auto_gc_code_free_array(ast, dn_array, dn_array->var->capacity, dn_array->var->nb_pointers);
-
-       scf_list_add_tail(h, &c->list);
-       return 0;
-}
-
-static int _auto_gc_code_list_memset_array(scf_list_t* h, scf_ast_t* ast, scf_dag_node_t* dn_array)
-{
-       scf_3ac_code_t*    c;
-
-       assert(dn_array->var->capacity > 0);
-
-       c = _auto_gc_code_memset_array(ast, dn_array);
-
-       scf_list_add_tail(h, &c->list);
-       return 0;
-}
+#include"scf_auto_gc_3ac.c"
 
 static int _find_ds_malloced(scf_basic_block_t* bb, void* data)
 {
@@ -701,32 +36,14 @@ static int _find_dn_active(scf_basic_block_t* bb, void* data)
 
 static int _bb_find_ds_malloced(scf_basic_block_t* root, scf_list_t* bb_list_head, scf_dn_status_t* ds, scf_vector_t* results)
 {
-       scf_list_t*        l;
-       scf_basic_block_t* bb;
-
-       for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) {
-
-               bb = scf_list_data(l, scf_basic_block_t, list);
-               l  = scf_list_next(l);
-
-               bb->visited_flag = 0;
-       }
+       scf_basic_block_visit_flag(bb_list_head, 0);
 
        return scf_basic_block_search_dfs_prev(root, _find_ds_malloced, ds, results);
 }
 
 static int _bb_find_dn_active(scf_basic_block_t* root, scf_list_t* bb_list_head, scf_dag_node_t* dn, scf_vector_t* results)
 {
-       scf_list_t*        l;
-       scf_basic_block_t* bb;
-
-       for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) {
-
-               bb = scf_list_data(l, scf_basic_block_t, list);
-               l  = scf_list_next(l);
-
-               bb->visited_flag = 0;
-       }
+       scf_basic_block_visit_flag(bb_list_head, 0);
 
        return scf_basic_block_search_dfs_prev(root, _find_dn_active, dn, results);
 }
@@ -734,8 +51,7 @@ static int _bb_find_dn_active(scf_basic_block_t* root, scf_list_t* bb_list_head,
 static int _bb_prev_add_active(scf_basic_block_t* bb, void* data, scf_vector_t* queue)
 {
        scf_basic_block_t* bb_prev;
-
-       scf_dag_node_t* dn = data;
+       scf_dag_node_t*    dn = data;
 
        int count = 0;
        int ret;
@@ -787,118 +103,9 @@ static int _bb_add_active(scf_basic_block_t* bb, scf_dag_node_t* dn)
        return ret;
 }
 
-static int _bb_add_gc_code_ref(scf_ast_t* ast, scf_basic_block_t* bb, scf_dn_status_t* ds)
-{
-       scf_3ac_code_t* c;
-       scf_list_t*     l;
-       scf_list_t      h;
-       scf_list_init(&h);
-
-       if (scf_vector_add_unique(bb->dn_reloads, ds->dag_node) < 0)
-               return -ENOMEM;
-
-       int ret = _auto_gc_code_list_ref(&h, ast, ds);
-       if (ret < 0)
-               return ret;
-
-       for (l = scf_list_head(&h); l != scf_list_sentinel(&h); ) {
-
-               c  = scf_list_data(l, scf_3ac_code_t, list);
-               l  = scf_list_next(l);
-
-               scf_list_del(&c->list);
-               scf_list_add_tail(&bb->code_list_head, &c->list);
-
-               c->basic_block = bb;
-       }
-       return 0;
-}
-
-static int _bb_add_gc_code_freep(scf_ast_t* ast, scf_basic_block_t* bb, scf_dn_status_t* ds)
-{
-       scf_3ac_code_t* c;
-       scf_list_t*     l;
-       scf_list_t      h;
-       scf_list_init(&h);
-
-       if (scf_vector_add_unique(bb->dn_reloads, ds->dag_node) < 0)
-               return -ENOMEM;
-
-       int ret = _auto_gc_code_list_freep(&h, ast, ds);
-       if (ret < 0)
-               return ret;
-
-       for (l = scf_list_head(&h); l != scf_list_sentinel(&h); ) {
-
-               c  = scf_list_data(l, scf_3ac_code_t, list);
-               l  = scf_list_next(l);
-
-               scf_list_del(&c->list);
-               scf_list_add_tail(&bb->code_list_head, &c->list);
-
-               c->basic_block = bb;
-       }
-       return 0;
-}
-
-static int _bb_add_gc_code_memset_array(scf_ast_t* ast, scf_basic_block_t* bb, scf_dag_node_t* dn_array)
-{
-       scf_3ac_code_t* c;
-       scf_list_t*     l;
-       scf_list_t      h;
-       scf_list_init(&h);
-
-       if (scf_vector_add_unique(bb->dn_reloads, dn_array) < 0)
-               return -ENOMEM;
-
-       int ret = _auto_gc_code_list_memset_array(&h, ast, dn_array);
-       if (ret < 0)
-               return ret;
-
-       for (l = scf_list_head(&h); l != scf_list_sentinel(&h); ) {
-
-               c  = scf_list_data(l, scf_3ac_code_t, list);
-               l  = scf_list_next(l);
-
-               scf_list_del(&c->list);
-               scf_list_add_tail(&bb->code_list_head, &c->list);
-
-               c->basic_block = bb;
-       }
-       return 0;
-}
-
-static int _bb_add_gc_code_free_array(scf_ast_t* ast, scf_basic_block_t* bb, scf_dag_node_t* dn_array)
-{
-       scf_3ac_code_t* c;
-       scf_list_t*     l;
-       scf_list_t      h;
-       scf_list_init(&h);
-
-       if (scf_vector_add_unique(bb->dn_reloads, dn_array) < 0)
-               return -ENOMEM;
-
-       int ret = _auto_gc_code_list_free_array(&h, ast, dn_array);
-       if (ret < 0)
-               return ret;
-
-       for (l = scf_list_head(&h); l != scf_list_sentinel(&h); ) {
-
-               c  = scf_list_data(l, scf_3ac_code_t, list);
-               l  = scf_list_next(l);
-
-               scf_list_del(&c->list);
-               scf_list_add_tail(&bb->code_list_head, &c->list);
-
-               c->basic_block = bb;
-       }
-       return 0;
-}
-
 static int _bb_add_free_arry(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_dag_node_t* dn_array)
 {
-       scf_basic_block_t* bb1     = NULL;
-       scf_dag_node_t*    dn2;
+       scf_basic_block_t* bb1 = NULL;
 
        int ret = scf_basic_block_split(bb, &bb1);
        if (ret < 0)
@@ -908,7 +115,7 @@ static int _bb_add_free_arry(scf_ast_t* ast, scf_function_t* f, scf_basic_block_
 
        if (bb->end_flag) {
 
-               scf_basic_block_mov_code(scf_list_head(&bb->code_list_head), bb1, bb);
+               scf_basic_block_mov_code(bb1, scf_list_head(&bb->code_list_head), bb);
 
                bb1->ret_flag  = bb->ret_flag;
                bb1->end_flag  = 1;
@@ -920,7 +127,7 @@ static int _bb_add_free_arry(scf_ast_t* ast, scf_function_t* f, scf_basic_block_
                bb1->call_flag = 1;
        }
 
-       ret = _bb_add_gc_code_free_array(ast, bb1, dn_array);
+       ret = _bb_add_gc_code_free_array(&f->dag_list_head, ast, bb1, dn_array);
        if (ret < 0)
                return ret;
 
@@ -933,9 +140,8 @@ static int _bb_add_free_arry(scf_ast_t* ast, scf_function_t* f, scf_basic_block_
 
 static int _bb_add_memset_array(scf_ast_t* ast, scf_function_t* f, scf_dag_node_t* dn_array)
 {
-       scf_basic_block_t* bb   = NULL;
-       scf_basic_block_t* bb1  = NULL;
-       scf_dag_node_t*    dn2;
+       scf_basic_block_t* bb  = NULL;
+       scf_basic_block_t* bb1 = NULL;
        scf_list_t*        l;
 
        l  = scf_list_head(&f->basic_block_list_head);
@@ -947,7 +153,7 @@ static int _bb_add_memset_array(scf_ast_t* ast, scf_function_t* f, scf_dag_node_
 
        scf_list_add_front(&bb->list, &bb1->list);
 
-       scf_basic_block_mov_code(scf_list_head(&bb->code_list_head), bb1, bb);
+       scf_basic_block_mov_code(bb1, scf_list_head(&bb->code_list_head), bb);
 
        bb1->call_flag = 1;
        bb1->ret_flag  = bb->ret_flag;
@@ -955,7 +161,7 @@ static int _bb_add_memset_array(scf_ast_t* ast, scf_function_t* f, scf_dag_node_
 
        bb1 = bb;
 
-       ret = _bb_add_gc_code_memset_array(ast, bb1, dn_array);
+       ret = _bb_add_gc_code_memset_array(&f->dag_list_head, ast, bb1, dn_array);
        if (ret < 0)
                return ret;
 
@@ -995,13 +201,17 @@ static int _bb_split_prev_add_free(scf_ast_t* ast, scf_function_t* f, scf_basic_
 
        scf_list_add_tail(&bb->list, &bb1->list);
 
+       scf_3ac_operand_t* dst;
+       scf_3ac_code_t*    c;
+       scf_list_t*        l;
        int j;
+       int k;
+
        for (j  = 0; j < bb1->prevs->size; j++) {
                bb2 =        bb1->prevs->data[j];
 
                assert(0 == scf_vector_del(bb->prevs, bb2));
 
-               int k;
                for (k = 0; k < bb2->nexts->size; k++) {
 
                        if (bb2->nexts->data[k] == bb)
@@ -1012,10 +222,6 @@ static int _bb_split_prev_add_free(scf_ast_t* ast, scf_function_t* f, scf_basic_
        for (j  = 0; j < bb->prevs->size; j++) {
                bb2 =        bb->prevs->data[j];
 
-               scf_list_t*        l;
-               scf_3ac_code_t*    c;
-               scf_3ac_operand_t* dst;
-
                for (l  = scf_list_next(&bb2->list); l != scf_list_sentinel(bb_list_head);
                         l  = scf_list_next(l)) {
 
@@ -1028,26 +234,9 @@ static int _bb_split_prev_add_free(scf_ast_t* ast, scf_function_t* f, scf_basic_
                                break;
 
                        if (bb3 == bb1) {
-                               bb3 = scf_basic_block_alloc();
+                               bb3 = scf_basic_block_jcc(bb, f, SCF_OP_GOTO);
                                if (!bb3)
                                        return -ENOMEM;
-                               bb3->jmp_flag = 1;
-
-                               c       = scf_3ac_code_alloc();
-                               c->op   = scf_3ac_find_operator(SCF_OP_GOTO);
-                               c->dsts = scf_vector_alloc();
-
-                               dst     = scf_3ac_operand_alloc();
-                               dst->bb = bb;
-
-                               if (scf_vector_add(c->dsts, dst) < 0)
-                                       return -ENOMEM;
-
-                               c->basic_block = bb3;
-
-                               assert(0 == scf_vector_add(f->jmps, c));
-
-                               scf_list_add_tail(&bb3->code_list_head, &c->list);
 
                                scf_list_add_tail(&bb1->list, &bb3->list);
                        }
@@ -1059,10 +248,8 @@ static int _bb_split_prev_add_free(scf_ast_t* ast, scf_function_t* f, scf_basic_
        for (j  = 0; j < bb1->prevs->size; j++) {
                bb2 =        bb1->prevs->data[j];
 
-               scf_list_t*        l;
-               scf_list_t*        l2;
-               scf_3ac_code_t*    c;
-               scf_3ac_operand_t* dst;
+               scf_dn_status_t* ds2;
+               scf_list_t*      l2;
 
                for (l  = scf_list_next(&bb2->list); l != &bb1->list && l != scf_list_sentinel(bb_list_head);
                         l  = scf_list_next(l)) {
@@ -1072,19 +259,16 @@ static int _bb_split_prev_add_free(scf_ast_t* ast, scf_function_t* f, scf_basic_
                        if (!bb3->jmp_flag)
                                break;
 
-                       for (l2 = scf_list_head(&bb3->code_list_head); l2 != scf_list_sentinel(&bb3->code_list_head);
-                                l2 = scf_list_next(l2)) {
+                       l2  = scf_list_head(&bb3->code_list_head);
+                       c   = scf_list_data(l2, scf_3ac_code_t, list);
+                       dst = c->dsts->data[0];
 
-                               c   = scf_list_data(l2, scf_3ac_code_t, list);
-                               dst = c->dsts->data[0];
+                       if (dst->bb == bb)
+                               dst->bb = bb1;
 
-                               if (dst->bb == bb)
-                                       dst->bb = bb1;
-                       }
+                       assert(scf_list_next(l2) == scf_list_sentinel(&bb3->code_list_head));
                }
 
-               scf_dn_status_t* ds2;
-               int k;
                for (k  = 0; k < bb2->ds_malloced->size; k++) {
                        ds2 =        bb2->ds_malloced->data[k];
 
@@ -1107,7 +291,7 @@ static int _bb_split_prev_add_free(scf_ast_t* ast, scf_function_t* f, scf_basic_
                }
        }
 
-       int ret = _bb_add_gc_code_freep(ast, bb1, ds);
+       int ret = _bb_add_gc_code_freep(&f->dag_list_head, ast, bb1, ds);
        if (ret < 0)
                return ret;
 
@@ -1166,7 +350,7 @@ static int _auto_gc_last_free(scf_ast_t* ast, scf_function_t* f)
                dn = ds->dag_node;
                v  = dn->var;
 
-               scf_loge("f: %s, last free: v_%d_%d/%s, ds->ret: %u\n",
+               scf_logw("f: %s, last free: v_%d_%d/%s, ds->ret: %u\n",
                                f->node.w->text->data, v->w->line, v->w->pos, v->w->text->data, ds->ret);
                scf_dn_status_print(ds);
 
@@ -1211,15 +395,11 @@ static int _auto_gc_last_free(scf_ast_t* ast, scf_function_t* f)
                        }
                }
 
-               scf_vector_t* vec;
-
-               vec = scf_vector_alloc();
+               scf_vector_t* vec = scf_vector_alloc();
                if (!vec)
                        return -ENOMEM;
 
                scf_basic_block_t* bb1;
-               scf_basic_block_t* bb2;
-               scf_basic_block_t* bb3;
                scf_basic_block_t* bb_dominator;
 
                int dfo = 0;
@@ -1318,7 +498,7 @@ static int _optimize_auto_gc_bb_ref(scf_ast_t* ast, scf_function_t* f, scf_basic
        if (!bb1->ds_auto_gc)
                return -ENOMEM;
 
-       int ret = _bb_add_gc_code_ref(ast, bb1, ds);
+       int ret = _bb_add_gc_code_ref(&f->dag_list_head, ast, bb1, ds);
        if (ret < 0)
                return ret;
 
@@ -1357,7 +537,7 @@ static int _optimize_auto_gc_bb_free(scf_ast_t* ast, scf_function_t* f, scf_basi
        bb1->dereference_flag = 0;
        bb1->auto_free_flag   = 1;
 
-       int ret = _bb_add_gc_code_freep(ast, bb1, ds);
+       int ret = _bb_add_gc_code_freep(&f->dag_list_head, ast, bb1, ds);
        if (ret < 0)
                return ret;
 
@@ -1375,17 +555,17 @@ static int _optimize_auto_gc_bb_free(scf_ast_t* ast, scf_function_t* f, scf_basi
 
 static int _bb_prevs_malloced(scf_basic_block_t* bb, scf_vector_t* ds_malloced)
 {
-       scf_basic_block_t* bb_prev;
+       scf_basic_block_t*  bb_prev;
+       scf_dn_status_t*    ds;
+       scf_dn_status_t*    ds2;
        int i;
        int j;
 
        for (i = 0; i < bb->prevs->size; i++) {
-
                bb_prev   = bb->prevs->data[i];
 
                for (j = 0; j < bb_prev->ds_malloced->size; j++) {
-
-                       scf_dn_status_t* ds = bb_prev->ds_malloced->data[j];
+                       ds =        bb_prev->ds_malloced->data[j];
 
                        if (scf_vector_find_cmp(bb_prev->ds_freed, ds, scf_ds_cmp_same_indexes))
                                continue;
@@ -1393,7 +573,7 @@ static int _bb_prevs_malloced(scf_basic_block_t* bb, scf_vector_t* ds_malloced)
                        if (scf_vector_find_cmp(ds_malloced, ds, scf_ds_cmp_like_indexes))
                                continue;
 
-                       scf_dn_status_t* ds2 = scf_dn_status_clone(ds);
+                       ds2 = scf_dn_status_clone(ds);
                        if (!ds2)
                                return -ENOMEM;
 
@@ -1589,9 +769,7 @@ static int _optimize_auto_gc_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_blo
                } else
                        goto _end;
 
-               scf_vector_t* bb_split_prevs;
-
-               bb_split_prevs = scf_vector_alloc();
+               scf_vector_t* bb_split_prevs = scf_vector_alloc();
                if (!bb_split_prevs)
                        return -ENOMEM;
 
index 64095053f6173f563d59cedec0387d4613c6131d..549f261b01ba58e197ccbc439cb0eff91a889d89 100644 (file)
 #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_ds_cmp_same_indexes))
-               return 0;
-
-       if (scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_ds_cmp_same_indexes))
-               return 1;
-       return 0;
-}
+#include"scf_auto_gc_find.c"
 
 static int _bb_add_ds(scf_basic_block_t* bb, scf_dn_status_t* ds_obj)
 {
-       scf_dn_status_t*   ds2;
+       scf_dn_status_t*  ds;
 
-       ds2 = scf_vector_find_cmp(bb->ds_freed, ds_obj, scf_ds_cmp_same_indexes);
-       if (ds2) {
-               scf_vector_del(bb->ds_freed, ds2);
-               if (ds2 != ds_obj)
-                       scf_dn_status_free(ds2);
-               ds2 = NULL;
+       ds = scf_vector_find_cmp(bb->ds_freed, ds_obj, scf_ds_cmp_same_indexes);
+       if (ds) {
+               assert(0 == scf_vector_del(bb->ds_freed, ds));
+
+               scf_dn_status_free(ds);
+               ds = NULL;
        }
 
-       ds2 = scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_ds_cmp_same_indexes);
-       if (!ds2) {
+       ds = scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_ds_cmp_same_indexes);
+       if (!ds) {
+               ds = scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_ds_cmp_like_indexes);
+
+               if (!ds) {
+                       ds = scf_dn_status_clone(ds_obj);
+                       if (!ds)
+                               return -ENOMEM;
 
-               ds2 = scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_ds_cmp_like_indexes);
-               if (!ds2) {
-                       assert(0 == scf_vector_add(bb->ds_malloced, ds_obj));
+                       int ret = scf_vector_add(bb->ds_malloced, ds);
+                       if (ret < 0) {
+                               scf_dn_status_free(ds);
+                               return ret;
+                       }
                        return 0;
                }
        }
 
-       ds2->ret |= ds_obj->ret;
-
-       scf_dn_status_free(ds_obj);
+       ds->ret |= ds_obj->ret;
        return 0;
 }
 
 static int _bb_del_ds(scf_basic_block_t* bb, scf_dn_status_t* ds_obj)
 {
-       scf_dn_status_t*   ds2;
+       scf_dn_status_t*  ds;
 
        if (!scf_vector_find_cmp(bb->ds_freed, ds_obj, scf_ds_cmp_same_indexes)) {
 
-               ds2 = scf_vector_find_cmp(bb->ds_freed, ds_obj, scf_ds_cmp_like_indexes);
-               if (!ds2) {
-                       ds2 = scf_dn_status_clone(ds_obj);
-                       assert(ds2);
+               ds = scf_vector_find_cmp(bb->ds_freed, ds_obj, scf_ds_cmp_like_indexes);
+               if (!ds) {
+                       ds = scf_dn_status_clone(ds_obj);
+                       if (!ds)
+                               return -ENOMEM;
 
-                       assert(0 == scf_vector_add(bb->ds_freed, ds2));
+                       int ret = scf_vector_add(bb->ds_freed, ds);
+                       if (ret < 0) {
+                               scf_dn_status_free(ds);
+                               return ret;
+                       }
                }
        }
 
-       ds2 = scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_ds_cmp_same_indexes);
-       if (ds2) {
-               scf_vector_del(bb->ds_malloced, ds2);
-               if (ds2 != ds_obj)
-                       scf_dn_status_free(ds2);
-               ds2 = NULL;
+       ds = scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_ds_cmp_same_indexes);
+       if (ds) {
+               assert(0 == scf_vector_del(bb->ds_malloced, ds));
+
+               scf_dn_status_free(ds);
+               ds = NULL;
        }
+       return 0;
+}
+
+static int __ds_append_index(scf_dn_status_t* dst, scf_dn_status_t* src)
+{
+       scf_dn_index_t* di;
+       scf_dn_index_t* di2;
+       int j;
+
+       for (j  = 0; j < src->dn_indexes->size; j++) {
+               di2 =        src->dn_indexes->data[j];
 
+               di = scf_dn_index_alloc();
+               if (!di)
+                       return -ENOMEM;
+
+               di->index  = di2->index;
+               di->member = di2->member;
+               di->dn     = di2->dn;
+#if 0
+               if (di2->dn) {
+                       di ->dn = scf_dag_node_alloc(di2->dn->type, di2->dn->var, di2->dn->node);
+                       if (!di->dn) {
+                               scf_dn_index_free (di);
+                               return -ENOMEM;
+                       }
+               }
+#endif
+               int ret = scf_vector_add_front(dst->dn_indexes, di);
+               if (ret < 0) {
+                       scf_dn_index_free(di);
+                       return ret;
+               }
+       }
        return 0;
 }
 
@@ -72,29 +108,27 @@ static int _bb_add_ds_for_call(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, s
 
        scf_dn_status_t*   ds;
        scf_dn_status_t*   ds2;
-
        scf_dn_index_t*    di;
-       scf_dn_index_t*    di2;
-
        scf_variable_t*    v;
        scf_variable_t*    v2;
 
        int i;
+       int j;
        for (i  = 0; i < bb2->ds_malloced->size; i++) {
                ds2 =        bb2->ds_malloced->data[i];
 
                if (ds2->dag_node->var != arg)
                        continue;
 
-               ds = scf_dn_status_clone(ds_obj);
-               if (!ds)
-                       return -ENOMEM;
-
                if (!ds2->dn_indexes) {
-                       _bb_add_ds(bb, ds);
+                       _bb_add_ds(bb, ds_obj);
                        continue;
                }
 
+               ds = scf_dn_status_clone(ds_obj);
+               if (!ds)
+                       return -ENOMEM;
+
                if (!ds->dn_indexes) {
                        ds ->dn_indexes = scf_vector_alloc();
 
@@ -104,32 +138,10 @@ static int _bb_add_ds_for_call(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, s
                        }
                }
 
-               int j;
-               for (j  = 0; j < ds2->dn_indexes->size; j++) {
-                       di2 =        ds2->dn_indexes->data[j];
-
-                       di = scf_dn_index_alloc();
-                       if (!di) {
-                               scf_dn_status_free(ds);
-                               return -ENOMEM;
-                       }
-                       di->index  = di2->index;
-                       di->member = di2->member;
-
-                       if (di2->dn) {
-                               di ->dn = scf_dag_node_alloc(di2->dn->type, di2->dn->var, di2->dn->node);
-                               if (!di->dn) {
-                                       scf_dn_status_free(ds);
-                                       scf_dn_index_free (di);
-                                       return -ENOMEM;
-                               }
-                       }
-
-                       if (scf_vector_add_front(ds->dn_indexes, di) < 0) {
-                               scf_dn_status_free(ds);
-                               scf_dn_index_free (di);
-                               return -ENOMEM;
-                       }
+               int ret = __ds_append_index(ds, ds2);
+               if (ret < 0) {
+                       scf_dn_status_free(ds);
+                       return ret;
                }
 
                v  = ds ->dag_node->var;
@@ -139,7 +151,6 @@ static int _bb_add_ds_for_call(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, s
                int n = v2->nb_pointers + v2->nb_dimentions + (v2->type >= SCF_STRUCT);
 
                for (j = 0; j + m < n; j++) {
-
                        di = ds->dn_indexes->data[ds->dn_indexes->size - 1];
 
                        if (di->member || 0 == di->index) {
@@ -160,35 +171,37 @@ static int _bb_add_ds_for_call(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, s
                }
 
                _bb_add_ds(bb, ds);
+
+               scf_dn_status_free(ds);
+               ds = NULL;
        }
 
        return 0;
 }
 
-static int __bb_add_ds(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, scf_basic_block_t* __bb, scf_dn_status_t* __ds)
+static int __bb_add_ds_append(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, scf_basic_block_t* __bb, scf_dn_status_t* __ds)
 {
-       scf_dn_status_t*   ds;
-       scf_dn_status_t*   ds2;
-
-       scf_dn_index_t*    di;
-       scf_dn_index_t*    di2;
-
+       scf_dn_status_t*  ds;
+       scf_dn_status_t*  ds2;
+       scf_dn_index_t*   di;
+       scf_dn_index_t*   di2;
        int i;
+
        for (i  = 0; i < __bb->ds_malloced->size; i++) {
                ds2 =        __bb->ds_malloced->data[i];
 
                if (ds2->dag_node->var != __ds->dag_node->var)
                        continue;
 
-               ds = scf_dn_status_clone(ds_obj);
-               if (!ds)
-                       return -ENOMEM;
-
                if (!ds2->dn_indexes) {
-                       _bb_add_ds(bb, ds);
+                       _bb_add_ds(bb, ds_obj);
                        continue;
                }
 
+               ds = scf_dn_status_clone(ds_obj);
+               if (!ds)
+                       return -ENOMEM;
+
                if (!ds->dn_indexes) {
                        ds ->dn_indexes = scf_vector_alloc();
 
@@ -198,52 +211,22 @@ static int __bb_add_ds(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, scf_basic
                        }
                }
 
-               int size = ds->dn_indexes->size;
-               int j;
-               for (j  = 0; j < ds2->dn_indexes->size; j++) {
-                       di2 =        ds2->dn_indexes->data[j];
-
-                       di = scf_dn_index_alloc();
-                       if (!di) {
-                               scf_dn_status_free(ds);
-                               return -ENOMEM;
-                       }
-                       di->index  = di2->index;
-                       di->member = di2->member;
-
-                       if (di2->dn) {
-                               di ->dn = scf_dag_node_alloc(di2->dn->type, di2->dn->var, di2->dn->node);
-                               if (!di->dn) {
-                                       scf_dn_status_free(ds);
-                                       scf_dn_index_free (di);
-                               }
-                       }
-
-                       if (scf_vector_add(ds->dn_indexes, di) < 0) {
-                               scf_dn_status_free(ds);
-                               scf_dn_index_free (di);
-                               return -ENOMEM;
-                       }
-               }
-
-               int k;
-               for (k = 0; k < ds2->dn_indexes->size; k++) {
-
-                       di = ds->dn_indexes->data[size + k];
-
-                       for (j = size + k - 1; j > k; j--)
-                               ds->dn_indexes->data[j + 1] = ds->dn_indexes->data[j];
-
-                       ds->dn_indexes->data[k] = di;
+               int ret = __ds_append_index(ds, ds2);
+               if (ret < 0) {
+                       scf_dn_status_free(ds);
+                       return ret;
                }
 
                _bb_add_ds(bb, ds);
+
+               scf_dn_status_free(ds);
+               ds = NULL;
        }
 
        return 0;
 }
 
-static int _bb_add_ds_for_ret(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, scf_function_t* f2, scf_3ac_code_t* c)
+static int _bb_add_ds_for_ret(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, scf_function_t* f2)
 {
        scf_list_t*        l2  = scf_list_tail(&f2->basic_block_list_head);
        scf_basic_block_t* bb2 = scf_list_data(l2, scf_basic_block_t, list);
@@ -256,160 +239,12 @@ static int _bb_add_ds_for_ret(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, sc
                if (!ds2->ret)
                        continue;
 
-               __bb_add_ds(bb, ds_obj, bb2, ds2);
+               __bb_add_ds_append(bb, ds_obj, bb2, ds2);
        }
 
        return 0;
 }
 
-int __bb_find_ds_alias(scf_vector_t* aliases, scf_dn_status_t* ds_obj, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
-{
-       scf_dn_status_t* ds_obj2;
-       scf_dn_status_t* ds_alias;
-       scf_dn_index_t*  di;
-
-       int ret;
-       int i;
-       int ndi = 0;
-
-       ds_obj2 = scf_dn_status_clone(ds_obj);
-       if (!ds_obj2)
-               return -ENOMEM;
-
-       while (1) {
-               scf_vector_t*    aliases2;
-               scf_dn_status_t* ds_alias2;
-
-               scf_3ac_code_t*  c2 = scf_list_data(scf_list_prev(&c->list), scf_3ac_code_t, list);
-
-               aliases2 = scf_vector_alloc();
-               if (!aliases2)
-                       return -ENOMEM;
-
-               ret = scf_pointer_alias_ds(aliases2, ds_obj2, c2, bb, bb_list_head);
-               if (ret < 0) {
-                       scf_vector_free(aliases2);
-
-                       if (SCF_POINTER_NOT_INIT == ret)
-                               break;
-                       return ret;
-               }
-
-               int j;
-               for (j = 0; j < aliases2->size; j++) {
-                       ds_alias2 = aliases2->data[j];
-
-                       SCF_XCHG(ds_alias2->dn_indexes, ds_alias2->alias_indexes);
-                       SCF_XCHG(ds_alias2->dag_node,   ds_alias2->alias);
-
-                       if (ds_obj->dn_indexes) {
-
-                               if (!ds_alias2->dn_indexes) {
-                                       ds_alias2 ->dn_indexes = scf_vector_alloc();
-                                       if (!ds_alias2->dn_indexes)
-                                               return -ENOMEM;
-                               }
-
-                               int k;
-                               for (k = 0; k < ndi; k++) {
-                                       di = ds_obj->dn_indexes->data[k];
-
-                                       ret = scf_vector_add(ds_alias2->dn_indexes, di);
-                                       if (ret < 0) {
-                                               scf_loge("\n");
-                                               return ret;
-                                       }
-                                       di->refs++;
-                               }
-
-                               for (k = ds_alias2->dn_indexes->size - 2; k >= 0; k--)
-                                       ds_alias2->dn_indexes->data[k + 1] = ds_alias2->dn_indexes->data[k];
-
-                               for (k = 0; k < ndi; k++)
-                                       ds_alias2->dn_indexes->data[k] = ds_obj->dn_indexes->data[k];
-                       }
-
-                       if (scf_vector_add(aliases, ds_alias2) < 0) {
-                               scf_vector_free (aliases2);
-                               return ret;
-                       }
-               }
-
-               scf_vector_free (aliases2);
-               aliases2 = NULL;
-
-               if (ds_obj2->dn_indexes) {
-
-                       assert(ds_obj2->dn_indexes->size > 0);
-
-                       di = ds_obj2->dn_indexes->data[0];
-
-                       for (j = 1; j < ds_obj2->dn_indexes->size; j++)
-                               ds_obj2->dn_indexes->data[j - 1] = ds_obj2->dn_indexes->data[j];
-
-                       scf_dn_index_free(di);
-                       di = NULL;
-
-                       ndi++;
-
-                       ds_obj2->dn_indexes->size--;
-
-                       if (0 == ds_obj2->dn_indexes->size) {
-                               scf_vector_free(ds_obj2->dn_indexes);
-                               ds_obj2->dn_indexes = NULL;
-                       }
-               } else
-                       break;
-       }
-
-       return 0;
-}
-
-static int _bb_find_ds_alias(scf_dn_status_t* ds_obj, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
-{
-       scf_dn_status_t* ds_obj2;
-       scf_dn_status_t* ds_alias;
-       scf_dn_index_t*  di;
-       scf_vector_t*    aliases;
-
-       int ret;
-       int i;
-
-       aliases = scf_vector_alloc();
-       if (!aliases)
-               return -ENOMEM;
-
-       ret = __bb_find_ds_alias(aliases, ds_obj, c, bb, bb_list_head);
-       if (ret < 0)
-               return ret;
-
-       int need = 0;
-       for (i = 0; i < aliases->size; i++) {
-               ds_alias  = aliases->data[i];
-
-               if (!ds_alias->dag_node)
-                       continue;
-
-               if (scf_vector_find_cmp(bb->ds_malloced, ds_alias, scf_ds_cmp_same_indexes)
-                               && !scf_vector_find_cmp(bb->ds_freed, ds_alias, scf_ds_cmp_same_indexes)) {
-                       need = 1;
-                       break;
-               }
-       }
-
-       if (scf_vector_find_cmp(bb->ds_malloced, ds_obj, scf_ds_cmp_same_indexes)
-                       && !scf_vector_find_cmp(bb->ds_freed, ds_obj, scf_ds_cmp_same_indexes)) {
-               need = 1;
-       }
-
-       ret = need;
-
-error:
-//     scf_vector_clear(aliases, ( void (*)(void*) ) scf_dn_status_free);
-       scf_vector_free (aliases);
-       return ret;
-}
-
 #define AUTO_GC_FIND_BB_SPLIT(parent, child) \
        do { \
                int ret = scf_basic_block_split(parent, &child); \
@@ -487,11 +322,10 @@ static int _auto_gc_find_argv_out(scf_basic_block_t* cur_bb, scf_3ac_code_t* c)
                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) {
-
+               ret = scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node);
+               if (ret < 0) {
                        scf_dn_status_free(ds_obj);
-                       ds_obj = NULL;
-                       return -ENOMEM;
+                       return ret;
                }
 
                ret = _bb_add_ds_for_call(cur_bb, ds_obj, f2, v1);
@@ -507,46 +341,6 @@ static int _auto_gc_find_argv_out(scf_basic_block_t* cur_bb, scf_3ac_code_t* c)
        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);
@@ -570,127 +364,136 @@ static int _auto_gc_find_ret(scf_basic_block_t* cur_bb, scf_3ac_code_t* c)
                        return -ENOMEM;
 
                _bb_add_ds(cur_bb, ds_obj);
+
+               scf_dn_status_free(ds_obj);
+               ds_obj = NULL;
        }
 
        return 0;
 }
 
-static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f)
+static int __auto_gc_ds_for_assign(scf_dn_status_t** ds, scf_dag_node_t** dn, scf_3ac_code_t* c)
 {
-       scf_list_t*     l;
-       scf_3ac_code_t* c;
-
-       scf_basic_block_t* cur_bb = bb;
-       scf_basic_block_t* bb2    = NULL;
-
-       int count = 0;
-
-       for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) {
-
-               c  = scf_list_data(l, scf_3ac_code_t, list);
-               l  = scf_list_next(l);
-
-               scf_3ac_operand_t* base;
-               scf_3ac_operand_t* member;
-               scf_3ac_operand_t* index;
-               scf_3ac_operand_t* scale;
-
-               scf_3ac_operand_t* dst;
-               scf_3ac_operand_t* src;
-               scf_dn_status_t*   ds_obj;
-               scf_dn_status_t*   ds;
-               scf_dag_node_t*    dn;
-               scf_variable_t*    v0;
+       scf_3ac_operand_t* base;
+       scf_3ac_operand_t* member;
+       scf_3ac_operand_t* index;
+       scf_3ac_operand_t* scale;
+       scf_3ac_operand_t* src;
+       scf_variable_t*    v;
 
-               if (SCF_OP_ASSIGN == c->op->type) {
+       switch (c->op->type) {
 
-                       dst = c->dsts->data[0];
-                       v0  = dst->dag_node->var;
+               case SCF_OP_ASSIGN:
+                       base = c->dsts->data[0];
+                       v    = base->dag_node->var;
 
-                       if (!scf_variable_may_malloced(v0))
-                               goto _end;
+                       if (!scf_variable_may_malloced(v))
+                               return 0;
 
-                       ds_obj = scf_dn_status_alloc(dst->dag_node);
-                       if (!ds_obj)
+                       *ds = scf_dn_status_alloc(base->dag_node);
+                       if (!*ds)
                                return -ENOMEM;
 
                        src = c->srcs->data[0];
-                       dn  = src->dag_node;
-
-               } else if (SCF_OP_3AC_ASSIGN_ARRAY_INDEX == c->op->type) {
+                       *dn = src->dag_node;
+                       break;
 
+               case SCF_OP_3AC_ASSIGN_ARRAY_INDEX:
                        assert(4 == c->srcs->size);
 
                        base  = c->srcs->data[0];
+                       v     = _scf_operand_get(base->node->parent);
+
+                       if (!scf_variable_may_malloced(v))
+                               return 0;
+
                        index = c->srcs->data[1];
                        scale = c->srcs->data[2];
                        src   = c->srcs->data[3];
-                       dn    = src->dag_node;
-                       v0    = _scf_operand_get(base->node->parent);
+                       *dn   = src->dag_node;
 
-                       if (!scf_variable_may_malloced(v0))
-                               goto _end;
+                       return scf_ds_for_assign_array_member(ds, base->dag_node, index->dag_node, scale->dag_node);
+                       break;
 
-                       ds_obj = NULL;
+               case SCF_OP_3AC_ASSIGN_POINTER:
+                       assert(3 == c->srcs->size);
 
-                       int ret = scf_ds_for_assign_array_member(&ds_obj, base->dag_node, index->dag_node, scale->dag_node);
-                       if (ret < 0)
-                               return ret;
+                       member = c->srcs->data[1];
+                       v      = member->dag_node->var;
 
-                       if (ds_obj->dag_node->var->arg_flag)
-                               ds_obj->ret = 1;
+                       if (!scf_variable_may_malloced(v))
+                               return 0;
 
-               } else if (SCF_OP_3AC_ASSIGN_POINTER == c->op->type) {
+                       base = c->srcs->data[0];
+                       src  = c->srcs->data[2];
+                       *dn  = src->dag_node;
 
-                       assert(3 == c->srcs->size);
+                       return scf_ds_for_assign_member(ds, base->dag_node, member->dag_node);
+                       break;
 
-                       base   = c->srcs->data[0];
-                       member = c->srcs->data[1];
-                       src    = c->srcs->data[2];
-                       dn     = src->dag_node;
-                       v0     = member->dag_node->var;
+               case SCF_OP_3AC_ASSIGN_DEREFERENCE:
+                       assert(2 == c->srcs->size);
 
-                       if (!scf_variable_may_malloced(v0))
-                               goto _end;
+                       base = c->srcs->data[0];
+                       v    = _scf_operand_get(base->node->parent);
 
-                       ds_obj = NULL;
+                       if (!scf_variable_may_malloced(v))
+                               return 0;
 
-                       int ret = scf_ds_for_assign_member(&ds_obj, base->dag_node, member->dag_node);
-                       if (ret < 0)
-                               return ret;
+                       src = c->srcs->data[1];
+                       *dn = src->dag_node;
 
-                       if (ds_obj->dag_node->var->arg_flag)
-                               ds_obj->ret = 1;
+                       return scf_ds_for_assign_dereference(ds, base->dag_node);
+               default:
+                       break;
+       };
 
-               } else if (SCF_OP_3AC_ASSIGN_DEREFERENCE == c->op->type) {
+       return 0;
+}
 
-                       assert(2 == c->srcs->size);
+static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f)
+{
+       scf_basic_block_t* cur_bb = bb;
+       scf_basic_block_t* bb2    = NULL;
+       scf_3ac_code_t*    c;
+       scf_list_t*        l;
 
-                       base = c->srcs->data[0];
-                       src  = c->srcs->data[1];
-                       dn   = src->dag_node;
-                       v0   = _scf_operand_get(base->node->parent);
+       int count = 0;
+       int ret;
+
+       for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) {
 
-                       if (!scf_variable_may_malloced(v0))
-                               goto _end;
+               c  = scf_list_data(l, scf_3ac_code_t, list);
+               l  = scf_list_next(l);
+
+               scf_3ac_operand_t* src;
+               scf_dn_status_t*   ds_obj = NULL;
+               scf_dn_status_t*   ds     = NULL;
+               scf_dag_node_t*    dn     = NULL;
 
-                       ds_obj  = NULL;
+               if (SCF_OP_ASSIGN == c->op->type
+                               || SCF_OP_3AC_ASSIGN_ARRAY_INDEX == c->op->type
+                               || SCF_OP_3AC_ASSIGN_POINTER     == c->op->type
+                               || SCF_OP_3AC_ASSIGN_DEREFERENCE == c->op->type) {
 
-                       int ret = scf_ds_for_assign_dereference(&ds_obj, base->dag_node);
+                       ret = __auto_gc_ds_for_assign(&ds_obj, &dn, c);
                        if (ret < 0)
                                return ret;
 
-                       if (ds_obj->dag_node->var->arg_flag)
-                               ds_obj->ret = 1;
+                       if (!ds_obj)
+                               goto end;
+
+                       if (SCF_OP_ASSIGN != c->op->type) {
+                               if (ds_obj->dag_node->var->arg_flag)
+                                       ds_obj->ret = 1;
+                       }
 #if 1
                } else if (SCF_OP_RETURN == c->op->type) {
-
                        src = c->srcs->data[0];
                        dn  = src->dag_node;
-                       v0  = dn->var;
 
-                       if (!scf_variable_may_malloced(v0))
-                               goto _end;
+                       if (!scf_variable_may_malloced(dn->var))
+                               goto end;
 
                        ds_obj = scf_dn_status_alloc(dn);
                        if (!ds_obj)
@@ -700,14 +503,9 @@ static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f)
                        goto ref;
 #endif
                } else if (SCF_OP_CALL == c->op->type) {
-
                        assert(c->srcs->size > 0);
-                       src =  c->srcs->data[0];
 
-                       scf_dag_node_t* dn_pf = src->dag_node;
-                       scf_function_t* f2    = dn_pf->var->func_ptr;
-
-                       int ret = _auto_gc_find_argv_out(cur_bb, c);
+                       ret = _auto_gc_find_argv_out(cur_bb, c);
                        if (ret < 0)
                                return ret;
                        count += ret;
@@ -720,9 +518,9 @@ static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f)
                        if (ret < 0)
                                return ret;
 
-                       goto _end;
+                       goto end;
                } else
-                       goto _end;
+                       goto end;
 
                _bb_del_ds(cur_bb, ds_obj);
                count++;
@@ -745,10 +543,6 @@ ref:
                                        || SCF_OP_CREATE == dn->node->split_parent->type);
                        }
 
-                       scf_variable_t* v = dn->var;
-                       if (v->w)
-                               scf_logd("dn: %p, type: %d, v: %d/%s\n", dn, dn->type, v->w->line, v->w->text->data);
-
                        scf_dag_node_t* dn_pf = dn->childs->data[0];
                        scf_function_t* f2    = dn_pf->var->func_ptr;
                        scf_variable_t* ret   = f2->rets->data[0];
@@ -758,7 +552,10 @@ ref:
                        if (!strcmp(f2->node.w->text->data, "scf__auto_malloc")) {
                                _bb_add_ds(cur_bb, ds_obj);
                                count++;
-                               goto _end;
+
+                               scf_dn_status_free(ds_obj);
+                               ds_obj = NULL;
+                               goto end;
 
                        } else if (ret->auto_gc_flag) {
 
@@ -767,14 +564,17 @@ ref:
                                        scf_list_add_tail(&cur_bb->code_list_head, &c->list);
                                }
 
-                               _bb_add_ds(cur_bb, ds_obj);
-                               _bb_add_ds_for_ret(cur_bb, ds_obj, f2, c);
+                               _bb_add_ds        (cur_bb, ds_obj);
+                               _bb_add_ds_for_ret(cur_bb, ds_obj, f2);
 
                                ds = scf_dn_status_alloc(dn);
-                               if (!ds)
+                               if (!ds) {
+                                       scf_dn_status_free(ds_obj);
                                        return -ENOMEM;
-
+                               }
                                _bb_del_ds(cur_bb, ds);
+
+                               scf_dn_status_free(ds);
                                ds = NULL;
 
                                if (l != scf_list_sentinel(&bb->code_list_head)) {
@@ -784,18 +584,28 @@ ref:
                                        scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node);
                                }
 
+                               scf_dn_status_free(ds_obj);
+                               ds_obj = NULL;
+
                                count++;
                                continue;
                        }
                } else {
                        ds  = NULL;
-                       int ret = scf_ds_for_dn(&ds, dn);
-                       if (ret < 0)
+                       ret = scf_ds_for_dn(&ds, dn);
+                       if (ret < 0) {
+                               scf_dn_status_free(ds_obj);
                                return ret;
+                       }
 
                        ret = _bb_find_ds_alias(ds, c, bb, &f->basic_block_list_head);
-                       if (ret < 0)
+
+                       scf_dn_status_free(ds);
+                       ds = NULL;
+                       if (ret < 0) {
+                               scf_dn_status_free(ds_obj);
                                return ret;
+                       }
 
                        if (1 == ret) {
                                if (cur_bb != bb) {
@@ -812,6 +622,9 @@ ref:
                                        scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node);
                                }
 
+                               scf_dn_status_free(ds_obj);
+                               ds_obj = NULL;
+
                                count++;
                                continue;
                        }
@@ -819,8 +632,7 @@ ref:
 
                scf_dn_status_free(ds_obj);
                ds_obj = NULL;
-
-_end:
+end:
                if (cur_bb != bb) {
                        scf_list_del(&c->list);
                        scf_list_add_tail(&cur_bb->code_list_head, &c->list);
@@ -830,132 +642,39 @@ _end:
        return count;
 }
 
-static int _auto_gc_bb_next_find(scf_basic_block_t* bb, void* data, scf_vector_t* queue)
-{
-       scf_basic_block_t* next_bb;
-       scf_dn_status_t*   ds;
-       scf_dn_status_t*   ds2;
-
-       int count = 0;
-       int ret;
-       int j;
-
-       for (j = 0; j < bb->nexts->size; j++) {
-               next_bb   = bb->nexts->data[j];
-
-               int k;
-               for (k = 0; k < bb->ds_malloced->size; k++) {
-                       ds =        bb->ds_malloced->data[k];
-
-                       if (scf_vector_find_cmp(bb->ds_freed, ds, scf_ds_cmp_same_indexes))
-                               continue;
-
-                       if (scf_vector_find_cmp(next_bb->ds_freed, ds, scf_ds_cmp_same_indexes))
-                               continue;
-
-                       ds2 = scf_vector_find_cmp(next_bb->ds_malloced, ds, scf_ds_cmp_like_indexes);
-                       if (ds2) {
-                               uint32_t tmp = ds2->ret;
-
-                               ds2->ret |= ds->ret;
-
-                               if (tmp != ds2->ret)
-                                       count++;
-                               continue;
-                       }
-
-                       ds2 = scf_dn_status_clone(ds);
-                       if (!ds2)
-                               return -ENOMEM;
-
-                       ret = scf_vector_add(next_bb->ds_malloced, ds2);
-                       if (ret < 0)
-                               return ret;
-                       ++count;
-               }
-
-               ret = scf_vector_add(queue, next_bb);
-               if (ret < 0)
-                       return ret;
-       }
-       return count;
-}
-
-static int _bfs_sort_function(scf_vector_t* fqueue, scf_function_t* fmalloc)
-{
-       scf_function_t* f;
-       scf_function_t* f2;
-
-       int ret = scf_vector_add(fqueue, fmalloc);
-       if (ret < 0)
-               return ret;
-
-       int i;
-       for (i = 0; i < fqueue->size; i++) {
-               f  =        fqueue->data[i];
-
-               if (f->visited_flag)
-                       continue;
-
-               scf_logd("f: %p, %s\n", f, f->node.w->text->data);
-
-               f->visited_flag = 1;
-
-               int j;
-               for (j = 0; j < f->caller_functions->size; j++) {
-                       f2 =        f->caller_functions->data[j];
-
-                       if (f2->visited_flag)
-                               continue;
-
-                       ret = scf_vector_add(fqueue, f2);
-                       if (ret < 0)
-                               return ret;
-               }
-       }
-
-       return 0;
-}
-
 static int _bb_find_ds_alias_leak(scf_dn_status_t* ds_obj, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
 {
-       scf_dn_status_t* ds_obj2;
-       scf_dn_status_t* ds_alias;
-       scf_dn_index_t*  di;
+       scf_dn_status_t* ds;
        scf_vector_t*    aliases;
-
-       int ret;
        int i;
 
        aliases = scf_vector_alloc();
        if (!aliases)
                return -ENOMEM;
 
-       ret = scf_pointer_alias_ds_leak(aliases, ds_obj, c, bb, bb_list_head);
-       if (ret < 0) {
-               scf_vector_free(aliases);
-               return ret;
-       }
+       int ret = scf_pointer_alias_ds_leak(aliases, ds_obj, c, bb, bb_list_head);
+       if (ret < 0)
+               goto error;
 
-       int need = 0;
        for (i = 0; i < aliases->size; i++) {
-               ds_alias  = aliases->data[i];
+               ds =        aliases->data[i];
 
-               SCF_XCHG(ds_alias->dn_indexes, ds_alias->alias_indexes);
-               SCF_XCHG(ds_alias->dag_node,   ds_alias->alias);
+               SCF_XCHG(ds->dn_indexes, ds->alias_indexes);
+               SCF_XCHG(ds->dag_node,   ds->alias);
 
-               if (!ds_alias->dag_node)
+               if (!ds->dag_node)
                        continue;
 
-               ret = __bb_add_ds(bb, ds_obj, bb, ds_alias);
+               ret = __bb_add_ds_append(bb, ds_obj, bb, ds);
                if (ret < 0) {
                        scf_loge("\n");
-                       return ret;
+                       goto error;
                }
        }
 
-       ret = need;
+       ret = 0;
 error:
+       scf_vector_clear(aliases, ( void (*)(void*) )scf_dn_status_free);
        scf_vector_free (aliases);
        return ret;
 }
@@ -977,7 +696,7 @@ static int _auto_gc_function_find(scf_ast_t* ast, scf_function_t* f, scf_list_t*
        int count;
        int ret;
 
-       scf_loge("f: %s\n", f->node.w->text->data);
+       scf_logw("f: %s\n", f->node.w->text->data);
 
        do {
                for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) {
@@ -1036,30 +755,16 @@ static int _auto_gc_function_find(scf_ast_t* ast, scf_function_t* f, scf_list_t*
        return total;
 }
 
-static int _auto_gc_global_find(scf_ast_t* ast, scf_vector_t* functions)
+static int _optimize_auto_gc_find(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
 {
-       scf_function_t* fmalloc = NULL;
-       scf_function_t* f;
-       scf_vector_t*   fqueue;
-
-       int i;
-       for (i = 0; i < functions->size; i++) {
-               f  =        functions->data[i];
-
-               f->visited_flag = 0;
-
-               if (!fmalloc && !strcmp(f->node.w->text->data, "scf__auto_malloc"))
-                       fmalloc = f;
-       }
-
-       if (!fmalloc)
-               return 0;
+       if (!ast || !functions || functions->size <= 0)
+               return -EINVAL;
 
-       fqueue = scf_vector_alloc();
+       scf_vector_t* fqueue = scf_vector_alloc();
        if (!fqueue)
                return -ENOMEM;
 
-       int ret = _bfs_sort_function(fqueue, fmalloc);
+       int ret = _bfs_sort_function(fqueue, functions);
        if (ret < 0) {
                scf_vector_free(fqueue);
                return ret;
@@ -1072,6 +777,7 @@ static int _auto_gc_global_find(scf_ast_t* ast, scf_vector_t* functions)
                total0 = total1;
                total1 = 0;
 
+               int i;
                for (i = 0; i < fqueue->size; i++) {
                        f  =        fqueue->data[i];
 
@@ -1083,7 +789,7 @@ static int _auto_gc_global_find(scf_ast_t* ast, scf_vector_t* functions)
 
                        ret = _auto_gc_function_find(ast, f, &f->basic_block_list_head);
                        if (ret < 0) {
-                               scf_loge("\n");
+                               scf_vector_free(fqueue);
                                return ret;
                        }
 
@@ -1094,20 +800,7 @@ static int _auto_gc_global_find(scf_ast_t* ast, scf_vector_t* functions)
 
        } while (total0 != total1);
 
-       return 0;
-}
-
-static int _optimize_auto_gc_find(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions)
-{
-       if (!ast || !functions || functions->size <= 0)
-               return -EINVAL;
-
-       int ret = _auto_gc_global_find(ast, functions);
-       if (ret < 0) {
-               scf_loge("\n");
-               return ret;
-       }
-
+       scf_vector_free(fqueue);
        return 0;
 }
 
index 4663abd43517fd5f79ebdad90ff1130cc40711ce..ea870531d826598a4b4e337c85eac4c11d16873b 100644 (file)
@@ -171,7 +171,7 @@ static int __optimize_call_bb(scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list
                                bb1->ret_flag         = bb0->ret_flag; \
                                bb0->ret_flag         = 0; \
                                scf_list_add_front(&bb0->list, &bb1->list); \
-                               scf_basic_block_mov_code(start, bb1, bb0); \
+                               scf_basic_block_mov_code(bb1, start, bb0); \
                        } while (0)
 
 static int _optimize_call_bb(scf_basic_block_t* bb, scf_list_t* bb_list_head)
@@ -265,4 +265,3 @@ scf_optimizer_t  scf_optimizer_call =
 
        .flags    = SCF_OPTIMIZER_LOCAL,
 };
-
index ffa7d141be00dbd20f5ddd3939c2c87401eca623..70858192e2c4ddba9f9b52a82c1841ce0ccab22b 100644 (file)
@@ -7,13 +7,13 @@ static int __bb_dfs_tree(scf_basic_block_t* root, scf_vector_t* edges, int* tota
 
        assert(!root->jmp_flag);
 
-       root->visited_flag = 1;
+       root->visit_flag = 1;
 
        int i;
        for (i = 0; i < root->nexts->size; ++i) {
                bb =        root->nexts->data[i];
 
-               if (bb->visited_flag)
+               if (bb->visit_flag)
                        continue;
 
                edge = malloc(sizeof(scf_bb_edge_t));
@@ -54,7 +54,7 @@ static int _bb_dfs_tree(scf_list_t* bb_list_head, scf_function_t* f)
        for (l = scf_list_tail(bb_list_head); l != scf_list_sentinel(bb_list_head); l = scf_list_prev(l)) {
                bb = scf_list_data(l, scf_basic_block_t, list);
 
-               bb->visited_flag = 0;
+               bb->visit_flag = 0;
 
                if (!bb->jmp_flag)
                        ++total;
index 6a6f50e1642dead54dc6787f7c8f6eb97f32d58d..eeea59d232e12515387e1116214660b17c55cd38 100644 (file)
@@ -7,12 +7,12 @@ static int __bb_dfs_loop2(scf_basic_block_t* root, scf_vector_t* loop)
 
        assert(!root->jmp_flag);
 
-       root->visited_flag = 1;
+       root->visit_flag = 1;
 
        for (i = 0; i < root->prevs->size; ++i) {
                bb =        root->prevs->data[i];
 
-               if (bb->visited_flag)
+               if (bb->visit_flag)
                        continue;
 
                int ret = scf_vector_add(loop, bb);
@@ -29,9 +29,6 @@ static int __bb_dfs_loop2(scf_basic_block_t* root, scf_vector_t* loop)
 
 static int __bb_dfs_loop(scf_list_t* bb_list_head, scf_basic_block_t* bb, scf_basic_block_t* dom, scf_vector_t* loop)
 {
-       scf_list_t*        l;
-       scf_basic_block_t* bb2;
-
        int ret = scf_vector_add(loop, bb);
        if (ret < 0)
                return ret;
@@ -43,15 +40,9 @@ static int __bb_dfs_loop(scf_list_t* bb_list_head, scf_basic_block_t* bb, scf_ba
        if (ret < 0)
                return ret;
 
-       for (l  = scf_list_tail(bb_list_head); l != scf_list_sentinel(bb_list_head); l = scf_list_prev(l)) {
-               bb2 = scf_list_data(l, scf_basic_block_t, list);
-
-               if (bb2->jmp_flag)
-                       continue;
+       scf_basic_block_visit_flag(bb_list_head, 0);
 
-               bb2->visited_flag = 0;
-       }
-       dom->visited_flag = 1;
+       dom->visit_flag = 1;
 
        return __bb_dfs_loop2(bb, loop);
 }
@@ -467,35 +458,10 @@ static int _bb_loop_add_pre_post(scf_function_t* f)
                        jmp = scf_list_data(scf_list_prev(&exit->list), scf_basic_block_t, list);
 
                        if (!jmp->jmp_flag) {
-
-                               scf_3ac_operand_t* dst;
-                               scf_3ac_code_t*    c;
-
-                               jmp = scf_basic_block_alloc();
+                               jmp = scf_basic_block_jcc(exit, f, SCF_OP_GOTO);
                                if (!jmp)
                                        return -ENOMEM;
 
-                               c = scf_3ac_jmp_code(SCF_OP_GOTO, NULL, NULL);
-                               if (!c) {
-                                       scf_basic_block_free(jmp);
-                                       return -ENOMEM;
-                               }
-
-                               if (scf_vector_add(f->jmps, c) < 0) {
-                                       scf_3ac_code_free(c);
-                                       scf_basic_block_free(jmp);
-                                       return -ENOMEM;
-                               }
-
-                               jmp->jmp_flag  = 1;
-
-                               c->basic_block = jmp;
-
-                               dst     = c->dsts->data[0];
-                               dst->bb = exit;
-
-                               scf_list_add_tail(&jmp->code_list_head, &c->list);
-
                                scf_list_add_tail(&exit->list, &jmp->list);
                        }
 
index 71a4ce327e660cbf61fb9c8d4757f1dc871f5fb1..8c61410a84e52841d093f6a9e01143d27726b946 100644 (file)
@@ -536,7 +536,7 @@ static int _optimize_alias_bb(scf_basic_block_t* bb, scf_list_t* bb_list_head)
                bb2->dereference_flag = 0;
                bb2->array_index_flag = bb->array_index_flag;
 
-               scf_basic_block_mov_code(scf_list_next(end), bb2, bb);
+               scf_basic_block_mov_code(bb2, scf_list_next(end), bb);
 
                scf_list_add_front(&bb->list, &bb2->list);
 
index b31907c4b6c60770c84ac26de33f0fbd51cedfc7..2232ac77d5b59d2efc5f5f3ba002eaecb0e3e2ff 100644 (file)
@@ -12,14 +12,14 @@ static int __bb_dfs_initeds(scf_basic_block_t* root, scf_dn_status_t* ds, scf_ve
 
        assert(!root->jmp_flag);
 
-       root->visited_flag = 1;
+       root->visit_flag = 1;
 
        int like = scf_dn_status_is_like(ds);
 
        for (i = 0; i < root->prevs->size; ++i) {
                bb =        root->prevs->data[i];
 
-               if (bb->visited_flag)
+               if (bb->visit_flag)
                        continue;
 
                for (j = 0; j < bb->dn_status_initeds->size; j++) {
@@ -40,7 +40,7 @@ static int __bb_dfs_initeds(scf_basic_block_t* root, scf_dn_status_t* ds, scf_ve
                        if (ret < 0)
                                return ret;
 
-                       bb->visited_flag = 1;
+                       bb->visit_flag = 1;
                        continue;
                }
 
@@ -62,15 +62,15 @@ static int __bb_dfs_check_initeds(scf_basic_block_t* root, scf_basic_block_t* ob
        if (root == obj)
                return -1;
 
-       if (root->visited_flag)
+       if (root->visit_flag)
                return 0;
 
-       root->visited_flag = 1;
+       root->visit_flag = 1;
 
        for (i = 0; i < root->nexts->size; ++i) {
                bb =        root->nexts->data[i];
 
-               if (bb->visited_flag)
+               if (bb->visit_flag)
                        continue;
 
                if (bb == obj)
@@ -86,16 +86,7 @@ static int __bb_dfs_check_initeds(scf_basic_block_t* root, scf_basic_block_t* ob
 
 static int _bb_dfs_initeds(scf_list_t* bb_list_head, scf_basic_block_t* bb, scf_dn_status_t* ds, scf_vector_t* initeds)
 {
-       scf_list_t*        l;
-       scf_basic_block_t* bb2;
-
-       for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head);
-                       l = scf_list_next(l)) {
-
-               bb2 = scf_list_data(l, scf_basic_block_t, list);
-
-               bb2->visited_flag = 0;
-       }
+       scf_basic_block_visit_flag(bb_list_head, 0);
 
        return __bb_dfs_initeds(bb, ds, initeds);
 }
@@ -104,21 +95,14 @@ static int _bb_dfs_check_initeds(scf_list_t* bb_list_head, scf_basic_block_t* bb
 {
        scf_list_t*        l;
        scf_basic_block_t* bb2;
-
        int i;
 
-       for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head);
-                       l = scf_list_next(l)) {
-
-               bb2 = scf_list_data(l, scf_basic_block_t, list);
-
-               bb2->visited_flag = 0;
-       }
+       scf_basic_block_visit_flag(bb_list_head, 0);
 
        for (i = 0; i < initeds->size; i++) {
                bb2       = initeds->data[i];
 
-               bb2->visited_flag = 1;
+               bb2->visit_flag = 1;
        }
 
        l   = scf_list_head(bb_list_head);