optimize: pointer dereference when the variable pointed can be identified,
authoryu.dongliang <maja_creater@qq.com>
Wed, 19 Oct 2022 09:45:25 +0000 (17:45 +0800)
committeryu.dongliang <maja_creater@qq.com>
Wed, 19 Oct 2022 09:45:29 +0000 (17:45 +0800)
such as:
int   a = 1;
int*  p = &a;
int** pp = &p;

**pp += 2; // this will be instead of 'a += 2', and 'p = &a; pp = &p' will be deleted.

core/scf_3ac.c
core/scf_optimizer_basic_block.c
core/scf_optimizer_pointer_alias.c

index 6089384e05c6d7e4b28299c64d7681d25a32c246..1d8f807e64951ca83f28d2ef47d6fbd6b1df7abf 100644 (file)
@@ -687,6 +687,7 @@ int scf_3ac_code_to_dag(scf_3ac_code_t* c, scf_list_t* dag)
                        return ret;
 
        } else if (scf_type_is_assign_array_index(c->op->type)
+                       || scf_type_is_assign_dereference(c->op->type)
                        || scf_type_is_assign_pointer(c->op->type)) {
 
                scf_3ac_operand_t* src;
index 1c8611195060fcfebc41dc835413eb6d2bd4846d..81a1d07fecbb8d23d573cbba4efbee00fd69bbd8 100644 (file)
@@ -55,15 +55,18 @@ static int _bb_dag_update(scf_basic_block_t* bb, scf_vector_t* dag, scf_list_t*
 
                        if (scf_type_is_assign_array_index(dn->type))
                                continue;
+                       if (scf_type_is_assign_dereference(dn->type) || SCF_OP_DEREFERENCE == dn->type)
+                               continue;
                        if (scf_type_is_assign_pointer(dn->type))
                                continue;
 
                        if (scf_type_is_assign(dn->type)
-                                       || SCF_OP_INC       == dn->type || SCF_OP_DEC       == dn->type
-                                       || SCF_OP_3AC_INC   == dn->type || SCF_OP_3AC_DEC   == dn->type
-                                       || SCF_OP_3AC_SETZ  == dn->type || SCF_OP_3AC_SETNZ == dn->type
-                                       || SCF_OP_3AC_SETLT == dn->type || SCF_OP_3AC_SETLE == dn->type
-                                       || SCF_OP_3AC_SETGT == dn->type || SCF_OP_3AC_SETGE == dn->type) {
+                                       || SCF_OP_INC         == dn->type || SCF_OP_DEC       == dn->type
+                                       || SCF_OP_3AC_INC     == dn->type || SCF_OP_3AC_DEC   == dn->type
+                                       || SCF_OP_3AC_SETZ    == dn->type || SCF_OP_3AC_SETNZ == dn->type
+                                       || SCF_OP_3AC_SETLT   == dn->type || SCF_OP_3AC_SETLE == dn->type
+                                       || SCF_OP_3AC_SETGT   == dn->type || SCF_OP_3AC_SETGE == dn->type
+                                       || SCF_OP_ADDRESS_OF  == dn->type) {
 
                                if (!dn->childs) {
                                        scf_list_del(&dn->list);
@@ -84,24 +87,27 @@ static int _bb_dag_update(scf_basic_block_t* bb, scf_vector_t* dag, scf_list_t*
                                        return -1;
                                }
 
-                               if (scf_vector_find(bb->dn_saves, dn_func)
-                                               || scf_vector_find(bb->dn_resaves, dn_func))
-                                       continue;
+                               if (SCF_OP_ADDRESS_OF != dn->type) {
 
-                               assert(dn_bb->parents && dn_bb->parents->size > 0);
+                                       if (scf_vector_find(bb->dn_saves,   dn_func)
+                                        || scf_vector_find(bb->dn_resaves, dn_func))
+                                               continue;
 
-                               if (dn != dn_bb->parents->data[dn_bb->parents->size - 1])
-                                       continue;
+                                       assert(dn_bb->parents && dn_bb->parents->size > 0);
+
+                                       if (dn != dn_bb->parents->data[dn_bb->parents->size - 1])
+                                               continue;
 
-                               if (2      == dn->childs->size) {
-                                       dn_bb2 =  dn->childs->data[1];
+                                       if (2      == dn->childs->size) {
+                                               dn_bb2 =  dn->childs->data[1];
 
-                                       assert(0 == scf_vector_del(dn->childs,      dn_bb2));
-                                       assert(0 == scf_vector_del(dn_bb2->parents, dn));
+                                               assert(0 == scf_vector_del(dn->childs,      dn_bb2));
+                                               assert(0 == scf_vector_del(dn_bb2->parents, dn));
 
-                                       if (0 == dn_bb2->parents->size) {
-                                               scf_vector_free(dn_bb2->parents);
-                                               dn_bb2->parents = NULL;
+                                               if (0 == dn_bb2->parents->size) {
+                                                       scf_vector_free(dn_bb2->parents);
+                                                       dn_bb2->parents = NULL;
+                                               }
                                        }
                                }
 
@@ -355,7 +361,6 @@ static int _optimize_basic_block(scf_ast_t* ast, scf_function_t* f, scf_list_t*
                                || bb->ret_flag
                                || bb->end_flag
                                || bb->call_flag
-                               || bb->dereference_flag
                                || bb->varg_flag) {
                        scf_logd("bb: %p, jmp:%d,ret:%d, end: %d, call:%d, varg:%d, dereference_flag: %d\n",
                                        bb, bb->jmp_flag, bb->ret_flag, bb->end_flag, bb->call_flag, bb->dereference_flag,
index d73035eb460c238b662f81a735b50003747037ee..583cdb155b4402d83ae28f48456fd9556510a261 100644 (file)
@@ -1,13 +1,15 @@
 #include"scf_optimizer.h"
 #include"scf_pointer_alias.h"
 
-static int _filter_3ac_by_pointer_alias(scf_3ac_operand_t* pointer, scf_list_t* prev, 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_list_t* bb_list_head)
 {
-       scf_3ac_code_t* c2;
-       scf_3ac_code_t* c3;
-       scf_list_t*     l2;
-       scf_list_t*     l3;
-       scf_list_t      h;
+       scf_basic_block_t* bb2;
+       scf_basic_block_t* bb3;
+       scf_3ac_code_t*    c2;
+       scf_3ac_code_t*    c3;
+       scf_list_t*        l2;
+       scf_list_t*        l3;
+       scf_list_t         h;
 
        scf_list_init(&h);
 
@@ -17,31 +19,81 @@ static int _filter_3ac_by_pointer_alias(scf_3ac_operand_t* pointer, scf_list_t*
                return ret;
        }
 
-       for (l2 = scf_list_head(&h); l2 != scf_list_sentinel(&h); ) {
+       l3  = prev;
+
+       for (l2 = scf_list_tail(&h); l2 != scf_list_sentinel(&h); ) {
 
                c2  = scf_list_data(l2, scf_3ac_code_t, list);
-               l2  = scf_list_next(l2);
 
-               for (l3 = prev; l3 != scf_list_sentinel(&bb->code_list_head); ) {
+               for ( ; l3 != scf_list_sentinel(&bb->code_list_head); ) {
 
                        c3  = scf_list_data(l3, scf_3ac_code_t, list);
-                       l3  = scf_list_prev(l3);
 
                        if (scf_3ac_code_same(c2, c3)) {
+                               l3  = scf_list_prev(l3);
+                               l2  = scf_list_prev(l2);
+
                                scf_list_del(&c3->list);
+                               scf_list_del(&c2->list);
+
                                scf_3ac_code_free(c3);
+                               scf_3ac_code_free(c2);
                                break;
                        }
+
+                       l3  = scf_list_prev(l3);
                }
 
-               scf_list_del(&c2->list);
-               scf_3ac_code_free(c2);
+               if (l3 == scf_list_sentinel(&bb->code_list_head)) {
+
+                       if (scf_list_prev(&bb->list) == scf_list_sentinel(bb_list_head))
+                               break;
+
+                       bb2 = scf_list_data(scf_list_prev(&bb->list), scf_basic_block_t, list);
+
+                       if (!bb2->nexts || bb2->nexts->size != 1)
+                               break;
+
+                       if (!bb->prevs  || bb->prevs->size != 1)
+                               break;
+
+                       if (bb2->nexts->data[0] != bb || bb->prevs->data[0] != bb2)
+                               break;
+
+                       if (scf_list_empty(&bb->code_list_head)) {
+
+                               SCF_XCHG(bb2->nexts, bb->nexts);
+
+                               int i;
+                               int j;
+
+                               for (i = 0; i < bb2->nexts->size; i++) {
+                                       bb3       = bb2->nexts->data[i];
+
+                                       for (j = 0; j < bb3->prevs->size; j++) {
+
+                                               if (bb3->prevs->data[j] == bb) {
+                                                       bb3->prevs->data[j] =  bb2;
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               scf_list_del(&bb->list);
+
+                               scf_basic_block_free(bb);
+                               bb = NULL;
+                       }
+
+                       bb = bb2;
+                       l3 = scf_list_tail(&bb->code_list_head);
+               }
        }
 
        return 0;
 }
 
-static int _3ac_pointer_alias(scf_dag_node_t* alias, scf_3ac_code_t* c, scf_basic_block_t* bb)
+static int _3ac_pointer_alias(scf_dag_node_t* alias, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
 {
        scf_3ac_operand_t* pointer;
 
@@ -58,7 +110,7 @@ static int _3ac_pointer_alias(scf_dag_node_t* alias, scf_3ac_code_t* c, scf_basi
        }
 
 #if 1
-       ret = _filter_3ac_by_pointer_alias(pointer, scf_list_prev(&c->list), bb);
+       ret = _filter_3ac_by_pointer_alias(pointer, scf_list_prev(&c->list), bb, bb_list_head);
        if (ret < 0)
                return ret;
 #endif
@@ -160,13 +212,16 @@ static int _alias_assign_dereference(scf_vector_t** paliases, scf_dag_node_t* dn
                status = aliases->data[0];
 
                if (SCF_DN_ALIAS_VAR == status->alias_type) {
-                       ret = _3ac_pointer_alias(status->alias, c, bb);
+
+                       ret = _3ac_pointer_alias(status->alias, c, bb, bb_list_head);
+
                        scf_vector_free(aliases);
+                       aliases = NULL;
+
                        if (ret < 0)
                                return ret;
                        return scf_basic_block_inited_vars(bb, bb_list_head);
                }
-               return 0;
        }
 
        *paliases = aliases;
@@ -196,7 +251,6 @@ static int __optimize_alias_dereference(scf_3ac_operand_t* pointer, scf_3ac_code
                return ret;
 
        if (aliases) {
-               flag = 1;
 
                if (1 == aliases->size) {
                        ds = aliases->data[0];
@@ -217,7 +271,7 @@ static int __optimize_alias_dereference(scf_3ac_operand_t* pointer, scf_3ac_code
                                        l   = scf_list_prev(&c->list);
                                }
 
-                               ret = _filter_3ac_by_pointer_alias(pointer, l, bb2);
+                               ret = _filter_3ac_by_pointer_alias(pointer, l, bb2, bb_list_head);
                                if (ret < 0)
                                        return ret;
 
@@ -227,7 +281,9 @@ static int __optimize_alias_dereference(scf_3ac_operand_t* pointer, scf_3ac_code
                                if (ret < 0)
                                        return ret;
 
-                               flag = 0;
+                               scf_vector_free(aliases);
+                               aliases = NULL;
+                               return 0;
                        }
                }
 
@@ -238,6 +294,8 @@ static int __optimize_alias_dereference(scf_3ac_operand_t* pointer, scf_3ac_code
 
                if (ret < 0)
                        return ret;
+
+               flag = 1;
        }
 
        return flag;
@@ -301,13 +359,13 @@ static int __optimize_alias_bb(scf_list_t** pend, scf_list_t* start, scf_basic_b
                                flag += ret;
 
                        } else if (SCF_OP_DEREFERENCE == c->op->type) {
-
+#if 0
                                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);
-
+#endif
                        } else {
                                if (i > 0)
                                        break;