- Improved addressmode optimisation for conv nodes
[libfirm] / ir / be / ia32 / bearch_ia32.c
index 2e87c73..3abf57d 100644 (file)
@@ -130,24 +130,17 @@ static const arch_register_req_t *ia32_get_irn_reg_req(const void *self, arch_re
                        return NULL;
                }
 
-               if (pos == -1) {
-                       node_pos = ia32_translate_proj_pos(irn);
-               }
-               else {
-                       node_pos = pos;
-               }
-
-               irn = skip_Proj(irn);
+               node_pos = (pos == -1) ? get_Proj_proj(irn) : pos;
+               irn      = skip_Proj(irn);
 
                DB((mod, LEVEL_1, "skipping Proj, going to %+F at pos %d ... ", irn, node_pos));
        }
 
        if (is_ia32_irn(irn)) {
-               if (pos >= 0) {
-                       irn_req = get_ia32_in_req(irn, pos);
-               }
-               else {
-                       irn_req = get_ia32_out_req(irn, node_pos);
+               irn_req = (pos >= 0) ? get_ia32_in_req(irn, pos) : get_ia32_out_req(irn, node_pos);
+               if (irn_req == NULL) {
+                       /* no requirements */
+                       return NULL;
                }
 
                DB((mod, LEVEL_1, "returning reqs for %+F at pos %d\n", irn, pos));
@@ -203,7 +196,7 @@ static void ia32_set_irn_reg(const void *self, ir_node *irn, const arch_register
        DBG((ops->cg->mod, LEVEL_1, "ia32 assigned register %s to node %+F\n", reg->name, irn));
 
        if (is_Proj(irn)) {
-               pos = ia32_translate_proj_pos(irn);
+               pos = get_Proj_proj(irn);
                irn = skip_Proj(irn);
        }
 
@@ -228,7 +221,7 @@ static const arch_register_t *ia32_get_irn_reg(const void *self, const ir_node *
                        return NULL;
                }
 
-               pos = ia32_translate_proj_pos(irn);
+               pos = get_Proj_proj(irn);
                irn = skip_Proj(irn);
        }
 
@@ -271,37 +264,21 @@ static arch_irn_class_t ia32_classify(const void *self, const ir_node *irn) {
 }
 
 static arch_irn_flags_t ia32_get_flags(const void *self, const ir_node *irn) {
+       arch_irn_flags_t flags;
+       ir_node          *pred = is_Proj(irn) && mode_is_datab(get_irn_mode(irn)) ? get_Proj_pred(irn) : NULL;
 
-       if(is_Proj(irn)) {
-               ir_node *pred = get_Proj_pred(irn);
-               int ia32_op   = get_ia32_irn_opcode(pred);
-               long proj     = get_Proj_proj(irn);
-               if (iro_ia32_Push == ia32_op && proj == pn_ia32_Push_stack) {
-                       /* Push modifies always ESP, this cannot be changed */
-                       return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
-               }
-               if (iro_ia32_Pop == ia32_op && proj == pn_ia32_Pop_stack) {
-                       /* Pop modifies always ESP, this cannot be changed */
-                       return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
-               }
-               if (iro_ia32_AddSP == ia32_op && proj == pn_ia32_AddSP_stack) {
-                       /* AddSP modifies always ESP, this cannot be changed */
-                       return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
-               }
-               if (iro_ia32_SubSP == ia32_op && proj == pn_ia32_SubSP_stack) {
-                       /* SubSP modifies always ESP, this cannot be changed */
-                       return arch_irn_flags_modify_sp | arch_irn_flags_ignore;
-               }
-       }
-
-       irn = skip_Proj(irn);
-       if (is_ia32_irn(irn))
-               return get_ia32_flags(irn);
+       if (is_Unknown(irn))
+               flags = arch_irn_flags_ignore;
        else {
-               if (is_Unknown(irn))
-                       return arch_irn_flags_ignore;
-               return 0;
+           /* pred is only set, if we have a Proj */
+               flags = pred && is_ia32_irn(pred) ? get_ia32_out_flags(pred, get_Proj_proj(irn)) : arch_irn_flags_none;
+
+               irn = skip_Proj(irn);
+               if (is_ia32_irn(irn))
+                       flags |= get_ia32_flags(irn);
        }
+
+       return flags;
 }
 
 /**
@@ -1022,9 +999,8 @@ static void transform_to_Load(ia32_transform_env_t *env) {
                else
                        new_op = new_rd_ia32_vfld(env->dbg, env->irg, env->block, ptr, noreg, mem);
        }
-       else {
+       else
                new_op = new_rd_ia32_Load(env->dbg, env->irg, env->block, ptr, noreg, mem);
-       }
 
        set_ia32_am_support(new_op, ia32_am_Source);
        set_ia32_op_type(new_op, ia32_AddrModeS);
@@ -1035,7 +1011,7 @@ static void transform_to_Load(ia32_transform_env_t *env) {
 
        DBG_OPT_RELOAD2LD(irn, new_op);
 
-       proj = new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, pn_Load_res);
+       proj = new_rd_Proj(env->dbg, env->irg, env->block, new_op, mode, pn_ia32_Load_res);
 
        if (sched_point) {
                sched_add_after(sched_point, new_op);