From 46b6e4a099fc213368a49fa24653f50384183dd5 Mon Sep 17 00:00:00 2001 From: "yu.dongliang" Date: Tue, 18 Oct 2022 23:03:47 +0800 Subject: [PATCH] fix & optimize: pointer dereference in if condition --- core/scf_basic_block.c | 4 +- core/scf_dag.c | 15 ++- core/scf_optimizer_pointer_alias.c | 162 ++++++++++++++++++++++------- parse/scf_parse2.c | 2 +- 4 files changed, 138 insertions(+), 45 deletions(-) diff --git a/core/scf_basic_block.c b/core/scf_basic_block.c index e1b3ffb..323fa13 100644 --- a/core/scf_basic_block.c +++ b/core/scf_basic_block.c @@ -243,8 +243,8 @@ void scf_basic_block_print_list(scf_list_t* h) scf_basic_block_t* bb = scf_list_data(l, scf_basic_block_t, list); - printf("\033[33mbasic_block: %p, index: %d, dfo_normal: %d, cmp_flag: %d, group: %d, loop: %d\033[0m\n", - bb, bb->index, bb->dfo_normal, bb->cmp_flag, bb->group_flag, bb->loop_flag); + printf("\033[33mbasic_block: %p, index: %d, dfo_normal: %d, cmp_flag: %d, group: %d, loop: %d, dereference_flag: %d\033[0m\n", + bb, bb->index, bb->dfo_normal, bb->cmp_flag, bb->group_flag, bb->loop_flag, bb->dereference_flag); scf_basic_block_print(bb, sentinel); diff --git a/core/scf_dag.c b/core/scf_dag.c index ff590b7..0c6cbdb 100644 --- a/core/scf_dag.c +++ b/core/scf_dag.c @@ -831,12 +831,21 @@ scf_dag_node_t* scf_dag_find_node(scf_list_t* h, const scf_node_t* node) int scf_dag_get_node(scf_list_t* h, const scf_node_t* node, scf_dag_node_t** pp) { - scf_variable_t* v = _scf_operand_get((scf_node_t*)node); + const scf_node_t* node2; + scf_variable_t* v; + scf_dag_node_t* dn; - scf_dag_node_t* dn = scf_dag_find_node(h, node); + if (*pp) + node2 = (*pp)->node; + else + node2 = node; + + v = _scf_operand_get((scf_node_t*)node2); + + dn = scf_dag_find_node(h, node2); if (!dn) { - dn = scf_dag_node_alloc(node->type, v, node); + dn = scf_dag_node_alloc(node2->type, v, node2); if (!dn) return -ENOMEM; diff --git a/core/scf_optimizer_pointer_alias.c b/core/scf_optimizer_pointer_alias.c index 6c5a1ba..d73035e 100644 --- a/core/scf_optimizer_pointer_alias.c +++ b/core/scf_optimizer_pointer_alias.c @@ -1,23 +1,8 @@ #include"scf_optimizer.h" #include"scf_pointer_alias.h" -static int _3ac_pointer_alias(scf_dag_node_t* alias, scf_3ac_code_t* c, scf_basic_block_t* bb) +static int _filter_3ac_by_pointer_alias(scf_3ac_operand_t* pointer, scf_list_t* prev, scf_basic_block_t* bb) { - scf_3ac_operand_t* pointer; - - int ret; - - assert(c->srcs && c->srcs->size >= 1); - - pointer = c->srcs->data[0]; - - ret = scf_vector_del(c->srcs, pointer); - if (ret < 0) { - scf_loge("\n"); - return ret; - } - -#if 1 scf_3ac_code_t* c2; scf_3ac_code_t* c3; scf_list_t* l2; @@ -26,7 +11,7 @@ static int _3ac_pointer_alias(scf_dag_node_t* alias, scf_3ac_code_t* c, scf_basi scf_list_init(&h); - ret = scf_dag_expr_calculate(&h, pointer->dag_node); + int ret = scf_dag_expr_calculate(&h, pointer->dag_node); if (ret < 0) { scf_loge("\n"); return ret; @@ -37,7 +22,7 @@ static int _3ac_pointer_alias(scf_dag_node_t* alias, scf_3ac_code_t* c, scf_basi c2 = scf_list_data(l2, scf_3ac_code_t, list); l2 = scf_list_next(l2); - for (l3 = scf_list_prev(&c->list); l3 != scf_list_sentinel(&bb->code_list_head); ) { + for (l3 = prev; l3 != scf_list_sentinel(&bb->code_list_head); ) { c3 = scf_list_data(l3, scf_3ac_code_t, list); l3 = scf_list_prev(l3); @@ -52,6 +37,30 @@ static int _3ac_pointer_alias(scf_dag_node_t* alias, scf_3ac_code_t* c, scf_basi scf_list_del(&c2->list); scf_3ac_code_free(c2); } + + return 0; +} + +static int _3ac_pointer_alias(scf_dag_node_t* alias, scf_3ac_code_t* c, scf_basic_block_t* bb) +{ + scf_3ac_operand_t* pointer; + + int ret; + + assert(c->srcs && c->srcs->size >= 1); + + pointer = c->srcs->data[0]; + + ret = scf_vector_del(c->srcs, pointer); + if (ret < 0) { + scf_loge("\n"); + return ret; + } + +#if 1 + ret = _filter_3ac_by_pointer_alias(pointer, scf_list_prev(&c->list), bb); + if (ret < 0) + return ret; #endif pointer->dag_node = alias; @@ -164,6 +173,76 @@ static int _alias_assign_dereference(scf_vector_t** paliases, scf_dag_node_t* dn return 0; } +static int __optimize_alias_dereference(scf_3ac_operand_t* pointer, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head) +{ + scf_basic_block_t* bb2; + scf_dn_status_t* ds; + scf_dag_node_t* dn_pointer; + scf_dag_node_t* dn_dereference; + scf_vector_t* aliases; + scf_list_t* l; + + int flag = 0; + + dn_pointer = pointer->dag_node; + dn_dereference = dn_pointer; + aliases = NULL; + + assert(1 == dn_pointer->childs->size); + dn_pointer = dn_pointer->childs->data[0]; + + int ret = _alias_dereference(&aliases, dn_pointer, c, bb, bb_list_head); + if (ret < 0) + return ret; + + if (aliases) { + flag = 1; + + if (1 == aliases->size) { + ds = aliases->data[0]; + + if (SCF_DN_ALIAS_VAR == ds->alias_type) { + + l = scf_list_prev(&c->list); + + if (l == scf_list_sentinel(&bb->code_list_head)) { + l = scf_list_prev(&bb->list); + + assert(l != scf_list_sentinel(bb_list_head)); + + bb2 = scf_list_data(l, scf_basic_block_t, list); + l = scf_list_tail(&bb2->code_list_head); + } else { + bb2 = bb; + l = scf_list_prev(&c->list); + } + + ret = _filter_3ac_by_pointer_alias(pointer, l, bb2); + if (ret < 0) + return ret; + + pointer->dag_node = ds->alias; + + ret = scf_basic_block_inited_vars(bb, bb_list_head); + if (ret < 0) + return ret; + + flag = 0; + } + } + + ret = _bb_copy_aliases(bb, dn_pointer, dn_dereference, aliases); + + scf_vector_free(aliases); + aliases = NULL; + + if (ret < 0) + return ret; + } + + return flag; +} + static int __optimize_alias_bb(scf_list_t** pend, scf_list_t* start, scf_basic_block_t* bb, scf_list_t* bb_list_head) { scf_list_t* l; @@ -212,40 +291,45 @@ static int __optimize_alias_bb(scf_list_t** pend, scf_list_t* start, scf_basic_b if (SCF_OP_3AC_TEQ == c->op->type || SCF_OP_3AC_CMP == c->op->type) { - dn_dereference = dn_pointer; + if (SCF_OP_DEREFERENCE != dn_pointer->type) + continue; + + ret = __optimize_alias_dereference(pointer, c, bb, bb_list_head); + if (ret < 0) + return ret; - assert(SCF_OP_DEREFERENCE == dn_pointer->type); - assert(1 == dn_pointer->childs->size); + flag += ret; - dn_pointer = dn_pointer->childs->data[0]; + } else if (SCF_OP_DEREFERENCE == c->op->type) { + + assert(c->dsts && 1 == c->dsts->size); + dst = c->dsts->data[0]; + dn_dereference = dst->dag_node; ret = _alias_dereference(&aliases, dn_pointer, c, bb, bb_list_head); - if (aliases && 1 == aliases->size) { + } else { + if (i > 0) + break; - ds = aliases->data[0]; + pointer = c->srcs->data[1]; + dn_pointer = pointer->dag_node; - if (SCF_DN_ALIAS_VAR == ds->alias_type) { - pointer->dag_node = ds->alias; + if (SCF_OP_DEREFERENCE == dn_pointer->type) { - scf_vector_free(aliases); - aliases = NULL; + ret = __optimize_alias_dereference(pointer, c, bb, bb_list_head); + if (ret < 0) + return ret; - ret = scf_basic_block_inited_vars(bb, bb_list_head); - if (ret < 0) - return ret; - } + flag += ret; } - } else if (SCF_OP_DEREFERENCE == c->op->type) { + pointer = c->srcs->data[0]; + dn_pointer = pointer->dag_node; + dn_dereference = NULL; - assert(c->dsts && 1 == c->dsts->size); - dst = c->dsts->data[0]; - dn_dereference = dst->dag_node; - - ret = _alias_dereference(&aliases, dn_pointer, c, bb, bb_list_head); - } else ret = _alias_assign_dereference(&aliases, dn_pointer, c, bb, bb_list_head); + } if (ret < 0) return ret; diff --git a/parse/scf_parse2.c b/parse/scf_parse2.c index baa3a0e..5eface5 100644 --- a/parse/scf_parse2.c +++ b/parse/scf_parse2.c @@ -2052,7 +2052,7 @@ int scf_parse_compile_functions(scf_parse_t* parse, scf_native_t* native, scf_ve } assert(scf_list_empty(&h)); -// scf_basic_block_print_list(&f->basic_block_list_head); + scf_basic_block_print_list(&f->basic_block_list_head); } int64_t tv1 = gettime(); scf_logw("tv1 - tv0: %ld\n", tv1 - tv0); -- 2.25.1