fix & optimize: dereference & assign in if condition, such as:
authoryu.dongliang <maja_creater@qq.com>
Tue, 18 Oct 2022 10:22:57 +0000 (18:22 +0800)
committeryu.dongliang <maja_creater@qq.com>
Tue, 18 Oct 2022 10:23:03 +0000 (18:23 +0800)
if (*p = i > 0 && j > 1 && k > 2)
return -1;
return 0;

core/scf_3ac.c
core/scf_operator_handler_3ac.c
core/scf_optimizer_pointer_alias.c

index 3813a973e68253df681f8e0c96d982ba624ae718..6089384e05c6d7e4b28299c64d7681d25a32c246 100644 (file)
@@ -1421,8 +1421,11 @@ static int _3ac_split_basic_blocks(scf_list_t* h, scf_function_t* f)
                        if (SCF_OP_3AC_CMP == c->op->type
                                        || SCF_OP_3AC_TEQ == c->op->type) {
 
-                               scf_list_t*         l2;
-                               scf_3ac_code_t* c2;
+                               scf_3ac_operand_t* src;
+                               scf_3ac_code_t*    c2;
+                               scf_list_t*            l2;
+                               scf_node_t*        e;
+                               int i;
 
                                for (l2 = scf_list_next(&c->list); l2 != scf_list_sentinel(h); l2 = scf_list_next(l2)) {
 
@@ -1431,8 +1434,24 @@ static int _3ac_split_basic_blocks(scf_list_t* h, scf_function_t* f)
                                        if (scf_type_is_setcc(c2->op->type))
                                                continue;
 
-                                       if (scf_type_is_jmp(c2->op->type))
+                                       if (scf_type_is_jmp(c2->op->type)) {
                                                bb->cmp_flag = 1;
+
+                                               if (c->srcs) {
+
+                                                       for (i = 0; i < c->srcs->size; i++) {
+                                                               src       = c->srcs->data[i];
+                                                               e         = src->node;
+
+                                                               while (e && SCF_OP_EXPR == e->type)
+                                                                       e = e->nodes[0];
+                                                               assert(e);
+
+                                                               if (SCF_OP_DEREFERENCE == e->type)
+                                                                       bb->dereference_flag = 1;
+                                                       }
+                                               }
+                                       }
                                        break;
                                }
 
index 4be21a126483cf1d7146bd02123077526f9ff042..0ceac0a6c3ea343b31d8fa3253f5177e56603d03 100644 (file)
@@ -803,10 +803,26 @@ static int _scf_op_cond(scf_ast_t* ast, scf_expr_t* e, scf_handler_data_t* d)
                        break;
 
                default:
+                       if (scf_type_is_assign(e->type)) {
+
+                               e = e->nodes[0];
+
+                               while (e && SCF_OP_EXPR == e->type)
+                                       e = e->nodes[0];
+
+                               assert(e);
+
+                               if (_scf_expr_calculate_internal(ast, e, d) < 0) {
+                                       scf_loge("\n");
+                                       return -1;
+                               }
+                       }
+
                        if (_scf_3ac_code_1(d->_3ac_list_head, SCF_OP_3AC_TEQ, e) < 0) {
                                scf_loge("\n");
                                return -1;
                        }
+
                        jmp_op     = SCF_OP_3AC_JZ;
                        is_default = 1;
                        break;
index 7261f8f54828f6ba23cb21ff5efaaf96da4852f0..6c5a1ba6837be5b6758b9d3729269598c4c9f025 100644 (file)
@@ -170,6 +170,7 @@ static int __optimize_alias_bb(scf_list_t** pend, scf_list_t* start, scf_basic_b
        scf_3ac_code_t*    c;
        scf_3ac_operand_t* pointer;
        scf_3ac_operand_t* dst;
+       scf_dn_status_t*   ds;
        scf_dag_node_t*    dn_pointer;
        scf_dag_node_t*    dn_dereference;
        scf_vector_t*      aliases;
@@ -181,52 +182,90 @@ static int __optimize_alias_bb(scf_list_t** pend, scf_list_t* start, scf_basic_b
                c  = scf_list_data(l, scf_3ac_code_t, list);
 
                if (!scf_type_is_assign_dereference(c->op->type)
-                               && SCF_OP_DEREFERENCE != c->op->type)
+                               && SCF_OP_DEREFERENCE != c->op->type
+                               && SCF_OP_3AC_TEQ     != c->op->type
+                               && SCF_OP_3AC_CMP     != c->op->type)
                        continue;
 
                assert(c->srcs && c->srcs->size >= 1);
-               pointer        = c->srcs->data[0];
-               dn_pointer     = pointer->dag_node;
-               aliases        = NULL;
-               dn_dereference = NULL;
-
-               if (dn_pointer->var->arg_flag) {
-                       scf_variable_t* v = dn_pointer->var;
-                       scf_logd("arg: v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
-                       continue;
-               }
 
-               if (dn_pointer->var->global_flag) {
-                       scf_variable_t* v = dn_pointer->var;
-                       scf_logd("global: v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
-                       continue;
-               }
+               int flag = 0;
+               int i;
+               for (i = 0; i < c->srcs->size; i++) {
 
-               if (SCF_OP_DEREFERENCE == c->op->type) {
+                       pointer        = c->srcs->data[i];
+                       dn_pointer     = pointer->dag_node;
+                       aliases        = NULL;
+                       dn_dereference = NULL;
 
-                       assert(c->dsts && 1 == c->dsts->size);
-                       dst = c->dsts->data[0];
-                       dn_dereference = dst->dag_node;
+                       if (dn_pointer->var->arg_flag) {
+                               scf_variable_t* v = dn_pointer->var;
+                               scf_logd("arg: v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
+                               continue;
+                       }
 
-                       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 (dn_pointer->var->global_flag) {
+                               scf_variable_t* v = dn_pointer->var;
+                               scf_logd("global: v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
+                               continue;
+                       }
 
-               if (ret < 0)
-                       return ret;
+                       if (SCF_OP_3AC_TEQ == c->op->type || SCF_OP_3AC_CMP == c->op->type) {
 
-               if (aliases) {
-                       scf_logd("bb: %p, bb->index: %d, aliases->size: %d\n", bb, bb->index, aliases->size);
-                       scf_variable_t* v = dn_pointer->var;
-                       scf_logd("v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
+                               dn_dereference = dn_pointer;
+
+                               assert(SCF_OP_DEREFERENCE == dn_pointer->type);
+                               assert(1                  == dn_pointer->childs->size);
+
+                               dn_pointer = dn_pointer->childs->data[0];
+
+                               ret = _alias_dereference(&aliases, dn_pointer, c, bb, bb_list_head);
+
+                               if (aliases && 1 == aliases->size) {
+
+                                       ds = aliases->data[0];
+
+                                       if (SCF_DN_ALIAS_VAR == ds->alias_type) {
+                                               pointer->dag_node = ds->alias;
+
+                                               scf_vector_free(aliases);
+                                               aliases = NULL;
+
+                                               ret = scf_basic_block_inited_vars(bb, bb_list_head);
+                                               if (ret < 0)
+                                                       return ret;
+                                       }
+                               }
+
+                       } 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);
+                       } else
+                               ret = _alias_assign_dereference(&aliases, dn_pointer, c, bb, bb_list_head);
 
-                       ret = _bb_copy_aliases(bb, dn_pointer, dn_dereference, aliases);
-                       scf_vector_free(aliases);
-                       aliases = NULL;
                        if (ret < 0)
                                return ret;
 
+                       if (aliases) {
+                               scf_logd("bb: %p, bb->index: %d, aliases->size: %d\n", bb, bb->index, aliases->size);
+                               scf_variable_t* v = dn_pointer->var;
+                               scf_logd("v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
+
+                               ret = _bb_copy_aliases(bb, dn_pointer, dn_dereference, aliases);
+                               scf_vector_free(aliases);
+                               aliases = NULL;
+                               if (ret < 0)
+                                       return ret;
+
+                               flag = 1;
+                       }
+               }
+
+               if (flag) {
                        *pend = l;
                        break;
                }
@@ -298,7 +337,7 @@ static int _optimize_pointer_alias(scf_ast_t* ast, scf_function_t* f, scf_list_t
                bb = scf_list_data(l, scf_basic_block_t, list);
                l  = scf_list_next(l);
 
-               if (bb->jmp_flag || bb->end_flag || bb->cmp_flag)
+               if (bb->jmp_flag || bb->end_flag)
                        continue;
 
                if (!bb->dereference_flag)
@@ -309,7 +348,6 @@ static int _optimize_pointer_alias(scf_ast_t* ast, scf_function_t* f, scf_list_t
                        return ret;
        }
 
-//     scf_basic_block_print_list(bb_list_head);
        ret = 0;
 error:
        return ret;