optimize argv[]'s sign/zero extending position of function call()
authoryu.dongliang <18588496441@163.com>
Mon, 14 Oct 2024 09:43:41 +0000 (17:43 +0800)
committeryu.dongliang <18588496441@163.com>
Mon, 14 Oct 2024 09:43:41 +0000 (17:43 +0800)
core/scf_basic_block.c
core/scf_dag.h
native/scf_native.c
native/x64/scf_x64.c
native/x64/scf_x64_inst.c
native/x64/scf_x64_reg.c
native/x64/scf_x64_reg.h

index 9939875ce538236f2170f7926f1c17c71651ceb1..bdf13ceeb51b3fe7d9f7ca5912be73dfb42db1ea 100644 (file)
@@ -379,7 +379,7 @@ void scf_basic_block_print_list(scf_list_t* h)
 
                                v  = dn->var;
                                if (v && v->w)
-                                       printf("entry active: v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
+                                       printf("entry active: v_%d_%d/%s_%#lx\n", v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn);
                        }
                }
 
@@ -389,7 +389,7 @@ void scf_basic_block_print_list(scf_list_t* h)
 
                                v  = dn->var;
                                if (v && v->w)
-                                       printf("exit  active: v_%d_%d/%s, dn: %#lx\n", v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn);
+                                       printf("exit  active: v_%d_%d/%s_%#lx\n", v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn);
                        }
                }
 
@@ -418,7 +418,7 @@ void scf_basic_block_print_list(scf_list_t* h)
 
                                v  = dn->var;
                                if (v && v->w)
-                                       printf("updated:      v_%d_%d/%s\n", v->w->line, v->w->pos, v->w->text->data);
+                                       printf("updated:      v_%d_%d/%s_%#lx\n", v->w->line, v->w->pos, v->w->text->data, 0xffff & (uintptr_t)dn);
                        }
                }
 
@@ -518,9 +518,6 @@ static int _copy_vars_by_active(scf_vector_t* dn_vec, scf_vector_t* ds_vars, int
 
                dn = ds->dag_node;
 
-               if (scf_variable_const(dn->var))
-                       continue;
-
                if (active == ds->active && scf_dn_through_bb(dn)) {
 
                        int ret = scf_vector_add_unique(dn_vec, dn);
index b58923ff66dd24df2a6ce18e246ab2ae1dfa16eb..b02bd116b87ecce051687cf8055ab74ad5455da1 100644 (file)
@@ -140,8 +140,10 @@ void              scf_ds_vector_clear_by_dn(scf_vector_t* vec, scf_dag_node_t*
 
 static int scf_dn_through_bb(scf_dag_node_t* dn)
 {
-       return (dn->var->global_flag || dn->var->local_flag || dn->var->tmp_flag)
-               && !scf_variable_const(dn->var);
+       scf_variable_t* v = dn->var;
+
+       return (v->global_flag || v->local_flag || v->tmp_flag)
+               && !(v->const_flag && 0 == v->nb_pointers + v->nb_dimentions);
 }
 
 static int scf_dn_status_cmp(const void* p0, const void* p1)
index 14b3e81e9c447bb29ed6e7a69f5d9d7d973a131a..6366eb79ce556feb79dd3b46d9d90be072dcbaea 100644 (file)
@@ -14,9 +14,12 @@ void scf_instruction_print(scf_instruction_t* inst)
                        printf("%d(%s, %s, %d), ", inst->src.disp, inst->src.base->name,
                                        inst->src.index->name, inst->src.scale);
 
-               else if (inst->src.base)
-                       printf("%d(%s), ", inst->src.disp, inst->src.base->name);
-               else
+               else if (inst->src.base) {
+                       if (inst->src.disp < 0)
+                               printf("-%#x(%s), ", -inst->src.disp, inst->src.base->name);
+                       else
+                               printf("%#x(%s), ", inst->src.disp, inst->src.base->name);
+               } else
                        printf("%d(rip), ", inst->dst.disp);
 
        } else if (inst->src.base)
@@ -30,9 +33,12 @@ void scf_instruction_print(scf_instruction_t* inst)
                        printf("%d(%s, %s, %d), ", inst->dst.disp, inst->dst.base->name,
                                        inst->dst.index->name, inst->dst.scale);
 
-               else if (inst->dst.base)
-                       printf("%d(%s), ", inst->dst.disp, inst->dst.base->name);
-               else
+               else if (inst->dst.base) {
+                       if (inst->dst.disp < 0)
+                               printf("-%#x(%s), ", -inst->dst.disp, inst->dst.base->name);
+                       else
+                               printf("%#x(%s), ", inst->dst.disp, inst->dst.base->name);
+               } else
                        printf("%d(rip), ", inst->dst.disp);
 
        } else if (inst->dst.base)
index ed48bea2fdef3b6f30e995e71f435367b3b7e608..5ebd0629e29a4e0f197aca121b220d63cf2313ad 100644 (file)
@@ -53,7 +53,7 @@ static void _x64_argv_rabi(scf_function_t* f)
 
                if (is_float) {
 
-                       if (f->args_float < X64_ABI_NB) {
+                       if (f->args_float < X64_ABI_FLOAT_NB) {
 
                                v->rabi       = x64_find_register_type_id_bytes(is_float, x64_abi_float_regs[f->args_float], size);
                                v->bp_offset  = bp_floats;
@@ -93,7 +93,7 @@ static int _x64_function_init(scf_function_t* f, scf_vector_t* local_vars)
 
        _x64_argv_rabi(f);
 
-       int local_vars_size = 8 + X64_ABI_NB * 8 * 2;
+       int local_vars_size = 8 + (X64_ABI_NB + X64_ABI_FLOAT_NB) * 8;
 
        for (i = 0; i < local_vars->size; i++) {
                v  =        local_vars->data[i];
index 7f6a32e601eff46ffa1fa2dc3c26af266075dab8..392cf0866d8832976b2fa81a249bc062d1154364 100644 (file)
@@ -112,10 +112,13 @@ static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f)
        scf_x64_OpCode_t*   mov;
        scf_x64_OpCode_t*   movx;
        scf_instruction_t*  inst;
+       scf_instruction_t*  inst_movx[X64_ABI_NB + X64_ABI_FLOAT_NB] = {NULL};
 
+       int nb_movx   = 0;
        int nb_floats = 0;
        int ret;
        int i;
+
        for (i = c->srcs->size - 1; i >= 1; i--) {
                scf_3ac_operand_t*  src   = c->srcs->data[i];
                scf_variable_t*     v     = src->dag_node->var;
@@ -199,12 +202,12 @@ static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f)
                        rs = x64_find_register_color_bytes(rs->color, 8);
                }
 
-               if (movx) {
-                       inst = x64_make_inst_E2G(movx, rs,  rs);
-                       X64_INST_ADD_CHECK(c->instructions, inst);
-               }
-
                if (!rd) {
+                       if (movx) {
+                               inst = x64_make_inst_E2G(movx, rs,  rs);
+                               X64_INST_ADD_CHECK(c->instructions, inst);
+                       }
+
                        inst = x64_make_inst_G2P(mov, rsp, v->sp_offset, rs);
                        X64_INST_ADD_CHECK(c->instructions, inst);
                        continue;
@@ -217,12 +220,30 @@ static int _x64_inst_call_argv(scf_3ac_code_t* c, scf_function_t* f)
                }
 
                if (!X64_COLOR_CONFLICT(rd->color, rs->color)) {
+                       if (movx) {
+                               inst = x64_make_inst_E2G(movx, rs,  rs);
+                               X64_INST_ADD_CHECK(c->instructions, inst);
+                       }
+
                        rd   = x64_find_register_color_bytes(rd->color, rs->bytes);
                        inst = x64_make_inst_G2E(mov, rd, rs);
                        X64_INST_ADD_CHECK(c->instructions, inst);
+
+               } else if (movx) {
+                       inst = x64_make_inst_E2G(movx, rs,  rs);
+                       if (!inst) {
+                               scf_loge("\n");
+                               return -ENOMEM;
+                       }
+
+                       inst_movx[nb_movx++] = inst;
                }
        }
 
+       for (i = 0; i < nb_movx; i++) {
+               X64_INST_ADD_CHECK(c->instructions, inst_movx[i]);
+       }
+
        return nb_floats;
 }
 
@@ -459,6 +480,7 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c)
 
        scf_register_t*     rsp  = x64_find_register("rsp");
        scf_register_t*     rax  = x64_find_register("rax");
+       scf_register_t*     eax  = x64_find_register("eax");
 //     scf_x64_OpCode_t*   xor;
        scf_x64_OpCode_t*   mov;
        scf_x64_OpCode_t*   sub;
@@ -502,15 +524,15 @@ static int _x64_inst_call_handler(scf_native_t* ctx, scf_3ac_code_t* c)
                scf_loge("\n");
                return ret;
        }
-       uint64_t imm = ret > 0;
+       uint32_t imm = ret > 0;
 
-       mov  = x64_find_OpCode(SCF_X64_MOV, 8,8, SCF_X64_I2G);
-       inst = x64_make_inst_I2G(mov, rax, (uint8_t*)&imm, sizeof(imm));
+       mov  = x64_find_OpCode(SCF_X64_MOV, 4,4, SCF_X64_I2G);
+       inst = x64_make_inst_I2G(mov, eax, (uint8_t*)&imm, sizeof(imm));
        X64_INST_ADD_CHECK(c->instructions, inst);
 
        scf_register_t* saved_regs[X64_ABI_CALLER_SAVES_NB];
 
-       int save_size = x64_caller_save_regs(c->instructions, x64_abi_caller_saves, X64_ABI_CALLER_SAVES_NB, stack_size, saved_regs);
+       int save_size = x64_caller_save_regs(c, x64_abi_caller_saves, X64_ABI_CALLER_SAVES_NB, stack_size, saved_regs);
        if (save_size < 0) {
                scf_loge("\n");
                return save_size;
@@ -2117,7 +2139,7 @@ static int _x64_inst_va_arg_handler(scf_native_t* ctx, scf_3ac_code_t* c)
        int size     = x64_variable_size(v);
 
        uint32_t nints   = X64_ABI_NB;
-       uint32_t nfloats = X64_ABI_NB;
+       uint32_t nfloats = X64_ABI_FLOAT_NB;
        uint32_t offset  = 0;
        uint32_t incptr  = 8;
 
index 0bec39239d82146cee12d3f4723191c32045ef3c..80548d113ce3731357af8c4a57e48ed3f951815c 100644 (file)
@@ -207,19 +207,23 @@ void x64_registers_print()
        }
 }
 
-int x64_caller_save_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs)
+int x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs)
 {
-       int i;
-       int j;
+       scf_basic_block_t*  bb = c->basic_block;
+       scf_dag_node_t*     dn;
+
+       scf_instruction_t*  inst;
+       scf_x64_OpCode_t*   push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
+       scf_x64_OpCode_t*   mov  = x64_find_OpCode(SCF_X64_MOV,  8,8, SCF_X64_G2E);
+       scf_register_t*     rsp  = x64_find_register("rsp");
        scf_register_t*     r;
        scf_register_t*     r2;
-       scf_register_t*     rsp  = x64_find_register("rsp");
-       scf_x64_OpCode_t*   mov  = x64_find_OpCode(SCF_X64_MOV,  8,8, SCF_X64_G2E);
-       scf_x64_OpCode_t*   push = x64_find_OpCode(SCF_X64_PUSH, 8,8, SCF_X64_G);
-       scf_instruction_t*  inst;
 
+       int i;
+       int j;
+       int k;
        int size = 0;
-       int k    = 0;
+       int n    = 0;
 
        for (j = 0; j < nb_regs; j++) {
                r2 = x64_find_register_type_id_bytes(0, regs[j], 8);
@@ -233,8 +237,27 @@ int x64_caller_save_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs
                        if (0 == r->dag_nodes->size)
                                continue;
 
-                       if (X64_COLOR_CONFLICT(r2->color, r->color))
-                               break;
+                       if (X64_COLOR_CONFLICT(r2->color, r->color)) {
+
+                               for (k = 0; k < r->dag_nodes->size; k++) {
+                                       dn =        r->dag_nodes->data[k];
+
+                                       if (scf_vector_find(bb->exit_dn_actives, dn)
+                                                       || scf_vector_find(bb->dn_saves, dn)
+                                                       || scf_vector_find(bb->dn_resaves, dn)) {
+
+                                               scf_variable_t* v = dn->var;
+                                               if (v && v->w)
+                                                       scf_logw("dn: %#lx, v_%d/%s/%#lx\n", 0xffff & (uintptr_t)dn, v->w->line, v->w->text->data, 0xffff & (uintptr_t)v);
+                                               else
+                                                       scf_logw("dn: %#lx, v_%#lx\n", 0xffff & (uintptr_t)dn, 0xffff & (uintptr_t)v);
+                                               break;
+                                       }
+                               }
+
+                               if (k < r->dag_nodes->size)
+                                       break;
+                       }
                }
 
                if (i == sizeof(x64_registers) / sizeof(x64_registers[0]))
@@ -244,29 +267,29 @@ int x64_caller_save_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs
                        inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2);
                else
                        inst = x64_make_inst_G(push, r2);
-               X64_INST_ADD_CHECK(instructions, inst);
+               X64_INST_ADD_CHECK(c->instructions, inst);
 
-               saved_regs[k++] = r2;
+               saved_regs[n++] = r2;
                size += 8;
        }
 
        if (size & 0xf) {
-               r2 = saved_regs[k - 1];
+               r2 = saved_regs[n - 1];
 
                if (stack_size > 0)
                        inst = x64_make_inst_G2P(mov, rsp, size + stack_size, r2);
                else
                        inst = x64_make_inst_G(push, r2);
-               X64_INST_ADD_CHECK(instructions, inst);
+               X64_INST_ADD_CHECK(c->instructions, inst);
 
-               saved_regs[k++] = r2;
+               saved_regs[n++] = r2;
                size += 8;
        }
 
        if (stack_size > 0) {
-               for (j = 0; j < k / 2; j++) {
+               for (j = 0; j < n / 2; j++) {
 
-                       i  = k - 1 - j;
+                       i  = n - 1 - j;
                        SCF_XCHG(saved_regs[i], saved_regs[j]);
                }
        }
@@ -1296,7 +1319,7 @@ void x64_call_rabi(int* p_nints, int* p_nfloats, scf_3ac_code_t* c)
                int size     = x64_variable_size (dn->var);
 
                if (is_float) {
-                       if (nfloats < X64_ABI_NB)
+                       if (nfloats < X64_ABI_FLOAT_NB)
                                dn->rabi2 = x64_find_register_type_id_bytes(is_float, x64_abi_float_regs[nfloats++], size);
                        else
                                dn->rabi2 = NULL;
index 832c62e652b4d0d4def1bd11da240fbd549e740b..6c90f72c624426511d229311cf42217d3836312d 100644 (file)
@@ -41,6 +41,7 @@ static uint32_t x64_abi_regs[] =
        SCF_X64_REG_R8,
        SCF_X64_REG_R9,
 };
+#define X64_ABI_NB (sizeof(x64_abi_regs) / sizeof(x64_abi_regs[0]))
 
 static uint32_t x64_abi_float_regs[] =
 {
@@ -48,8 +49,12 @@ static uint32_t x64_abi_float_regs[] =
        SCF_X64_REG_XMM1,
        SCF_X64_REG_XMM2,
        SCF_X64_REG_XMM3,
+       SCF_X64_REG_XMM4,
+       SCF_X64_REG_XMM5,
+       SCF_X64_REG_XMM6,
+       SCF_X64_REG_XMM7,
 };
-#define X64_ABI_NB (sizeof(x64_abi_regs) / sizeof(x64_abi_regs[0]))
+#define X64_ABI_FLOAT_NB (sizeof(x64_abi_float_regs) / sizeof(x64_abi_float_regs[0]))
 
 static uint32_t x64_abi_ret_regs[] =
 {
@@ -132,7 +137,8 @@ int                 x64_save_var2(scf_dag_node_t* dn, scf_register_t* r, scf_3ac
 
 int                 x64_push_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs);
 int                 x64_pop_regs (scf_vector_t* instructions, scf_register_t** regs, int nb_regs, scf_register_t** updated_regs, int nb_updated);
-int                 x64_caller_save_regs(scf_vector_t* instructions, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs);
+
+int                 x64_caller_save_regs(scf_3ac_code_t* c, uint32_t* regs, int nb_regs, int stack_size, scf_register_t** saved_regs);
 
 int                 x64_push_callee_regs(scf_3ac_code_t* c, scf_function_t* f);
 int                 x64_pop_callee_regs (scf_3ac_code_t* c, scf_function_t* f);