fix: pointer alias error in scf_p2a() of ../examples/scf_printf.c
authoryu.dongliang <18588496441@163.com>
Mon, 27 Nov 2023 07:26:16 +0000 (15:26 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 27 Nov 2023 07:26:16 +0000 (15:26 +0800)
core/scf_optimizer.c
core/scf_optimizer_pointer_alias.c
examples/scf_printf.c [new file with mode: 0644]
native/x64/scf_x64.c

index ef09951101aadc17f5b0cab75c189b0b84eef059..b5be44936e8a2fb09da9ef8411389a69004b5a4b 100644 (file)
@@ -162,6 +162,8 @@ int scf_optimize(scf_ast_t* ast, scf_vector_t* functions)
                if (!f->node.define_flag)
                        continue;
 
+               scf_logi("------- %s() ------\n", f->node.w->text->data);
+
                scf_basic_block_print_list(&f->basic_block_list_head);
                scf_loops_print(f->bb_loops);
                scf_groups_print(f->bb_groups);
index 4ab05ffd56914644c053b7f0902144a6eea25f7b..02244d3ba682a30d80a4ac48830289533fa4d919 100644 (file)
@@ -222,6 +222,8 @@ static int _alias_dereference(scf_vector_t** paliases, scf_dag_node_t* dn_pointe
 {
        scf_3ac_operand_t* dst;
        scf_dn_status_t*   ds;
+       scf_variable_t*    vd;
+       scf_variable_t*    va;
        scf_vector_t*      aliases;
 
        int ret;
@@ -244,15 +246,22 @@ static int _alias_dereference(scf_vector_t** paliases, scf_dag_node_t* dn_pointe
 
                        dst = c->dsts->data[0];
 
-                       __alias_filter_3ac_next(dst->dag_node, ds, c, bb, bb_list_head);
+                       vd  = dst->dag_node->var;
+                       va  = ds->alias->var;
 
-                       scf_vector_free(aliases);
-                       aliases = NULL;
+                       if (!scf_variable_const(va)
+                                       && scf_variable_nb_pointers(vd) == scf_variable_nb_pointers(va)) {
 
-                       ret = scf_basic_block_inited_vars(bb, bb_list_head);
-                       if (ret < 0)
-                               return ret;
-                       return 1;
+                               __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 1;
+                       }
                }
        }
 
@@ -263,7 +272,7 @@ static int _alias_dereference(scf_vector_t** paliases, scf_dag_node_t* dn_pointe
 static int _alias_assign_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)
 {
        scf_dn_status_t* status;
-       scf_vector_t*     aliases;
+       scf_vector_t*    aliases;
        int ret;
 
        aliases = scf_vector_alloc();
diff --git a/examples/scf_printf.c b/examples/scf_printf.c
new file mode 100644 (file)
index 0000000..e6df4f9
--- /dev/null
@@ -0,0 +1,244 @@
+struct va_list
+{
+       uint8_t*  iptr;
+       uint8_t*  fptr;
+       uint8_t*  optr;
+
+       intptr_t  ireg;
+       intptr_t  freg;
+       intptr_t  others;
+};
+
+int scf_ulong2a(char* buf, int* pn, int size, uint64_t num)
+{
+       int n = *pn;
+       int i = n;
+
+       while (n < size - 1) {
+
+               buf[n++] = num % 10 + '0';
+
+               num /= 10;
+               if (0 == num)
+                       break;
+       }
+
+       *pn = n--;
+
+       while (i < n) {
+               char c   = buf[i];
+               buf[i++] = buf[n];
+               buf[n--] = c;
+       }
+       return *pn;
+}
+
+int scf_long2a(char* buf, int* pn, int size, int64_t num)
+{
+       int n = *pn;
+
+       if (n < size - 1 && num < 0) {
+               buf[n++] = '-';
+               num = -num;
+       }
+
+       *pn = n;
+       return scf_ulong2a(buf, pn, size, num);
+}
+
+int scf_hex2a(char* buf, int* pn, int size, uint64_t num)
+{
+       int n = *pn;
+       int i = n;
+
+       while (n < size - 1) {
+
+               uint8_t x = num % 16;
+
+               if (x > 9)
+                       buf[n++] = x - 10 + 'a';
+               else
+                       buf[n++] = x + '0';
+
+               num /= 16;
+               if (0 == num)
+                       break;
+       }
+
+       *pn = n--;
+
+       while (i < n) {
+               char c   = buf[i];
+               buf[i++] = buf[n];
+               buf[n--] = c;
+       }
+       return *pn;
+}
+
+int scf_hex2a_prefix(char* buf, int* pn, int size, uint64_t num)
+{
+       int n = *pn;
+
+       if (n < size - 1 - 2) {
+               buf[n++] = '0';
+               buf[n++] = 'x';
+       }
+
+       *pn = n;
+       return scf_hex2a(buf, pn, size, num);
+}
+
+int scf_p2a(char* buf, int* pn, int size, uint64_t num)
+{
+       if (0 == num) {
+               int   n = *pn;
+               char* p = "null";
+
+               while (n < size - 1 && *p)
+                       buf[n++] = *p++;
+
+               *pn = n;
+               return n;
+       }
+
+       return scf_hex2a_prefix(buf, pn, size, num);
+}
+
+int scf_str2a(char* buf, int* pn, int size, const char* str)
+{
+       int n = *pn;
+
+       while (n < size - 1 && *str)
+               buf[n++] = *str++;
+
+       *pn = n;
+       return n;
+}
+
+int scf_double2a(char* buf, int* pn, int size, double num)
+{
+       if (*pn < size - 1 && num < 0.0) {
+               buf[(*pn)++] = '-';
+               num = -num;
+       }
+
+       int64_t l    = (int64_t)num;
+       int64_t diff = (int64_t)((num - l) * 1000000);
+
+       scf_ulong2a(buf, pn, size, l);
+
+       if (*pn < size - 1)
+               buf[(*pn)++] = '.';
+
+       return scf_ulong2a(buf, pn, size, diff);
+}
+
+int scf_vsnprintf(char* buf, int size, const char* fmt, va_list* ap)
+{
+       int n = 0;
+
+       while (*fmt) {
+
+               if ('%' != *fmt) {
+                       buf[n++] = *fmt++;
+                       continue;
+               }
+
+               fmt++;
+               if ('%' == *fmt) {
+                       buf[n++] = *fmt++;
+                       continue;
+               }
+
+               int prefix = 0;
+               if ('#' == *fmt) {
+                       prefix++;
+                       fmt++;
+               }
+
+               int l = 0;
+               if ('l' == *fmt) {
+                       l++;
+                       fmt++;
+               }
+
+               if ('c' == *fmt)
+                       buf[n++] = va_arg(ap, int32_t);
+
+               else if ('u' == *fmt) {
+                       if (l)
+                               scf_ulong2a(buf, &n, size, va_arg(ap, uint64_t));
+                       else
+                               scf_ulong2a(buf, &n, size, va_arg(ap, uint32_t));
+
+               } else if ('d' == *fmt) {
+                       if (l)
+                               scf_long2a(buf, &n, size, va_arg(ap, int64_t));
+                       else
+                               scf_long2a(buf, &n, size, va_arg(ap, int32_t));
+
+               } else if ('x' == *fmt) {
+                       if (prefix) {
+                               if (l)
+                                       scf_hex2a_prefix(buf, &n, size, va_arg(ap, uint64_t));
+                               else
+                                       scf_hex2a_prefix(buf, &n, size, va_arg(ap, uint32_t));
+                       } else {
+                               if (l)
+                                       scf_hex2a(buf, &n, size, va_arg(ap, uint64_t));
+                               else
+                                       scf_hex2a(buf, &n, size, va_arg(ap, uint32_t));
+                       }
+               } else if ('p' == *fmt)
+                       scf_p2a(buf, &n, size, va_arg(ap, uint64_t));
+
+               else if ('s' == *fmt)
+                       scf_str2a(buf, &n, size, va_arg(ap, char*));
+
+               else if ('f' == *fmt) {
+                       if (l)
+                               scf_double2a(buf, &n, size, va_arg(ap, double));
+                       else
+                               scf_double2a(buf, &n, size, va_arg(ap, float));
+               } else
+                       return -1;
+
+               fmt++;
+       }
+
+       buf[n] = '\0';
+       return n;
+}
+
+int write(int fd, uint8_t* buf, intptr_t size);
+
+int scf_printf(const char* fmt, ...)
+{
+       va_list ap;
+
+       char buf[1024];
+
+       va_start(ap, fmt);
+       int ret = scf_vsnprintf(buf, sizeof(buf) - 1, fmt, &ap);
+       va_end(ap);
+
+       if (ret > 0) {
+               ret = write(1, buf, ret);
+       }
+
+       return ret;
+}
+
+int main()
+{
+       char buf[1024];
+
+       float   f   = 2.71828;
+       double  d   = -3.1415926;
+       int64_t i64 = -255;
+
+       int ret = scf_printf("i: %d, ld: %ld,  x: %x, x: %#lx, p: %p, s: %s, f: %lf, d: %lf\n",
+                       100, i64, 254, 253, buf, "hello", f, -3.14);
+
+       return ret;
+}
index cbec2432ea343d56ddb781e14a5bfab92a37daa5..9b55d5031a0155e492cc48fe3e0a689fb36fa129 100644 (file)
@@ -1159,6 +1159,8 @@ int scf_x64_select_inst(scf_native_t* ctx, scf_function_t* f)
        if (local_vars_size < 0)
                return -1;
 
+       scf_logi("---------- %s() ------------\n", f->node.w->text->data);
+
        int i;
        for (i = 0; i < local_vars->size; i++) {
                scf_variable_t* v = local_vars->data[i];