remove sel_based_null_check flag
[libfirm] / ir / opt / opt_osr.c
index 1d39084..cdab220 100644 (file)
@@ -22,7 +22,6 @@
  * @brief   Operator Strength Reduction.
  * @date    12.5.2006
  * @author  Michael Beck
- * @version $Id$
  * @brief
  *  Implementation of the Operator Strength Reduction algorithm
  *  by Keith D. Cooper, L. Taylor Simpson, Christopher A. Vick.
@@ -46,6 +45,7 @@
 #include "set.h"
 #include "tv.h"
 #include "hashptr.h"
+#include "util.h"
 #include "irtools.h"
 #include "irloop_t.h"
 #include "array.h"
@@ -608,13 +608,12 @@ static int is_counter_iv(ir_node *iv, iv_env *env)
  */
 static int check_users_for_reg_pressure(ir_node *iv, iv_env *env)
 {
-       ir_node    *irn, *header;
+       ir_node    *irn;
        ir_node    *have_user = NULL;
        ir_node    *have_cmp  = NULL;
        node_entry *e         = get_irn_ne(iv, env);
        scc        *pscc      = e->pscc;
 
-       header = e->header;
        for (irn = pscc->head; irn != NULL; irn = e->next) {
                const ir_edge_t *edge;
 
@@ -1156,6 +1155,12 @@ static ir_node *applyOneEdge(ir_node *iv, ir_node *rc, LFTR_edge *e, iv_env *env
                        panic("Unsupported opcode");
                }
 
+               if (tv == tarval_bad || tv_init == tarval_bad) {
+                       tarval_set_integer_overflow_mode(ovmode);
+                       DB((dbg, LEVEL_4, " = OVERFLOW"));
+                       return NULL;
+               }
+
                if (pscc->code == iro_Add) {
                        tv_end = tarval_add(tv, tv_incr);
                } else {
@@ -1165,7 +1170,7 @@ static ir_node *applyOneEdge(ir_node *iv, ir_node *rc, LFTR_edge *e, iv_env *env
 
                tarval_set_integer_overflow_mode(ovmode);
 
-               if (tv == tarval_bad || tv_init == tarval_bad || tv_end == tarval_bad) {
+               if (tv_end == tarval_bad) {
                        DB((dbg, LEVEL_4, " = OVERFLOW"));
                        return NULL;
                }
@@ -1275,7 +1280,8 @@ static void lftr(ir_graph *irg, iv_env *env)
  */
 static void clear_and_fix(ir_node *irn, void *env)
 {
-       int *moved = (int*)env;
+       (void)env;
+
        set_irn_link(irn, NULL);
 
        if (is_Proj(irn)) {
@@ -1284,7 +1290,6 @@ static void clear_and_fix(ir_node *irn, void *env)
 
                if (get_nodes_block(irn) != pred_block) {
                        set_nodes_block(irn, pred_block);
-                       *moved = 1;
                }
        }
 }  /* clear_and_fix */
@@ -1294,7 +1299,6 @@ static void clear_and_fix(ir_node *irn, void *env)
 void remove_phi_cycles(ir_graph *irg)
 {
        iv_env env;
-       int    projs_moved;
 
        FIRM_DBG_REGISTER(dbg, "firm.opt.remove_phi");
 
@@ -1317,10 +1321,7 @@ void remove_phi_cycles(ir_graph *irg)
         * the same block as their predecessors.
         * This can improve the placement of new nodes.
         */
-       projs_moved = 0;
-       irg_walk_graph(irg, NULL, clear_and_fix, &projs_moved);
-       if (projs_moved)
-               set_irg_outs_inconsistent(irg);
+       irg_walk_graph(irg, NULL, clear_and_fix, NULL);
 
        /* we need outs for calculating the post order */
        assure_irg_outs(irg);
@@ -1334,7 +1335,6 @@ void remove_phi_cycles(ir_graph *irg)
        ir_free_resources(irg, IR_RESOURCE_IRN_LINK);
 
        if (env.replaced) {
-               set_irg_outs_inconsistent(irg);
                DB((dbg, LEVEL_1, "remove_phi_cycles: %u Cycles removed\n\n", env.replaced));
        }
 
@@ -1398,6 +1398,19 @@ static void fix_adds_and_subs(ir_node *irn, void *ctx)
                                        set_Sub_right(irn, right);
                                }
                        }
+               } else if (mode_is_reference(mode)) {
+                       ir_node *left   = get_Sub_left(irn);
+                       ir_node *right  = get_Sub_right(irn);
+                       ir_mode *l_mode = get_irn_mode(left);
+                       ir_mode *r_mode = get_irn_mode(right);
+                       if (mode_is_int(l_mode)) {
+                               /* Usually, Sub(I*,P) is an error, hence the verifier rejects it.
+                                * However, it is correct in this case, so add Conv to make verifier happy. */
+                               ir_node *block = get_nodes_block(right);
+                               ir_node *lconv = new_r_Conv(block, left, r_mode);
+                               assert(mode_is_reference(r_mode));
+                               set_Sub_left(irn, lconv);
+                       }
                }
        }
 }  /* fix_adds_and_subs */
@@ -1407,7 +1420,6 @@ void opt_osr(ir_graph *irg, unsigned flags)
 {
        iv_env   env;
        int      edges;
-       int      projs_moved;
 
        FIRM_DBG_REGISTER(dbg, "firm.opt.osr");
 
@@ -1427,13 +1439,10 @@ void opt_osr(ir_graph *irg, unsigned flags)
        env.process_scc   = process_scc;
 
        /* Clear all links and move Proj nodes into the
-          the same block as it's predecessors.
-          This can improve the placement of new nodes.
+        * the same block as its predecessors.
+        * This can improve the placement of new nodes.
         */
-       projs_moved = 0;
-       irg_walk_graph(irg, NULL, clear_and_fix, &projs_moved);
-       if (projs_moved)
-               set_irg_outs_inconsistent(irg);
+       irg_walk_graph(irg, NULL, clear_and_fix, NULL);
 
        /* we need dominance */
        assure_doms(irg);
@@ -1456,7 +1465,6 @@ void opt_osr(ir_graph *irg, unsigned flags)
                lftr(irg, &env);
                (void)lftr;
 
-               set_irg_outs_inconsistent(irg);
                DB((dbg, LEVEL_1, "Replacements: %u + %u (lftr)\n\n", env.replaced, env.lftr_replaced));
        }
        ir_free_resources(irg, IR_RESOURCE_IRN_LINK);