- Improved addressmode optimisation for conv nodes
[libfirm] / ir / be / ia32 / bearch_ia32.c
index ee0e16c..3abf57d 100644 (file)
@@ -138,6 +138,10 @@ static const arch_register_req_t *ia32_get_irn_reg_req(const void *self, arch_re
 
        if (is_ia32_irn(irn)) {
                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));
 
@@ -222,14 +226,9 @@ static const arch_register_t *ia32_get_irn_reg(const void *self, const ir_node *
        }
 
        if (is_ia32_irn(irn)) {
-               /* retrieve "real" x87 register */
-               if (ia32_has_x87_register(irn))
-                       reg = get_ia32_attr(irn)->x87[pos + 2];
-               else {
-                       const arch_register_t **slots;
-                       slots = get_ia32_slots(irn);
-                       reg   = slots[pos];
-               }
+               const arch_register_t **slots;
+               slots = get_ia32_slots(irn);
+               reg   = slots[pos];
        }
        else {
                reg = ia32_get_firm_reg(irn, cur_reg_set);
@@ -265,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;
 }
 
 /**