From 6589169b3609fb1fab401ded3ac57827fda8055d Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Sun, 13 Oct 2024 00:39:35 +0800 Subject: [PATCH] support auto gc for multi-return-values --- core/scf_3ac.c | 4 +- core/scf_auto_gc_3ac.c | 8 +- core/scf_auto_gc_find.c | 14 +- core/scf_basic_block.c | 1 - core/scf_basic_block.h | 2 - core/scf_core_types.h | 4 +- core/scf_dag.c | 4 +- core/scf_dag.h | 4 +- core/scf_function.c | 25 +- core/scf_function.h | 4 +- core/scf_operator.c | 157 +++--- core/scf_operator.h | 12 +- core/scf_optimizer_auto_gc.c | 571 ++++++++++------------ core/scf_optimizer_auto_gc_find.c | 355 +++++++++----- core/scf_optimizer_generate_loads_saves.c | 44 +- examples/auto_gc_multi_rets.c | 27 + examples/mat.c | 71 --- native/risc/scf_risc_inst.c | 4 +- native/risc/scf_risc_rcg.c | 4 +- native/x64/scf_x64_inst.c | 62 ++- native/x64/scf_x64_rcg.c | 4 +- parse/scf_dfa_function.c | 2 + parse/scf_dfa_operator.c | 3 +- parse/scf_operator_handler_semantic.c | 4 +- 24 files changed, 738 insertions(+), 652 deletions(-) create mode 100644 examples/auto_gc_multi_rets.c diff --git a/core/scf_3ac.c b/core/scf_3ac.c index 5f0374e..ba65074 100644 --- a/core/scf_3ac.c +++ b/core/scf_3ac.c @@ -102,8 +102,8 @@ static scf_3ac_operator_t _3ac_operators[] = { {SCF_OP_3AC_RELOAD, "reload"}, {SCF_OP_3AC_RESAVE, "resave"}, - {SCF_OP_3AC_PUSH_RAX, "push rax"}, - {SCF_OP_3AC_POP_RAX, "pop rax"}, + {SCF_OP_3AC_PUSH_RETS, "push rets"}, + {SCF_OP_3AC_POP_RETS, "pop rets"}, {SCF_OP_3AC_MEMSET, "memset"}, {SCF_OP_3AC_INC, "inc3"}, diff --git a/core/scf_auto_gc_3ac.c b/core/scf_auto_gc_3ac.c index ca34c27..5006aef 100644 --- a/core/scf_auto_gc_3ac.c +++ b/core/scf_auto_gc_3ac.c @@ -1070,7 +1070,7 @@ static int _bb_add_gc_code_ref(scf_list_t* dag_list_head, scf_ast_t* ast, scf_ba scf_list_t h; scf_list_init(&h); - if (scf_vector_add_unique(bb->dn_reloads, ds->dag_node) < 0) + if (scf_vector_add_unique(bb->entry_dn_actives, ds->dag_node) < 0) return -ENOMEM; int ret = _auto_gc_code_list_ref(&h, dag_list_head, ast, ds); @@ -1086,7 +1086,7 @@ static int _bb_add_gc_code_freep(scf_list_t* dag_list_head, scf_ast_t* ast, scf_ scf_list_t h; scf_list_init(&h); - if (scf_vector_add_unique(bb->dn_reloads, ds->dag_node) < 0) + if (scf_vector_add_unique(bb->entry_dn_actives, ds->dag_node) < 0) return -ENOMEM; int ret = _auto_gc_code_list_freep(&h, dag_list_head, ast, ds); @@ -1102,7 +1102,7 @@ static int _bb_add_gc_code_memset_array(scf_list_t* dag_list_head, scf_ast_t* as scf_list_t h; scf_list_init(&h); - if (scf_vector_add_unique(bb->dn_reloads, dn_array) < 0) + if (scf_vector_add_unique(bb->entry_dn_actives, dn_array) < 0) return -ENOMEM; int ret = _auto_gc_code_list_memset_array(&h, dag_list_head, ast, dn_array); @@ -1118,7 +1118,7 @@ static int _bb_add_gc_code_free_array(scf_list_t* dag_list_head, scf_ast_t* ast, scf_list_t h; scf_list_init(&h); - if (scf_vector_add_unique(bb->dn_reloads, dn_array) < 0) + if (scf_vector_add_unique(bb->entry_dn_actives, dn_array) < 0) return -ENOMEM; int ret = _auto_gc_code_list_free_array(&h, dag_list_head, ast, dn_array); diff --git a/core/scf_auto_gc_find.c b/core/scf_auto_gc_find.c index 8e8d595..012d2df 100644 --- a/core/scf_auto_gc_find.c +++ b/core/scf_auto_gc_find.c @@ -193,7 +193,7 @@ static int _auto_gc_find_argv_in(scf_basic_block_t* cur_bb, scf_3ac_code_t* c) scf_logd("v: %s\n", v->w->text->data); - if (scf_vector_add_unique(cur_bb->dn_reloads, dn) < 0) + if (scf_vector_add_unique(cur_bb->entry_dn_actives, dn) < 0) return -ENOMEM; } @@ -225,12 +225,18 @@ static int _auto_gc_bb_next_find(scf_basic_block_t* bb, void* data, scf_vector_t ds2 = scf_vector_find_cmp(next_bb->ds_malloced, ds, scf_ds_cmp_like_indexes); if (ds2) { - uint32_t tmp = ds2->ret; + uint32_t tmp = ds2->ret_flag; - ds2->ret |= ds->ret; + ds2->ret_flag |= ds->ret_flag; + + if (tmp != ds2->ret_flag) { + scf_logd("*** ds2: %#lx, ret_index: %d, ret_flag: %d, ds: %#lx, ret_index: %d, ret_flag: %d\n", + 0xffff & (uintptr_t)ds2, ds2->ret_index, ds2->ret_flag, + 0xffff & (uintptr_t)ds, ds->ret_index, ds->ret_flag); - if (tmp != ds2->ret) count++; + ds2->ret_index = ds->ret_index; + } continue; } diff --git a/core/scf_basic_block.c b/core/scf_basic_block.c index 3ea1b5f..9939875 100644 --- a/core/scf_basic_block.c +++ b/core/scf_basic_block.c @@ -90,7 +90,6 @@ scf_basic_block_t* scf_basic_block_alloc() if (!bb->ds_freed) goto error_freed; - bb->generate_flag = 1; return bb; error_freed: diff --git a/core/scf_basic_block.h b/core/scf_basic_block.h index 49c1280..eec1060 100644 --- a/core/scf_basic_block.h +++ b/core/scf_basic_block.h @@ -95,8 +95,6 @@ struct scf_basic_block_s uint32_t auto_ref_flag :1; uint32_t auto_free_flag:1; - uint32_t generate_flag :1; - uint32_t back_flag :1; uint32_t loop_flag :1; uint32_t group_flag :1; diff --git a/core/scf_core_types.h b/core/scf_core_types.h index 956acab..a3e8468 100644 --- a/core/scf_core_types.h +++ b/core/scf_core_types.h @@ -193,8 +193,8 @@ enum scf_core_types SCF_OP_3AC_PUSH, // push a var to stack, only for 3ac & native SCF_OP_3AC_POP, // pop a var from stack, only for 3ac & native - SCF_OP_3AC_PUSH_RAX, // push rax, only for 3ac & native - SCF_OP_3AC_POP_RAX, // pop rax, only for 3ac & native + SCF_OP_3AC_PUSH_RETS, // push return value registers, only for 3ac & native + SCF_OP_3AC_POP_RETS, // pop return value registers, only for 3ac & native SCF_OP_3AC_MEMSET, // diff --git a/core/scf_dag.c b/core/scf_dag.c index 85ab1d0..6290c18 100644 --- a/core/scf_dag.c +++ b/core/scf_dag.c @@ -234,7 +234,9 @@ scf_dn_status_t* scf_dn_status_clone(scf_dn_status_t* ds) ds2->active = ds->active; ds2->inited = ds->inited; ds2->updated = ds->updated; - ds2->ret = ds->ret; + + ds2->ret_flag = ds->ret_flag; + ds2->ret_index = ds->ret_index; return ds2; } diff --git a/core/scf_dag.h b/core/scf_dag.h index 9ca0cdc..b58923f 100644 --- a/core/scf_dag.h +++ b/core/scf_dag.h @@ -75,11 +75,13 @@ struct scf_dn_status_s { intptr_t color; + int ret_index; + uint32_t ret_flag:1; + uint32_t active :1; uint32_t inited :1; uint32_t updated:1; uint32_t loaded :1; - uint32_t ret :1; }; scf_dn_index_t* scf_dn_index_alloc(); diff --git a/core/scf_function.c b/core/scf_function.c index ff2884a..46bf26b 100644 --- a/core/scf_function.c +++ b/core/scf_function.c @@ -224,17 +224,16 @@ int scf_function_same_type(scf_function_t* f0, scf_function_t* f1) int scf_function_signature(scf_function_t* f) { + scf_string_t* s; + scf_type_t* t = (scf_type_t*)f->node.parent; + int ret; int i; - if (f->signature) - scf_string_free(f->signature); - - scf_string_t* s = scf_string_alloc(); + s = scf_string_alloc(); if (!s) return -ENOMEM; - scf_type_t* t = (scf_type_t*)f->node.parent; if (t->node.type >= SCF_STRUCT) { assert(t->node.class_flag); @@ -247,12 +246,24 @@ int scf_function_signature(scf_function_t* f) goto error; } - ret = scf_string_cat(s, f->node.w->text); + if (f->op_type >= 0) { + scf_operator_t* op = scf_find_base_operator_by_type(f->op_type); + + if (!op->signature) + goto error; + + ret = scf_string_cat_cstr(s, op->signature); + } else + ret = scf_string_cat(s, f->node.w->text); + if (ret < 0) goto error; scf_logd("f signature: %s\n", s->data); if (t->node.type < SCF_STRUCT) { + if (f->signature) + scf_string_free(f->signature); + f->signature = s; return 0; } @@ -287,6 +298,8 @@ int scf_function_signature(scf_function_t* f) scf_logd("f signature: %s\n", s->data); + if (f->signature) + scf_string_free(f->signature); f->signature = s; return 0; diff --git a/core/scf_function.h b/core/scf_function.h index bccf075..d6d987c 100644 --- a/core/scf_function.h +++ b/core/scf_function.h @@ -51,7 +51,6 @@ struct scf_function_s { int local_vars_size; int code_bytes; - uint32_t vargs_flag :1; uint32_t visited_flag:1; uint32_t bp_used_flag:1; @@ -59,6 +58,9 @@ struct scf_function_s { uint32_t extern_flag:1; uint32_t inline_flag:1; uint32_t member_flag:1; + + uint32_t vargs_flag :1; + uint32_t void_flag :1; }; scf_function_t* scf_function_alloc(scf_lex_word_t* w); diff --git a/core/scf_operator.c b/core/scf_operator.c index 7440af4..8d870b0 100644 --- a/core/scf_operator.c +++ b/core/scf_operator.c @@ -1,84 +1,85 @@ #include"scf_operator.h" #include"scf_core_types.h" -static scf_operator_t base_operators[] = { - {SCF_OP_EXPR, "(", 0, 1, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_CALL, "(", 1, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_ARRAY_INDEX, "[", 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_POINTER, "->", 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_VA_START, "va_start", 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_VA_ARG, "va_arg", 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_VA_END, "va_end", 1, 1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_CONTAINER, "container", 1, 3, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_CREATE, "create", 2, -1, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_TYPE_CAST, "(", 2, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_LOGIC_NOT, "!", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_BIT_NOT, "~", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_NEG, "-", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_POSITIVE, "+", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_SIZEOF, "sizeof", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - - {SCF_OP_INC, "++", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_DEC, "--", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - - {SCF_OP_INC_POST, "++", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_DEC_POST, "--", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - - {SCF_OP_DEREFERENCE, "*", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_ADDRESS_OF, "&", 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, - - {SCF_OP_MUL, "*", 4, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_DIV, "/", 4, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_MOD, "%", 4, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_ADD, "+", 5, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_SUB, "-", 5, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_SHL, "<<", 6, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_SHR, ">>", 6, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_BIT_AND, "&", 7, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_BIT_OR, "|", 7, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_EQ, "==", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_NE, "!=", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_GT, ">", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_LT, "<", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_GE, ">=", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_LE, "<=", 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_LOGIC_AND, "&&", 9, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_LOGIC_OR, "||", 9, 2, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_ASSIGN, "=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_ADD_ASSIGN, "+=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_SUB_ASSIGN, "-=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_MUL_ASSIGN, "*=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_DIV_ASSIGN, "/=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_MOD_ASSIGN, "%=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_SHL_ASSIGN, "<<=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_SHR_ASSIGN, ">>=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_AND_ASSIGN, "&=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - {SCF_OP_OR_ASSIGN, "|=", 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, - - {SCF_OP_BLOCK, "{}", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_RETURN, "return", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_BREAK, "break", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_CONTINUE, "continue", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_GOTO, "goto", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_LABEL, "label", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_IF, "if", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_WHILE, "while", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_DO, "do", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_FOR, "for", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - - {SCF_OP_SWITCH, "switch", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_CASE, "case", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, - {SCF_OP_DEFAULT, "default", 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, +static scf_operator_t base_operators[] = +{ + {"(", NULL, SCF_OP_EXPR, 0, 1, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"(", NULL, SCF_OP_CALL, 1, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"[", "i", SCF_OP_ARRAY_INDEX, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"->", "p", SCF_OP_POINTER, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"va_start", NULL, SCF_OP_VA_START, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"va_arg", NULL, SCF_OP_VA_ARG, 1, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"va_end", NULL, SCF_OP_VA_END, 1, 1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"container", NULL, SCF_OP_CONTAINER, 1, 3, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"create", NULL, SCF_OP_CREATE, 2, -1, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"(", NULL, SCF_OP_TYPE_CAST, 2, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"!", "not", SCF_OP_LOGIC_NOT, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"~", "bnot", SCF_OP_BIT_NOT, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"-", "neg", SCF_OP_NEG, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"+", "pos", SCF_OP_POSITIVE, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"sizeof", NULL, SCF_OP_SIZEOF, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + + {"++", "inc", SCF_OP_INC, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"--", "dec", SCF_OP_DEC, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + + {"++", "inc", SCF_OP_INC_POST, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"--", "dec", SCF_OP_DEC_POST, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + + {"*", NULL, SCF_OP_DEREFERENCE, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"&", NULL, SCF_OP_ADDRESS_OF, 2, 1, SCF_OP_ASSOCIATIVITY_RIGHT}, + + {"*", "mul", SCF_OP_MUL, 4, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"/", "div", SCF_OP_DIV, 4, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"%", "mod", SCF_OP_MOD, 4, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"+", "add", SCF_OP_ADD, 5, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"-", "sub", SCF_OP_SUB, 5, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"<<", NULL, SCF_OP_SHL, 6, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {">>", NULL, SCF_OP_SHR, 6, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"&", "band", SCF_OP_BIT_AND, 7, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"|", "bor", SCF_OP_BIT_OR, 7, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"==", "eq", SCF_OP_EQ, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"!=", "ne", SCF_OP_NE, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {">", "gt", SCF_OP_GT, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"<", "lt", SCF_OP_LT, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {">=", "ge", SCF_OP_GE, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"<=", "le", SCF_OP_LE, 8, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"&&", NULL, SCF_OP_LOGIC_AND, 9, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + {"||", NULL, SCF_OP_LOGIC_OR, 9, 2, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"=", "a", SCF_OP_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"+=", "add_", SCF_OP_ADD_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"-=", "sub_", SCF_OP_SUB_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"*=", "mul_", SCF_OP_MUL_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"/=", "div_", SCF_OP_DIV_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"%=", "mod_", SCF_OP_MOD_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"<<=", NULL, SCF_OP_SHL_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {">>=", NULL, SCF_OP_SHR_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"&=", "and_", SCF_OP_AND_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + {"|=", "or_", SCF_OP_OR_ASSIGN, 10, 2, SCF_OP_ASSOCIATIVITY_RIGHT}, + + {"{}", NULL, SCF_OP_BLOCK, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"return", NULL, SCF_OP_RETURN, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"break", NULL, SCF_OP_BREAK, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"continue", NULL, SCF_OP_CONTINUE, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"goto", NULL, SCF_OP_GOTO, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"label", NULL, SCF_LABEL, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"if", NULL, SCF_OP_IF, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"while", NULL, SCF_OP_WHILE, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"do", NULL, SCF_OP_DO, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"for", NULL, SCF_OP_FOR, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + + {"switch", NULL, SCF_OP_SWITCH, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"case", NULL, SCF_OP_CASE, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, + {"default", NULL, SCF_OP_DEFAULT, 15, -1, SCF_OP_ASSOCIATIVITY_LEFT}, }; scf_operator_t* scf_find_base_operator(const char* name, const int nb_operands) diff --git a/core/scf_operator.h b/core/scf_operator.h index 88159e4..ab8ddca 100644 --- a/core/scf_operator.h +++ b/core/scf_operator.h @@ -9,12 +9,13 @@ struct scf_operator_s { - int type; - char* name; + char* name; + char* signature; + int type; - int priority; - int nb_operands; - int associativity; + int priority; + int nb_operands; + int associativity; }; scf_operator_t* scf_find_base_operator(const char* name, const int nb_operands); @@ -22,4 +23,3 @@ scf_operator_t* scf_find_base_operator(const char* name, const int nb_operands); scf_operator_t* scf_find_base_operator_by_type(const int type); #endif - diff --git a/core/scf_optimizer_auto_gc.c b/core/scf_optimizer_auto_gc.c index c0b6cd2..5ea1bf8 100644 --- a/core/scf_optimizer_auto_gc.c +++ b/core/scf_optimizer_auto_gc.c @@ -3,6 +3,8 @@ #include"scf_auto_gc_3ac.c" +int __auto_gc_ds_for_assign(scf_dn_status_t** ds, scf_dag_node_t** dn, scf_3ac_code_t* c); + static int _find_ds_malloced(scf_basic_block_t* bb, void* data) { scf_dn_status_t* ds = data; @@ -30,6 +32,9 @@ static int _find_dn_active(scf_basic_block_t* bb, void* data) if (scf_vector_find(bb->dn_reloads, data)) return 1; + if (scf_vector_find(bb->entry_dn_actives, data)) + return 1; + scf_logd("bb: %p, dn: %s, 0\n", bb, dn->var->w->text->data); return 0; } @@ -97,8 +102,8 @@ static int _bb_add_active(scf_basic_block_t* bb, scf_dag_node_t* dn) if (scf_type_is_operator(dn->type)) ret = scf_vector_add(bb->dn_reloads, dn); - else - ret = scf_vector_add(bb->dn_loads, dn); +// else +// ret = scf_vector_add(bb->dn_loads, dn); return ret; } @@ -186,19 +191,25 @@ static int _bb_split_prev_add_free(scf_ast_t* ast, scf_function_t* f, scf_basic_ return -ENOMEM; } + scf_vector_free(bb1->prevs); + bb1->prevs = bb_split_prevs; + bb_split_prevs = NULL; + bb1->ds_auto_gc = scf_dn_status_clone(ds); - if (!bb1->ds_auto_gc) + if (!bb1->ds_auto_gc) { + scf_basic_block_free(bb1); return -ENOMEM; + } + + int ret = scf_vector_add(bb1->nexts, bb); + if (ret < 0) { + scf_basic_block_free(bb1); + return ret; + } bb1->call_flag = 1; bb1->auto_free_flag = 1; - scf_vector_add( bb1->nexts, bb); - scf_vector_free(bb1->prevs); - - bb1->prevs = bb_split_prevs; - bb_split_prevs = NULL; - scf_list_add_tail(&bb->list, &bb1->list); scf_3ac_operand_t* dst; @@ -285,13 +296,13 @@ static int _bb_split_prev_add_free(scf_ast_t* ast, scf_function_t* f, scf_basic_ if (!ds3) return -ENOMEM; - int ret = scf_vector_add(bb1->ds_malloced, ds3); + ret = scf_vector_add(bb1->ds_malloced, ds3); if (ret < 0) return ret; } } - int ret = _bb_add_gc_code_freep(&f->dag_list_head, ast, bb1, ds); + ret = _bb_add_gc_code_freep(&f->dag_list_head, ast, bb1, ds); if (ret < 0) return ret; @@ -323,17 +334,67 @@ static int _bb_split_prevs(scf_basic_block_t* bb, scf_dn_status_t* ds, scf_vecto return 0; } +static int _bb_add_last_free(scf_dn_status_t* ds, scf_basic_block_t* bb, scf_ast_t* ast, scf_function_t* f) +{ + scf_vector_t* vec = scf_vector_alloc(); + if (!vec) + return -ENOMEM; + + scf_basic_block_t* bb2; + int j; + int dfo = 0; + + int ret = _bb_find_ds_malloced(bb, &f->basic_block_list_head, ds, vec); + if (ret < 0) { + scf_vector_free(vec); + return ret; + } + +#define AUTO_GC_FIND_MAX_DFO() \ + do { \ + for (j = 0; j < vec->size; j++) { \ + bb2 = vec->data[j]; \ + \ + if (bb2->dfo > dfo) \ + dfo = bb2->dfo; \ + } \ + } while (0) + AUTO_GC_FIND_MAX_DFO(); + vec->size = 0; + + ret = _bb_find_dn_active(bb, &f->basic_block_list_head, ds->dag_node, vec); + if (ret < 0) { + scf_vector_free(vec); + return ret; + } + AUTO_GC_FIND_MAX_DFO(); + vec->size = 0; + + for (j = 0; j < bb->dominators->size; j++) { + bb2 = bb->dominators->data[j]; + + if (bb2->dfo > dfo) + break; + } + + ret = _bb_split_prevs(bb2, ds, vec); + if (ret < 0) { + scf_vector_free(vec); + return ret; + } + + return _bb_split_prev_add_free(ast, f, bb2, ds, vec); +} + static int _auto_gc_last_free(scf_ast_t* ast, scf_function_t* f) { - scf_list_t* bb_list_head = &f->basic_block_list_head; - scf_list_t* l; + scf_list_t* l = scf_list_tail(&f->basic_block_list_head); scf_basic_block_t* bb; scf_dn_status_t* ds; scf_dag_node_t* dn; scf_variable_t* v; scf_vector_t* local_arrays; - l = scf_list_tail(bb_list_head); bb = scf_list_data(l, scf_basic_block_t, list); scf_logd("bb: %p, bb->ds_malloced->size: %d\n", bb, bb->ds_malloced->size); @@ -344,27 +405,23 @@ static int _auto_gc_last_free(scf_ast_t* ast, scf_function_t* f) int ret; int i; - for (i = 0; i < bb->ds_malloced->size; ) { + + for (i = 0; i < bb->ds_malloced->size; i++) { ds = bb->ds_malloced->data[i]; dn = ds->dag_node; v = dn->var; - 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_logw("%s(), last free: v_%d_%d/%s, ds->ret_flag: %u\n", + f->node.w->text->data, v->w->line, v->w->pos, v->w->text->data, ds->ret_flag); scf_dn_status_print(ds); - if (ds->ret) { - i++; + if (ds->ret_flag) continue; - } if (ds->dn_indexes) { - - scf_dn_index_t* di; - - int var_index = 0; int j; + scf_dn_index_t* di; for (j = ds->dn_indexes->size - 1; j >= 0; j--) { di = ds->dn_indexes->data[j]; @@ -374,81 +431,24 @@ static int _auto_gc_last_free(scf_ast_t* ast, scf_function_t* f) break; } - if (-1 == di->index) - var_index++; - } - - if (var_index > 0) { - if (v->nb_dimentions > 0 && v->local_flag) { + if (-1 == di->index) { + if (v->nb_dimentions > 0 && v->local_flag) { - if (scf_vector_add_unique(local_arrays, dn) < 0) - return -ENOMEM; + ret = scf_vector_add_unique(local_arrays, dn); + if (ret < 0) + goto error; + } + break; } - - i++; - continue; } - if (j >= 0) { - i++; + if (j >= 0) continue; - } - } - - scf_vector_t* vec = scf_vector_alloc(); - if (!vec) - return -ENOMEM; - - scf_basic_block_t* bb1; - scf_basic_block_t* bb_dominator; - - int dfo = 0; - int j; - - ret = _bb_find_ds_malloced(bb, bb_list_head, ds, vec); - if (ret < 0) { - scf_vector_free(vec); - return ret; - } -#define AUTO_GC_FIND_MAX_DFO() \ - do { \ - for (j = 0; j < vec->size; j++) { \ - bb1 = vec->data[j]; \ - \ - if (bb1->dfo > dfo) \ - dfo = bb1->dfo; \ - } \ - } while (0) - AUTO_GC_FIND_MAX_DFO(); - - vec->size = 0; - - ret = _bb_find_dn_active(bb, bb_list_head, dn, vec); - if (ret < 0) { - scf_vector_free(vec); - return ret; - } - AUTO_GC_FIND_MAX_DFO(); - - for (j = 0; j < bb->dominators->size; j++) { - bb_dominator = bb->dominators->data[j]; - - if (bb_dominator->dfo > dfo) - break; - } - - vec->size = 0; - - ret = _bb_split_prevs(bb_dominator, ds, vec); - if (ret < 0) { - scf_vector_free(vec); - return ret; } - ret = _bb_split_prev_add_free(ast, f, bb_dominator, ds, vec); + ret = _bb_add_last_free(ds, bb, ast, f); if (ret < 0) - return ret; - i++; + goto error; } for (i = 0; i < local_arrays->size; i++) { @@ -456,14 +456,17 @@ static int _auto_gc_last_free(scf_ast_t* ast, scf_function_t* f) ret = _bb_add_memset_array(ast, f, dn); if (ret < 0) - return ret; + goto error; ret = _bb_add_free_arry(ast, f, bb, dn); if (ret < 0) - return ret; + goto error; } - return 0; + ret = 0; +error: + scf_vector_free(local_arrays); + return ret; } #define AUTO_GC_BB_SPLIT(parent, child) \ @@ -486,19 +489,29 @@ static int _auto_gc_last_free(scf_ast_t* ast, scf_function_t* f) scf_list_add_front(&parent->list, &child->list); \ } while (0) -static int _optimize_auto_gc_bb_ref(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t** pbb, scf_list_t* bb_list_head, scf_dn_status_t* ds) +static int _auto_gc_bb_split(scf_basic_block_t* parent, scf_basic_block_t** pchild) +{ + scf_basic_block_t* child = NULL; + + AUTO_GC_BB_SPLIT(parent, child); + + *pchild = child; + return 0; +} + +static int _auto_gc_bb_ref(scf_dn_status_t* ds_obj, scf_vector_t* ds_malloced, scf_ast_t* ast, scf_function_t* f, scf_basic_block_t** pbb) { scf_basic_block_t* cur_bb = *pbb; scf_basic_block_t* bb1 = NULL; - scf_dag_node_t* dn = ds->dag_node; + scf_dag_node_t* dn = ds_obj->dag_node; AUTO_GC_BB_SPLIT(cur_bb, bb1); - bb1->ds_auto_gc = scf_dn_status_clone(ds); + bb1->ds_auto_gc = scf_dn_status_clone(ds_obj); if (!bb1->ds_auto_gc) return -ENOMEM; - int ret = _bb_add_gc_code_ref(&f->dag_list_head, ast, bb1, ds); + int ret = _bb_add_gc_code_ref(&f->dag_list_head, ast, bb1, ds_obj); if (ret < 0) return ret; @@ -510,6 +523,14 @@ static int _optimize_auto_gc_bb_ref(scf_ast_t* ast, scf_function_t* f, scf_basic if (ret < 0) return ret; + if (!scf_vector_find_cmp(ds_malloced, ds_obj, scf_ds_cmp_like_indexes)) { + ret = scf_vector_add(ds_malloced, ds_obj); + if (ret < 0) + return ret; + + scf_dn_status_ref(ds_obj); + } + bb1->call_flag = 1; bb1->dereference_flag = 0; bb1->auto_ref_flag = 1; @@ -518,7 +539,7 @@ static int _optimize_auto_gc_bb_ref(scf_ast_t* ast, scf_function_t* f, scf_basic return 0; } -static int _optimize_auto_gc_bb_free(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t** pbb, scf_dn_status_t* ds) +static int _bb_split_add_free(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t** pbb, scf_dn_status_t* ds) { scf_basic_block_t* cur_bb = *pbb; scf_basic_block_t* bb1 = NULL; @@ -589,44 +610,51 @@ static int _bb_prevs_malloced(scf_basic_block_t* bb, scf_vector_t* ds_malloced) 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); -static int _bb_need_ref(scf_dn_status_t* ds_obj, scf_vector_t* ds_malloced, - scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head) +static int _bb_need_ref(scf_dag_node_t* dn, scf_vector_t* ds_malloced, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head) { - scf_dn_status_t* ds_alias; + scf_dn_status_t* ds = NULL; scf_vector_t* aliases; - - int ret; int i; + int ret = scf_ds_for_dn(&ds, dn); + if (ret < 0) + return ret; + + if (scf_vector_find_cmp(ds_malloced, ds, scf_ds_cmp_like_indexes)) { + scf_dn_status_free(ds); + return 1; + } + aliases = scf_vector_alloc(); - if (!aliases) + if (!aliases) { + scf_dn_status_free(ds); return -ENOMEM; + } - ret = __bb_find_ds_alias(aliases, ds_obj, c, bb, bb_list_head); - if (ret < 0) - return ret; + ret = __bb_find_ds_alias(aliases, ds, c, bb, bb_list_head); - scf_logd("aliases->size: %d\n", aliases->size); + scf_dn_status_free(ds); + ds = NULL; + if (ret < 0) + goto error; - int need = 0; + ret = 0; for (i = 0; i < aliases->size; i++) { - ds_alias = aliases->data[i]; + ds = aliases->data[i]; - if (!ds_alias->dag_node) + if (!ds->dag_node) continue; - if (scf_vector_find_cmp(ds_malloced, ds_alias, scf_ds_cmp_like_indexes)) { - need = 1; + if (scf_vector_find_cmp(ds_malloced, ds, scf_ds_cmp_like_indexes)) { + ret = 1; break; } } - if (scf_vector_find_cmp(ds_malloced, ds_obj, scf_ds_cmp_like_indexes)) { - need = 1; - } - +error: + scf_vector_clear(aliases, ( void (*)(void*) )scf_dn_status_free); scf_vector_free (aliases); - return need; + return ret; } static int _bb_split_prevs_need_free(scf_dn_status_t* ds_obj, scf_vector_t* ds_malloced, scf_vector_t* bb_split_prevs, scf_basic_block_t* bb) @@ -643,168 +671,149 @@ static int _bb_split_prevs_need_free(scf_dn_status_t* ds_obj, scf_vector_t* ds_m return 0; } -static int _optimize_auto_gc_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_list_t* bb_list_head) +static int _auto_gc_bb_free(scf_dn_status_t* ds_obj, scf_vector_t* ds_malloced, scf_vector_t* ds_assigned, scf_ast_t* ast, + scf_function_t* f, + scf_basic_block_t* bb, + scf_basic_block_t** cur_bb) { - scf_list_t* l; - scf_3ac_code_t* c; - scf_vector_t* ds_malloced; - scf_vector_t* ds_assigned; - - scf_basic_block_t* bb_prev = NULL; - scf_basic_block_t* cur_bb = bb; - - ds_malloced = scf_vector_alloc(); - if (!ds_malloced) - return -ENOMEM; + scf_vector_t* bb_split_prevs = scf_vector_alloc(); - ds_assigned = scf_vector_alloc(); - if (!ds_assigned) + if (!bb_split_prevs) return -ENOMEM; - // at first, the malloced vars, are ones malloced in previous blocks - - int ret = _bb_prevs_malloced(bb, ds_malloced); + int ret = _bb_split_prevs_need_free(ds_obj, ds_malloced, bb_split_prevs, bb); if (ret < 0) { - scf_vector_clear(ds_malloced, ( void (*)(void*) )scf_dn_status_free); - scf_vector_free(ds_malloced); + scf_vector_free(bb_split_prevs); return ret; } - for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) { + if (ret) { + if (!scf_vector_find_cmp(ds_assigned, ds_obj, scf_ds_cmp_like_indexes) + && bb_split_prevs->size > 0 + && bb_split_prevs->size < bb->prevs->size) { - 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; + return _bb_split_prev_add_free(ast, f, bb, ds_obj, bb_split_prevs); + } - scf_3ac_operand_t* dst; - scf_3ac_operand_t* src; - scf_dag_node_t* dn; - scf_dn_status_t* ds_obj; - scf_variable_t* v0; + ret = _bb_split_add_free(ast, f, cur_bb, ds_obj); + } - if (SCF_OP_ASSIGN == c->op->type) { + scf_vector_free(bb_split_prevs); + bb_split_prevs = NULL; + return ret; +} - dst = c->dsts->data[0]; - v0 = dst->dag_node->var; +static int _auto_gc_retval(scf_dn_status_t* ds_obj, scf_dag_node_t* dn, scf_vector_t* ds_malloced, scf_3ac_code_t* c, scf_function_t* f) +{ + scf_dag_node_t* pf; + scf_function_t* f2; + scf_variable_t* fret; + scf_node_t* parent; + scf_node_t* result; - if (!scf_variable_may_malloced(v0)) - goto _end; + int i = 0; - ds_obj = NULL; + if (dn->node->split_flag) { + parent = dn->node->split_parent; - ret = scf_ds_for_dn(&ds_obj, dst->dag_node); - if (!ds_obj) - return -ENOMEM; + assert(SCF_OP_CALL == parent->type || SCF_OP_CREATE == parent->type); - src = c->srcs->data[0]; - dn = src->dag_node; + for (i = 0; i < parent->result_nodes->size; i++) { + result = parent->result_nodes->data[i]; - } else if (SCF_OP_3AC_ASSIGN_ARRAY_INDEX == c->op->type) { + if (dn->node == result) + break; + } + } - assert(4 == c->srcs->size); + pf = dn->childs->data[0]; + f2 = pf->var->func_ptr; + fret = f2->rets->data[i]; - base = c->srcs->data[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); + if (!strcmp(f2->node.w->text->data, "scf__auto_malloc") || fret->auto_gc_flag) { - if (!scf_variable_may_malloced(v0)) - goto _end; + assert(SCF_OP_RETURN != c->op->type); +// fret = f->rets->data[i]; +// fret->auto_gc_flag = 1; - ds_obj = NULL; + if (!scf_vector_find_cmp(ds_malloced, ds_obj, scf_ds_cmp_like_indexes)) { - int ret = scf_ds_for_assign_array_member(&ds_obj, base->dag_node, index->dag_node, scale->dag_node); + int ret = scf_vector_add(ds_malloced, ds_obj); if (ret < 0) return ret; - if (ds_obj->dag_node->var->arg_flag) - ds_obj->ret = 1; - - } else if (SCF_OP_3AC_ASSIGN_POINTER == c->op->type) { - - assert(3 == c->srcs->size); + scf_dn_status_ref(ds_obj); + } + } - base = c->srcs->data[0]; - member = c->srcs->data[1]; - src = c->srcs->data[2]; - dn = src->dag_node; - v0 = member->dag_node->var; + return 0; +} - if (!scf_variable_may_malloced(v0)) - goto _end; +static int _optimize_auto_gc_bb(scf_ast_t* ast, scf_function_t* f, scf_basic_block_t* bb, scf_list_t* bb_list_head) +{ + scf_basic_block_t* cur_bb = bb; + scf_basic_block_t* bb2; + scf_3ac_code_t* c; + scf_vector_t* ds_malloced; + scf_vector_t* ds_assigned; + scf_list_t* l; - ds_obj = NULL; + ds_malloced = scf_vector_alloc(); + if (!ds_malloced) + return -ENOMEM; - int ret = scf_ds_for_assign_member(&ds_obj, base->dag_node, member->dag_node); - if (ret < 0) - return ret; + ds_assigned = scf_vector_alloc(); + if (!ds_assigned) { + scf_vector_free(ds_malloced); + return -ENOMEM; + } - if (ds_obj->dag_node->var->arg_flag) - ds_obj->ret = 1; + // at first, the malloced vars, are ones malloced in previous blocks - } else if (SCF_OP_3AC_ASSIGN_DEREFERENCE == c->op->type) { + int ret = _bb_prevs_malloced(bb, ds_malloced); + if (ret < 0) + goto error; - assert(2 == c->srcs->size); + for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) { - src = c->srcs->data[1]; - dn = src->dag_node; - v0 = dn->var; + c = scf_list_data(l, scf_3ac_code_t, list); + l = scf_list_next(l); - if (!scf_variable_may_malloced(v0)) - goto _end; + scf_dn_status_t* ds_obj = NULL; + scf_dn_status_t* ds = NULL; + scf_dag_node_t* dn = NULL; - src = c->srcs->data[0]; - 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, src->dag_node); + ret = __auto_gc_ds_for_assign(&ds_obj, &dn, c); if (ret < 0) - return ret; + goto error; - } else - goto _end; - - scf_vector_t* bb_split_prevs = scf_vector_alloc(); - if (!bb_split_prevs) - return -ENOMEM; - - ret = _bb_split_prevs_need_free(ds_obj, ds_malloced, bb_split_prevs, bb); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - - if (ret) { - if (!scf_vector_find_cmp(ds_assigned, ds_obj, scf_ds_cmp_like_indexes) - && bb_split_prevs->size > 0 - && bb_split_prevs->size < bb->prevs->size) - - ret = _bb_split_prev_add_free(ast, f, bb, ds_obj, bb_split_prevs); - else { - scf_vector_free(bb_split_prevs); - bb_split_prevs = NULL; + if (!ds_obj) + goto end; - ret = _optimize_auto_gc_bb_free(ast, f, &cur_bb, ds_obj); + if (SCF_OP_ASSIGN != c->op->type) { + if (ds_obj->dag_node->var->arg_flag) + ds_obj->ret_flag = 1; } + } else + goto end; - if (ret < 0) - return ret; - } else { - scf_vector_free(bb_split_prevs); - bb_split_prevs = NULL; + ret = _auto_gc_bb_free(ds_obj, ds_malloced, ds_assigned, ast, f, bb, &cur_bb); + if (ret < 0) { + scf_dn_status_free(ds_obj); + goto error; } - if (scf_vector_add(ds_assigned, ds_obj) < 0) { + ret = scf_vector_add(ds_assigned, ds_obj); + if (ret < 0) { scf_dn_status_free(ds_obj); - return -ENOMEM; + goto error; } - -_ref: +ref: if (!dn->var->local_flag && cur_bb != bb) dn ->var->tmp_flag = 1; @@ -820,100 +829,54 @@ _ref: if (SCF_OP_CALL == dn->type || dn->node->split_flag) { - if (dn->node->split_flag) { - assert(SCF_OP_CALL == dn->node->split_parent->type - || SCF_OP_CREATE == dn->node->split_parent->type); - } - - scf_dag_node_t* dn_pf; - scf_function_t* f2; - scf_variable_t* ret; - - dn_pf = dn->childs->data[0]; - f2 = dn_pf->var->func_ptr; - ret = f2->rets->data[0]; - - if (!strcmp(f2->node.w->text->data, "scf__auto_malloc") || ret->auto_gc_flag) { - - if (SCF_OP_RETURN == c->op->type) { - ret = f->rets->data[0]; - ret->auto_gc_flag = 1; - } - - if (!scf_vector_find_cmp(ds_malloced, ds_obj, scf_ds_cmp_like_indexes)) { - - assert(0 == scf_vector_add(ds_malloced, ds_obj)); - } else { - scf_dn_status_free(ds_obj); - ds_obj = NULL; - } - - if (cur_bb != bb) { - scf_list_del(&c->list); - scf_list_add_tail(&cur_bb->code_list_head, &c->list); - } - continue; - } - } else { - scf_dn_status_t* ds = NULL; - - ret = scf_ds_for_dn(&ds, dn); + ret = _auto_gc_retval(ds_obj, dn, ds_malloced, c, f); if (ret < 0) - return ret; - - int ret = _bb_need_ref(ds, ds_malloced, c, bb, bb_list_head); - - scf_dn_status_free(ds); - ds = NULL; + goto error; + } else { + ret = _bb_need_ref(dn, ds_malloced, c, bb, bb_list_head); if (ret < 0) - return ret; + goto error; if (ret > 0) { - scf_basic_block_t* bb2 = NULL; - - if (SCF_OP_RETURN == c->op->type) { - scf_variable_t* ret = f->rets->data[0]; - ret->auto_gc_flag = 1; - } + assert(SCF_OP_RETURN != c->op->type); +// scf_variable_t* fret = f->rets->data[0]; +// fret->auto_gc_flag = 1; if (cur_bb != bb) { scf_list_del(&c->list); scf_list_add_tail(&cur_bb->code_list_head, &c->list); } - int ret = _optimize_auto_gc_bb_ref(ast, f, &cur_bb, bb_list_head, ds_obj); + ret = _auto_gc_bb_ref(ds_obj, ds_malloced, ast, f, &cur_bb); if (ret < 0) - return ret; - - if (!scf_vector_find_cmp(ds_malloced, ds_obj, scf_ds_cmp_like_indexes)) { - - assert(0 == scf_vector_add(ds_malloced, ds_obj)); - } else { - scf_dn_status_free(ds_obj); - ds_obj = NULL; - } + goto error; if (l != scf_list_sentinel(&bb->code_list_head)) { + bb2 = NULL; + ret = _auto_gc_bb_split(cur_bb, &bb2); + if (ret < 0) + goto error; - AUTO_GC_BB_SPLIT(cur_bb, bb2); cur_bb = bb2; } - 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 0; + ret = 0; +error: + scf_vector_clear(ds_assigned, ( void (*)(void*) )scf_dn_status_free); + scf_vector_clear(ds_malloced, ( void (*)(void*) )scf_dn_status_free); + scf_vector_free (ds_assigned); + scf_vector_free (ds_malloced); + return ret; } static int _optimize_auto_gc(scf_ast_t* ast, scf_function_t* f, scf_vector_t* functions) diff --git a/core/scf_optimizer_auto_gc_find.c b/core/scf_optimizer_auto_gc_find.c index 549f261..6e0bf9b 100644 --- a/core/scf_optimizer_auto_gc_find.c +++ b/core/scf_optimizer_auto_gc_find.c @@ -33,7 +33,8 @@ static int _bb_add_ds(scf_basic_block_t* bb, scf_dn_status_t* ds_obj) } } - ds->ret |= ds_obj->ret; + ds->ret_flag |= ds_obj->ret_flag; + ds->ret_index = ds_obj->ret_index; return 0; } @@ -236,7 +237,7 @@ static int _bb_add_ds_for_ret(scf_basic_block_t* bb, scf_dn_status_t* ds_obj, sc for (i = 0; i < bb2->ds_malloced->size; i++) { ds2 = bb2->ds_malloced->data[i]; - if (!ds2->ret) + if (!ds2->ret_flag) continue; __bb_add_ds_append(bb, ds_obj, bb2, ds2); @@ -320,9 +321,9 @@ static int _auto_gc_find_argv_out(scf_basic_block_t* cur_bb, scf_3ac_code_t* c) return ret; if (ds_obj->dag_node->var->arg_flag) - ds_obj->ret = 1; + ds_obj->ret_flag = 1; - ret = scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node); + ret = scf_vector_add_unique(cur_bb->entry_dn_actives, ds_obj->dag_node); if (ret < 0) { scf_dn_status_free(ds_obj); return ret; @@ -348,31 +349,40 @@ static int _auto_gc_find_ret(scf_basic_block_t* cur_bb, scf_3ac_code_t* c) scf_3ac_operand_t* dst; scf_3ac_operand_t* src = c->srcs->data[0]; scf_function_t* f2 = src->dag_node->var->func_ptr; - scf_variable_t* ret = f2->rets->data[0]; + scf_variable_t* fret; scf_variable_t* v; scf_dn_status_t* ds_obj; - if (ret->auto_gc_flag) { - dst = c->dsts->data[0]; - v = dst->dag_node->var; + assert(c->dsts->size <= f2->rets->size); - if (!scf_variable_may_malloced(v)) - return 0; + int i; + for (i = 0; i < c->dsts->size; i++) { + dst = c->dsts->data[i]; - ds_obj = scf_dn_status_alloc(dst->dag_node); - if (!ds_obj) - return -ENOMEM; + fret = f2->rets->data[i]; + v = dst->dag_node->var; - _bb_add_ds(cur_bb, ds_obj); + scf_logd("--- f2: %s(), i: %d, auto_gc_flag: %d\n", f2->node.w->text->data, i, fret->auto_gc_flag); - scf_dn_status_free(ds_obj); - ds_obj = NULL; + if (fret->auto_gc_flag) { + if (!scf_variable_may_malloced(v)) + return 0; + + ds_obj = scf_dn_status_alloc(dst->dag_node); + if (!ds_obj) + return -ENOMEM; + + _bb_add_ds(cur_bb, ds_obj); + + scf_dn_status_free(ds_obj); + ds_obj = NULL; + } } return 0; } -static int __auto_gc_ds_for_assign(scf_dn_status_t** ds, scf_dag_node_t** dn, scf_3ac_code_t* c) +int __auto_gc_ds_for_assign(scf_dn_status_t** ds, scf_dag_node_t** dn, scf_3ac_code_t* c) { scf_3ac_operand_t* base; scf_3ac_operand_t* member; @@ -451,6 +461,145 @@ static int __auto_gc_ds_for_assign(scf_dn_status_t** ds, scf_dag_node_t** dn, sc return 0; } +static int _auto_gc_find_ref(scf_dn_status_t* ds_obj, scf_dag_node_t* dn, scf_3ac_code_t* c, + scf_basic_block_t* bb, + scf_basic_block_t* cur_bb, + scf_function_t* f) +{ + scf_dn_status_t* ds; + scf_dag_node_t* pf; + scf_function_t* f2; + scf_variable_t* fret; + scf_node_t* parent; + scf_node_t* result; + + if (SCF_OP_CALL == dn->type || dn->node->split_flag) { + int i = 0; + + if (dn->node->split_flag) { + parent = dn->node->split_parent; + + assert(SCF_OP_CALL == parent->type || SCF_OP_CREATE == parent->type); + + for (i = 0; i < parent->result_nodes->size; i++) { + result = parent->result_nodes->data[i]; + + if (dn->node == result) + break; + } + } + + pf = dn->childs->data[0]; + f2 = pf->var->func_ptr; + fret = f2->rets->data[i]; + + scf_logd("f2: %s, rets[%d], auto_gc_flag: %d\n", f2->node.w->text->data, i, fret->auto_gc_flag); + + if (!strcmp(f2->node.w->text->data, "scf__auto_malloc")) { + _bb_add_ds(cur_bb, ds_obj); + return 1; + } + + if (fret->auto_gc_flag) { + _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) + return -ENOMEM; + + _bb_del_ds(cur_bb, ds); + + scf_dn_status_free(ds); + ds = NULL; + return 2; + } + } else { + ds = NULL; + int ret = scf_ds_for_dn(&ds, dn); + if (ret < 0) + return ret; + + ret = _bb_find_ds_alias(ds, c, bb, &f->basic_block_list_head); + + scf_dn_status_free(ds); + ds = NULL; + if (ret < 0) + return ret; + + if (1 == ret) { + _bb_add_ds(cur_bb, ds_obj); + return 2; + } + } + + return 0; +} + +static int _auto_gc_find_return(scf_vector_t* objs, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_basic_block_t* cur_bb, scf_function_t* f) +{ + scf_3ac_operand_t* src; + scf_dn_status_t* ds_obj; + scf_dag_node_t* dn; + scf_variable_t* v; + + int count = 0; + int i; + + for (i = 0; i < c->srcs->size; i++) { + src = c->srcs->data[i]; + + dn = src->dag_node; + v = dn->var; + + if (!scf_variable_may_malloced(dn->var)) + continue; + + if (v->w) + scf_logd("v: %s, line: %d\n", v->w->text->data, v->w->line); + + while (dn) { + if (SCF_OP_TYPE_CAST == dn->type) + dn = dn->childs->data[0]; + + else if (SCF_OP_EXPR == dn->type) + dn = dn->childs->data[0]; + else + break; + } + + ds_obj = scf_dn_status_alloc(dn); + if (!ds_obj) + return -ENOMEM; + + ds_obj->ret_flag = 1; + ds_obj->ret_index = i; + + scf_logd("i: %d, ds: %#lx, ret_index: %d\n", i, 0xffffff &(uintptr_t)ds_obj, ds_obj->ret_index); +// scf_dn_status_print(ds_obj); + + int ret = _auto_gc_find_ref(ds_obj, dn, c, bb, cur_bb, f); + if (ret < 0) { + scf_dn_status_free(ds_obj); + return ret; + } + + count += ret > 0; + + if (ret > 1) { + ret = scf_vector_add(objs, ds_obj); + if (ret < 0) { + scf_dn_status_free(ds_obj); + return ret; + } + } else + scf_dn_status_free(ds_obj); + ds_obj = NULL; + } + + return count; +} + static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f) { scf_basic_block_t* cur_bb = bb; @@ -460,6 +609,7 @@ static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f) int count = 0; int ret; + int i; for (l = scf_list_head(&bb->code_list_head); l != scf_list_sentinel(&bb->code_list_head); ) { @@ -485,23 +635,49 @@ static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f) if (SCF_OP_ASSIGN != c->op->type) { if (ds_obj->dag_node->var->arg_flag) - ds_obj->ret = 1; + ds_obj->ret_flag = 1; } -#if 1 - } else if (SCF_OP_RETURN == c->op->type) { - src = c->srcs->data[0]; - dn = src->dag_node; - if (!scf_variable_may_malloced(dn->var)) - goto end; + } else if (SCF_OP_RETURN == c->op->type) { - ds_obj = scf_dn_status_alloc(dn); - if (!ds_obj) + scf_vector_t* objs = scf_vector_alloc(); + if (!objs) return -ENOMEM; - ds_obj->ret = 1; - goto ref; -#endif + ret = _auto_gc_find_return(objs, c, bb, cur_bb, f); + if (ret < 0) { + scf_vector_clear(objs, ( void (*)(void*) )scf_dn_status_free); + scf_vector_free (objs); + return ret; + } + count += ret; + + if (cur_bb != bb) { + scf_list_del(&c->list); + scf_list_add_tail(&cur_bb->code_list_head, &c->list); + } + + if (objs->size > 0 && l != scf_list_sentinel(&bb->code_list_head)) { + + AUTO_GC_FIND_BB_SPLIT(cur_bb, bb2); + cur_bb = bb2; + + for (i = 0; i < objs->size; i++) { + ds_obj = objs->data[i]; + + ret = scf_vector_add_unique(cur_bb->entry_dn_actives, ds_obj->dag_node); + if (ret < 0) { + scf_vector_clear(objs, ( void (*)(void*) )scf_dn_status_free); + scf_vector_free (objs); + return ret; + } + } + } + + scf_vector_clear(objs, ( void (*)(void*) )scf_dn_status_free); + scf_vector_free (objs); + continue; + } else if (SCF_OP_CALL == c->op->type) { assert(c->srcs->size > 0); @@ -524,7 +700,6 @@ static int _auto_gc_bb_find(scf_basic_block_t* bb, scf_function_t* f) _bb_del_ds(cur_bb, ds_obj); count++; - ref: while (dn) { if (SCF_OP_TYPE_CAST == dn->type) @@ -536,102 +711,34 @@ ref: break; } - if (SCF_OP_CALL == dn->type || dn->node->split_flag) { - - if (dn->node->split_flag) { - assert(SCF_OP_CALL == dn->node->split_parent->type - || SCF_OP_CREATE == dn->node->split_parent->type); - } - - 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]; - - scf_logd("f2: %s, ret->auto_gc_flag: %d\n", f2->node.w->text->data, ret->auto_gc_flag); - - if (!strcmp(f2->node.w->text->data, "scf__auto_malloc")) { - _bb_add_ds(cur_bb, ds_obj); - count++; - - scf_dn_status_free(ds_obj); - ds_obj = NULL; - goto end; - - } else if (ret->auto_gc_flag) { - - if (cur_bb != bb) { - scf_list_del(&c->list); - 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); - - ds = scf_dn_status_alloc(dn); - 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)) { + ret = _auto_gc_find_ref(ds_obj, dn, c, bb, cur_bb, f); + if (ret < 0) { + scf_dn_status_free(ds_obj); + return ret; + } - AUTO_GC_FIND_BB_SPLIT(cur_bb, bb2); - cur_bb = bb2; - scf_vector_add_unique(cur_bb->dn_reloads, ds_obj->dag_node); - } + count += ret > 0; - scf_dn_status_free(ds_obj); - ds_obj = NULL; + if (cur_bb != bb) { + scf_list_del(&c->list); + scf_list_add_tail(&cur_bb->code_list_head, &c->list); + } - count++; - continue; - } - } else { - ds = NULL; - ret = scf_ds_for_dn(&ds, dn); - if (ret < 0) { - scf_dn_status_free(ds_obj); - return ret; - } + if (ret > 1 && l != scf_list_sentinel(&bb->code_list_head)) { - ret = _bb_find_ds_alias(ds, c, bb, &f->basic_block_list_head); + AUTO_GC_FIND_BB_SPLIT(cur_bb, bb2); + cur_bb = bb2; - scf_dn_status_free(ds); - ds = NULL; + ret = scf_vector_add_unique(cur_bb->entry_dn_actives, ds_obj->dag_node); if (ret < 0) { scf_dn_status_free(ds_obj); return ret; } - - if (1 == ret) { - if (cur_bb != bb) { - scf_list_del(&c->list); - scf_list_add_tail(&cur_bb->code_list_head, &c->list); - } - - _bb_add_ds(cur_bb, ds_obj); - - if (l != scf_list_sentinel(&bb->code_list_head)) { - - AUTO_GC_FIND_BB_SPLIT(cur_bb, bb2); - cur_bb = bb2; - 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; + continue; end: if (cur_bb != bb) { scf_list_del(&c->list); @@ -691,12 +798,13 @@ static int _auto_gc_function_find(scf_ast_t* ast, scf_function_t* f, scf_list_t* scf_basic_block_t* bb; scf_dn_status_t* ds; scf_3ac_code_t* c; + scf_variable_t* fret; int total = 0; - int count; + int count = 0; int ret; - scf_logw("f: %s\n", f->node.w->text->data); + scf_logw("--- %s() ---\n", f->node.w->text->data); do { for (l = scf_list_head(bb_list_head); l != scf_list_sentinel(bb_list_head); ) { @@ -733,24 +841,27 @@ static int _auto_gc_function_find(scf_ast_t* ast, scf_function_t* f, scf_list_t* int i; for (i = 0; i < bb->ds_malloced->size; i++) { ds = bb->ds_malloced->data[i]; + + if (!ds->ret_flag) + continue; #if 1 - scf_logi("ds->ret: %u, ds->dag_node->var->arg_flag: %u\n", ds->ret, ds->dag_node->var->arg_flag); + scf_logi("ds: %#lx, ds->ret_flag: %u, ds->ret_index: %d, ds->dag_node->var->arg_flag: %u\n", + 0xffff & (uintptr_t)ds, ds->ret_flag, ds->ret_index, ds->dag_node->var->arg_flag); scf_dn_status_print(ds); - printf("\n"); #endif - if (!ds->ret) - continue; if (ds->dag_node->var->arg_flag) ds->dag_node->var->auto_gc_flag = 1; else { - scf_variable_t* ret = f->rets->data[0]; - ret->auto_gc_flag = 1; + assert(ds->ret_index < f->rets->size); + + fret = f->rets->data[ds->ret_index]; + fret->auto_gc_flag = 1; _bb_find_ds_alias_leak(ds, c, bb, bb_list_head); } } - scf_logi("f: %s *****\n\n", f->node.w->text->data); + scf_logi("--- %s() ---\n\n", f->node.w->text->data); return total; } diff --git a/core/scf_optimizer_generate_loads_saves.c b/core/scf_optimizer_generate_loads_saves.c index c2d5ec2..cb026e8 100644 --- a/core/scf_optimizer_generate_loads_saves.c +++ b/core/scf_optimizer_generate_loads_saves.c @@ -68,31 +68,29 @@ static int _optimize_generate_loads_saves(scf_ast_t* ast, scf_function_t* f, scf bb->index = f->nb_basic_blocks++; - if (bb->generate_flag) { - for (i = 0; i < bb->dn_loads->size; i++) { - dn = bb->dn_loads->data[i]; + for (i = 0; i < bb->dn_loads->size; i++) { + dn = bb->dn_loads->data[i]; - if (scf_vector_find(bb->dn_reloads, dn)) - continue; + if (scf_vector_find(bb->dn_reloads, dn)) + continue; - SCF_OPTIMIZER_LOAD(SCF_OP_3AC_LOAD, &bb->code_list_head); - } + SCF_OPTIMIZER_LOAD(SCF_OP_3AC_LOAD, &bb->code_list_head); + } - for (i = 0; i < bb->dn_saves->size; i++) { - dn = bb->dn_saves->data[i]; + for (i = 0; i < bb->dn_saves->size; i++) { + dn = bb->dn_saves->data[i]; - if (scf_vector_find(bb->dn_resaves, dn)) - continue; + if (scf_vector_find(bb->dn_resaves, dn)) + continue; - if (bb->loop_flag) - SCF_OPTIMIZER_SAVE(SCF_OP_3AC_SAVE, &bb->save_list_head); - else { - SCF_OPTIMIZER_SAVE(SCF_OP_3AC_SAVE, &bb->code_list_head); + if (bb->loop_flag) + SCF_OPTIMIZER_SAVE(SCF_OP_3AC_SAVE, &bb->save_list_head); + else { + SCF_OPTIMIZER_SAVE(SCF_OP_3AC_SAVE, &bb->code_list_head); - if (bb->cmp_flag) { - scf_list_del(&save->list); - scf_list_add_front(&bb->code_list_head, &save->list); - } + if (bb->cmp_flag) { + scf_list_del(&save->list); + scf_list_add_front(&bb->code_list_head, &save->list); } } } @@ -113,16 +111,18 @@ static int _optimize_generate_loads_saves(scf_ast_t* ast, scf_function_t* f, scf } if (bb->auto_ref_flag || bb->auto_free_flag) { - +#if 1 scf_3ac_code_t* c0 = scf_3ac_code_alloc(); scf_3ac_code_t* c1 = scf_3ac_code_alloc(); - c0->op = scf_3ac_find_operator(SCF_OP_3AC_PUSH_RAX); - c1->op = scf_3ac_find_operator(SCF_OP_3AC_POP_RAX); + c0->op = scf_3ac_find_operator(SCF_OP_3AC_PUSH_RETS); + c1->op = scf_3ac_find_operator(SCF_OP_3AC_POP_RETS); scf_list_add_front(&bb->code_list_head, &c0->list); scf_list_add_tail(&bb->code_list_head, &c1->list); +#endif } + #if 1 scf_logd("bb: %p, bb->index: %d\n", bb, bb->index); ret = scf_basic_block_active_vars(bb); diff --git a/examples/auto_gc_multi_rets.c b/examples/auto_gc_multi_rets.c new file mode 100644 index 0000000..ee8be80 --- /dev/null +++ b/examples/auto_gc_multi_rets.c @@ -0,0 +1,27 @@ + +#include "../lib/scf_capi.c" + +int*, int* f() +{ + int* p0 = scf__auto_malloc(sizeof(int)); + int* p1 = scf__auto_malloc(sizeof(int)); + + *p0 = 1; + *p1 = 2; + + return p0, p1; +} + +int main(int argc, char* argv[]) +{ + int* p0; + int* p1; + + p0, p1 = f(); + + if (argc > 1) + return 1; + + printf("%d, %d\n", *p0, *p1); + return 0; +} diff --git a/examples/mat.c b/examples/mat.c index fb99a1c..aa4f5ef 100644 --- a/examples/mat.c +++ b/examples/mat.c @@ -66,76 +66,8 @@ struct mat return 0; } -/* int operator+=(mat* this, mat* that) - { - if (this->depth != that->depth - || this->width != that->width - || this->height != that->height - || this->count != that->count - || this->type != that->type) - return -1; - - if (MAT_TYPE_DOUBLE != this->type) - return -1; - - int64_t c; - int64_t y; - int64_t x; - int64_t z; - - double* d0 = (double*)this->data; - double* d1 = (double*)that->data; - - for (c = 0; c < this->count; c++) { - - int64_t c0 = this->c + this->cstep * c; - int64_t c1 = that->c + that->cstep * c; - - int64_t coffset0 = c0 * this->height * this->xstride; - int64_t coffset1 = c1 * that->height * that->xstride; - - for (y = 0; y < this->height; y++) { - - int64_t y0 = this->y + this->ystep * y; - int64_t y1 = that->y + that->ystep * y; - - int64_t yoffset0 = y0 * this->xstride * this->depth; - int64_t yoffset1 = y1 * that->xstride * that->depth; - - for (x = 0; x < this->width; x++) { - - int64_t x0 = this->x + this->xstep * x; - int64_t x1 = that->x + that->xstep * x; - - int64_t xoffset0 = x0 * this->depth; - int64_t xoffset1 = x1 * that->depth; - - for (z = 0; z < this->depth; z++) { - - int64_t z0 = this->z + this->zstep * z; - int64_t z1 = that->z + that->zstep * z; - - d0[coffset0 + yoffset0 + xoffset0 + z0] += d1[coffset1 + yoffset1 + xoffset1 + z1]; - } - } - } - } - - return 0; - } -*/ mat*, int operator+(mat* this, mat* that) { -/* if (this->depth != that->depth - || this->width != that->width - || this->height != that->height - || this->count != that->count - || this->type != that->type) - return NULL, -1; - - if (MAT_TYPE_DOUBLE != this->type) - return NULL, -1; -*/ mat* res; res = create mat(MAT_TYPE_DOUBLE, NULL, this->depth, this->width, this->height, this->count); @@ -217,15 +149,12 @@ int main() m2 = create mat(MAT_TYPE_DOUBLE, (uint8_t*)c, 1, 2, 2, 1); m3 = m0 + m1 + m2; -// scf_printf("%s(),%d\n", __func__, __LINE__); double* dd = (double*)m3->data; int i; for (i = 0; i < 4; i++) printf("m3: %lf\n", dd[i]); -// scf_printf("m1: %lf\n", *(double*)(m1->data + i * sizeof(double))); return 0; } - diff --git a/native/risc/scf_risc_inst.c b/native/risc/scf_risc_inst.c index fd0c4fd..6231fb1 100644 --- a/native/risc/scf_risc_inst.c +++ b/native/risc/scf_risc_inst.c @@ -5729,8 +5729,8 @@ static risc_inst_handler_pt risc_inst_handlers[SCF_N_3AC_OPS] = [SCF_OP_3AC_INC ] = _risc_inst_inc_handler, [SCF_OP_3AC_DEC ] = _risc_inst_dec_handler, - [SCF_OP_3AC_PUSH_RAX] = _risc_inst_push_rax_handler, - [SCF_OP_3AC_POP_RAX ] = _risc_inst_pop_rax_handler, + [SCF_OP_3AC_PUSH_RETS] = _risc_inst_push_rax_handler, + [SCF_OP_3AC_POP_RETS ] = _risc_inst_pop_rax_handler, [SCF_OP_3AC_MEMSET ] = _risc_inst_memset_handler, diff --git a/native/risc/scf_risc_rcg.c b/native/risc/scf_risc_rcg.c index 82eb8e4..629ce91 100644 --- a/native/risc/scf_risc_rcg.c +++ b/native/risc/scf_risc_rcg.c @@ -1220,8 +1220,8 @@ static risc_rcg_handler_pt risc_rcg_handlers[SCF_N_3AC_OPS] = [SCF_OP_3AC_INC ] = _risc_rcg_inc_handler, [SCF_OP_3AC_DEC ] = _risc_rcg_dec_handler, - [SCF_OP_3AC_PUSH_RAX] = _risc_rcg_push_rax_handler, - [SCF_OP_3AC_POP_RAX ] = _risc_rcg_pop_rax_handler, + [SCF_OP_3AC_PUSH_RETS] = _risc_rcg_push_rax_handler, + [SCF_OP_3AC_POP_RETS ] = _risc_rcg_pop_rax_handler, [SCF_OP_3AC_MEMSET ] = _risc_rcg_memset_handler, diff --git a/native/x64/scf_x64_inst.c b/native/x64/scf_x64_inst.c index be0cd86..951ef23 100644 --- a/native/x64/scf_x64_inst.c +++ b/native/x64/scf_x64_inst.c @@ -1844,7 +1844,7 @@ static int _x64_inst_address_of_pointer_handler(scf_native_t* ctx, scf_3ac_code_ return x64_inst_pointer(ctx, c, 1); } -static int _x64_inst_push_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _x64_inst_push_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c) { if (!c->instructions) { c->instructions = scf_vector_alloc(); @@ -1852,19 +1852,34 @@ static int _x64_inst_push_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - scf_register_t* rax = x64_find_register("rax"); - scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G); + scf_x64_context_t* x64 = ctx->priv; + scf_function_t* f = x64->f; + scf_instruction_t* inst; + scf_x64_OpCode_t* push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G); + scf_register_t* r; - inst = x64_make_inst_G(push, rax); - X64_INST_ADD_CHECK(c->instructions, inst); + int n = 0; + int i; + + if (!f->void_flag) { + n = f->rets->size; + + if (n > X64_ABI_RET_NB) + return -EINVAL; + } + + for (i = 0; i < n; i++) { + r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[i], 8); + + inst = x64_make_inst_G(push, r); + X64_INST_ADD_CHECK(c->instructions, inst); + } - inst = x64_make_inst_G(push, rax); - X64_INST_ADD_CHECK(c->instructions, inst); return 0; } -static int _x64_inst_pop_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c) +static int _x64_inst_pop_rets_handler(scf_native_t* ctx, scf_3ac_code_t* c) { if (!c->instructions) { c->instructions = scf_vector_alloc(); @@ -1872,15 +1887,30 @@ static int _x64_inst_pop_rax_handler(scf_native_t* ctx, scf_3ac_code_t* c) return -ENOMEM; } - scf_register_t* rax = x64_find_register("rax"); - scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8,8, SCF_X64_G); + scf_x64_context_t* x64 = ctx->priv; + scf_function_t* f = x64->f; + scf_instruction_t* inst; + scf_x64_OpCode_t* pop = x64_find_OpCode(SCF_X64_POP, 8,8, SCF_X64_G); + scf_register_t* r; - inst = x64_make_inst_G(pop, rax); - X64_INST_ADD_CHECK(c->instructions, inst); + int n = 0; + int i; + + if (!f->void_flag) { + n = f->rets->size; + + if (n > X64_ABI_RET_NB) + return -EINVAL; + } + + for (i = n - 1; i >= 0; i--) { + r = x64_find_register_type_id_bytes(0, x64_abi_ret_regs[i], 8); + + inst = x64_make_inst_G(pop, r); + X64_INST_ADD_CHECK(c->instructions, inst); + } - inst = x64_make_inst_G(pop, rax); - X64_INST_ADD_CHECK(c->instructions, inst); return 0; } @@ -2228,8 +2258,8 @@ static x64_inst_handler_pt x64_inst_handlers[] = [SCF_OP_3AC_INC ] = _x64_inst_inc_handler, [SCF_OP_3AC_DEC ] = _x64_inst_dec_handler, - [SCF_OP_3AC_PUSH_RAX] = _x64_inst_push_rax_handler, - [SCF_OP_3AC_POP_RAX ] = _x64_inst_pop_rax_handler, + [SCF_OP_3AC_PUSH_RETS] = _x64_inst_push_rets_handler, + [SCF_OP_3AC_POP_RETS] = _x64_inst_pop_rets_handler, [SCF_OP_3AC_MEMSET ] = _x64_inst_memset_handler, diff --git a/native/x64/scf_x64_rcg.c b/native/x64/scf_x64_rcg.c index 63a6b51..332b805 100644 --- a/native/x64/scf_x64_rcg.c +++ b/native/x64/scf_x64_rcg.c @@ -1322,8 +1322,8 @@ static x64_rcg_handler_pt x64_rcg_handlers[SCF_N_3AC_OPS] = [SCF_OP_3AC_INC ] = _x64_rcg_inc_handler, [SCF_OP_3AC_DEC ] = _x64_rcg_dec_handler, - [SCF_OP_3AC_PUSH_RAX] = _x64_rcg_push_rax_handler, - [SCF_OP_3AC_POP_RAX ] = _x64_rcg_pop_rax_handler, + [SCF_OP_3AC_PUSH_RETS] = _x64_rcg_push_rax_handler, + [SCF_OP_3AC_POP_RETS] = _x64_rcg_pop_rax_handler, [SCF_OP_3AC_MEMSET ] = _x64_rcg_memset_handler, diff --git a/parse/scf_dfa_function.c b/parse/scf_dfa_function.c index 9bbe184..2e7fe32 100644 --- a/parse/scf_dfa_function.c +++ b/parse/scf_dfa_function.c @@ -94,6 +94,8 @@ int _function_add_function(scf_dfa_t* dfa, dfa_data_t* d) return SCF_DFA_ERROR; } + f->void_flag = void_flag; + if (f->rets->size > 4) { scf_loge("function return values must NOT more than 4!\n"); return SCF_DFA_ERROR; diff --git a/parse/scf_dfa_operator.c b/parse/scf_dfa_operator.c index 3e54678..2d1abae 100644 --- a/parse/scf_dfa_operator.c +++ b/parse/scf_dfa_operator.c @@ -254,7 +254,8 @@ static int _operator_action_rp(scf_dfa_t* dfa, scf_vector_t* words, void* data) } } else { scf_operator_t* op = scf_find_base_operator(d->current_function->node.w->text->data, d->current_function->argv->size); - if (!op) { + + if (!op || !op->signature) { scf_loge("operator: '%s', nb_operands: %d\n", d->current_function->node.w->text->data, d->current_function->argv->size); return SCF_DFA_ERROR; diff --git a/parse/scf_operator_handler_semantic.c b/parse/scf_operator_handler_semantic.c index 7a1294a..7294b5f 100644 --- a/parse/scf_operator_handler_semantic.c +++ b/parse/scf_operator_handler_semantic.c @@ -2593,8 +2593,8 @@ static int _semantic_multi_rets_assign(scf_ast_t* ast, scf_node_t** nodes, int n assert(call->nb_nodes > 0); - scf_loge("rets->nb_nodes: %d, call->result_nodes: %p\n", rets->nb_nodes, call->result_nodes); - scf_loge("rets->nb_nodes: %d, call->result_nodes->size: %d\n", rets->nb_nodes, call->result_nodes->size); + scf_logd("rets->nb_nodes: %d, call->result_nodes: %p\n", rets->nb_nodes, call->result_nodes); + scf_logd("rets->nb_nodes: %d, call->result_nodes->size: %d\n", rets->nb_nodes, call->result_nodes->size); assert(rets->nb_nodes <= call->result_nodes->size); -- 2.25.1