optimize pointer alias & add a test '../examples/pointer_opt.c'
authoryu.dongliang <18588496441@163.com>
Mon, 27 Nov 2023 03:50:17 +0000 (11:50 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 27 Nov 2023 03:50:17 +0000 (11:50 +0800)
core/scf_optimizer_pointer_alias.c
examples/pointer_opt.c [new file with mode: 0644]

index 31907fd7c01e1709b22a79b1d0263cb1b4a8b393..4ab05ffd56914644c053b7f0902144a6eea25f7b 100644 (file)
@@ -171,38 +171,51 @@ static int _3ac_pointer_alias(scf_dag_node_t* alias, scf_3ac_code_t* c, scf_basi
        return 0;
 }
 
-static int _alias_dereference_filter_3ac(scf_dag_node_t* dn, scf_dn_status_t* ds, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+static void __alias_filter_3ac_next2(scf_dag_node_t* dn, scf_dn_status_t* ds, scf_list_t* start, scf_basic_block_t* bb)
 {
        scf_3ac_operand_t* dst;
        scf_3ac_operand_t* src;
-       scf_3ac_code_t*    c2;
+       scf_3ac_code_t*    c;
        scf_list_t*        l;
 
        int i;
 
-       for (l = scf_list_next(&c->list); l != scf_list_sentinel(&bb->code_list_head); l = scf_list_next(l)) {
-               c2 = scf_list_data(l, scf_3ac_code_t, list);
+       for (l = start; l != scf_list_sentinel(&bb->code_list_head); l = scf_list_next(l)) {
+               c  = scf_list_data(l, scf_3ac_code_t, list);
 
-               if (c2->srcs) {
-                       for (i = 0; i < c2->srcs->size; i++) {
-                               src       = c2->srcs->data[i];
+               if (c->srcs) {
+                       for (i = 0; i < c->srcs->size; i++) {
+                               src       = c->srcs->data[i];
 
                                if (src->dag_node == dn)
                                        src->dag_node  = ds->alias;
                        }
                }
 
-               if (c2->dsts) {
-                       for (i = 0; i < c2->dsts->size; i++) {
-                               dst       = c2->dsts->data[i];
+               if (c->dsts) {
+                       for (i = 0; i < c->dsts->size; i++) {
+                               dst       = c->dsts->data[i];
 
                                if (dst->dag_node == dn)
                                        dst->dag_node  = ds->alias;
                        }
                }
        }
+}
 
-       return 0;
+static void __alias_filter_3ac_next(scf_dag_node_t* dn, scf_dn_status_t* ds, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
+{
+       scf_list_t* l;
+
+       __alias_filter_3ac_next2(dn, ds, scf_list_next(&c->list), bb);
+
+       l = scf_list_next(&bb->list);
+       if (l != scf_list_sentinel(bb_list_head)) {
+
+               bb = scf_list_data(l, scf_basic_block_t, list);
+
+               __alias_filter_3ac_next2(dn, ds, scf_list_head(&bb->code_list_head), bb);
+       }
 }
 
 static int _alias_dereference(scf_vector_t** paliases, scf_dag_node_t* dn_pointer, scf_3ac_code_t* c, scf_basic_block_t* bb, scf_list_t* bb_list_head)
@@ -231,14 +244,15 @@ static int _alias_dereference(scf_vector_t** paliases, scf_dag_node_t* dn_pointe
 
                        dst = c->dsts->data[0];
 
-                       _alias_dereference_filter_3ac(dst->dag_node, ds, c, bb, bb_list_head);
+                       __alias_filter_3ac_next(dst->dag_node, ds, c, bb, bb_list_head);
 
                        scf_vector_free(aliases);
                        aliases = NULL;
 
+                       ret = scf_basic_block_inited_vars(bb, bb_list_head);
                        if (ret < 0)
                                return ret;
-                       return scf_basic_block_inited_vars(bb, bb_list_head);
+                       return 1;
                }
        }
 
@@ -292,8 +306,6 @@ static int __optimize_alias_dereference(scf_3ac_operand_t* pointer, scf_3ac_code
        scf_vector_t*      aliases;
        scf_list_t*        l;
 
-       int flag = 0;
-
        dn_pointer     = pointer->dag_node;
        dn_dereference = dn_pointer;
        aliases        = NULL;
@@ -301,59 +313,56 @@ static int __optimize_alias_dereference(scf_3ac_operand_t* pointer, scf_3ac_code
        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;
+       aliases = scf_vector_alloc();
+       if (!aliases)
+               return -ENOMEM;
 
-       if (aliases) {
+       int ret = __alias_dereference(aliases, dn_pointer, c, bb, bb_list_head);
+       if (ret < 0) {
+               scf_vector_free(aliases);
+               return ret;
+       }
 
-               if (1 == aliases->size) {
-                       ds = aliases->data[0];
+       if (1 == aliases->size) {
+               ds = aliases->data[0];
 
-                       if (SCF_DN_ALIAS_VAR == ds->alias_type) {
+               if (SCF_DN_ALIAS_VAR == ds->alias_type) {
 
-                               l = scf_list_prev(&c->list);
+                       l = scf_list_prev(&c->list);
 
-                               if (l == scf_list_sentinel(&bb->code_list_head)) {
-                                       l =  scf_list_prev(&bb->list);
+                       if (l == scf_list_sentinel(&bb->code_list_head)) {
+                               l =  scf_list_prev(&bb->list);
 
-                                       assert(l != scf_list_sentinel(bb_list_head));
+                               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);
-                               }
+                               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, bb_list_head);
-                               if (ret < 0)
-                                       return ret;
+                       scf_vector_free(aliases);
+                       aliases = NULL;
 
-                               pointer->dag_node = ds->alias;
+                       ret = _filter_3ac_by_pointer_alias(pointer, l, bb2, bb_list_head);
+                       if (ret < 0)
+                               return ret;
 
-                               ret = scf_basic_block_inited_vars(bb, bb_list_head);
-                               if (ret < 0)
-                                       return ret;
+                       pointer->dag_node = ds->alias;
 
-                               scf_vector_free(aliases);
-                               aliases = NULL;
-                               return 0;
-                       }
+                       return scf_basic_block_inited_vars(bb, bb_list_head);
                }
+       }
 
-               ret = _bb_copy_aliases(bb, dn_pointer, dn_dereference, aliases);
+       ret = _bb_copy_aliases(bb, dn_pointer, dn_dereference, aliases);
 
-               scf_vector_free(aliases);
-               aliases = NULL;
-
-               if (ret < 0)
-                       return ret;
+       scf_vector_free(aliases);
+       aliases = NULL;
 
-               flag = 1;
-       }
-
-       return flag;
+       if (ret < 0)
+               return ret;
+       return 1;
 }
 
 static int __optimize_alias_bb(scf_list_t** pend, scf_list_t* start, scf_basic_block_t* bb, scf_list_t* bb_list_head)
@@ -421,6 +430,12 @@ static int __optimize_alias_bb(scf_list_t** pend, scf_list_t* start, scf_basic_b
                                dn_dereference = dst->dag_node;
 
                                ret = _alias_dereference(&aliases, dn_pointer, c, bb, bb_list_head);
+                               if (1 == ret) {
+                                       scf_list_del(&c->list);
+                                       scf_3ac_code_free(c);
+                                       c = NULL;
+                                       break;
+                               }
 #endif
                        } else {
                                if (i > 0)
diff --git a/examples/pointer_opt.c b/examples/pointer_opt.c
new file mode 100644 (file)
index 0000000..a796c29
--- /dev/null
@@ -0,0 +1,26 @@
+int printf(const char* fmt, ...);
+
+int f(int i, int a, int b)
+{
+       int*   p;
+       int**  pp  = &p;
+       int*** ppp = &pp;
+
+       if (i > 0)
+               p = &a;
+       else
+               p = &b;
+
+       ***ppp += 2;
+       return a;
+}
+
+int main()
+{
+       int i = 1;
+       int a = 2;
+       int b = 3;
+
+       printf("%d\n", f(i, a, b));
+       return 0;
+}