--- /dev/null
+#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;
+}
--- /dev/null
+#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;
+}
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) {
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)
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);
if (ret < 0)
return ret;
- bb->visited_flag = 1;
+ bb->visit_flag = 1;
continue;
}
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;
+ }
+}
#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;
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;
};
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();
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
#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)
{
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);
}
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;
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)
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;
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;
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);
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;
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;
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)
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)) {
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);
}
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)) {
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];
}
}
- 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;
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);
}
}
- 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;
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;
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;
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;
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;
} 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;
#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;
}
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();
}
}
- 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;
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) {
}
_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();
}
}
- 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);
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); \
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);
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);
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)
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;
if (ret < 0)
return ret;
- goto _end;
+ goto end;
} else
- goto _end;
+ goto end;
_bb_del_ds(cur_bb, ds_obj);
count++;
|| 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];
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) {
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)) {
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) {
scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node);
}
+ scf_dn_status_free(ds_obj);
+ ds_obj = NULL;
+
count++;
continue;
}
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);
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;
}
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); ) {
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;
total0 = total1;
total1 = 0;
+ int i;
for (i = 0; i < fqueue->size; i++) {
f = fqueue->data[i];
ret = _auto_gc_function_find(ast, f, &f->basic_block_list_head);
if (ret < 0) {
- scf_loge("\n");
+ scf_vector_free(fqueue);
return ret;
}
} 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;
}
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)
.flags = SCF_OPTIMIZER_LOCAL,
};
-
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));
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;
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);
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;
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);
}
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);
}
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);
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++) {
if (ret < 0)
return ret;
- bb->visited_flag = 1;
+ bb->visit_flag = 1;
continue;
}
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)
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);
}
{
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);