Only (IV - RC) is allowed for induction variables.
[libfirm] / ir / opt / jumpthreading.c
index 39de745..eeca132 100644 (file)
  * @brief   Path-Sensitive Jump Threading
  * @date    10. Sep. 2006
  * @author  Christoph Mallon, Matthias Braun
- * @version $Id$
  */
 #include "config.h"
 
 #include "iroptimize.h"
 
 #include <assert.h>
+#include <stdbool.h>
 #include "array_t.h"
 #include "debug.h"
 #include "ircons.h"
@@ -49,7 +49,7 @@
 
 #undef AVOID_PHIB
 
-DEBUG_ONLY(static firm_dbg_module_t *dbg);
+DEBUG_ONLY(static firm_dbg_module_t *dbg;)
 
 /**
  * Add the new predecessor x to node node, which is either a Block or a Phi
@@ -294,7 +294,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
                }
                /* ignore control flow */
                mode = get_irn_mode(node);
-               if (mode == mode_X || is_Cond(node))
+               if (mode == mode_X || is_Cond(node) || is_Switch(node))
                        continue;
 #ifdef AVOID_PHIB
                /* we may not copy mode_b nodes, because this could produce Phi with
@@ -347,7 +347,7 @@ static void copy_and_fix(const jumpthreading_env_t *env, ir_node *block,
                ir_mode *mode;
 
                mode = get_irn_mode(node);
-               if (mode == mode_X || is_Cond(node))
+               if (mode == mode_X || is_Cond(node) || is_Switch(node))
                        continue;
 #ifdef AVOID_PHIB
                if (mode == mode_b)
@@ -633,7 +633,7 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
 static void thread_jumps(ir_node* block, void* data)
 {
        jumpthreading_env_t env;
-       int *changed = (int*)data;
+       bool *changed = (bool*)data;
        ir_node *selector;
        ir_node *projx;
        ir_node *cond;
@@ -654,15 +654,12 @@ static void thread_jumps(ir_node* block, void* data)
        assert(get_irn_mode(projx) == mode_X);
 
        cond = get_Proj_pred(projx);
-       if (!is_Cond(cond))
-               return;
-
-       selector = get_Cond_selector(cond);
        /* TODO handle switch Conds */
-       if (get_irn_mode(selector) != mode_b)
+       if (!is_Cond(cond))
                return;
 
        /* handle cases that can be immediately evaluated */
+       selector = get_Cond_selector(cond);
        selector_evaluated = -1;
        if (is_Cmp(selector)) {
                ir_node *left  = get_Cmp_left(selector);
@@ -706,14 +703,14 @@ static void thread_jumps(ir_node* block, void* data)
                ir_graph *irg = get_irn_irg(block);
                ir_node  *bad = new_r_Bad(irg, mode_X);
                exchange(projx, bad);
-               *changed = 1;
+               *changed = true;
                return;
        } else if (selector_evaluated == 1) {
                dbg_info *dbgi = get_irn_dbg_info(selector);
                ir_node  *jmp  = new_rd_Jmp(dbgi, get_nodes_block(projx));
                DBG_OPT_JUMPTHREADING(projx, jmp);
                exchange(projx, jmp);
-               *changed = 1;
+               *changed = true;
                return;
        }
 
@@ -750,41 +747,36 @@ static void thread_jumps(ir_node* block, void* data)
        set_Block_cfgpred(env.cnst_pred, cnst_pos, badX);
 
        /* the graph is changed now */
-       *changed = 1;
+       *changed = true;
 }
 
 void opt_jumpthreading(ir_graph* irg)
 {
-       int changed, rerun;
+       bool changed;
+       bool rerun;
+
+       assure_irg_properties(irg,
+               IR_GRAPH_PROPERTY_NO_UNREACHABLE_CODE
+               | IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES
+               | IR_GRAPH_PROPERTY_NO_CRITICAL_EDGES);
 
        FIRM_DBG_REGISTER(dbg, "firm.opt.jumpthreading");
 
        DB((dbg, LEVEL_1, "===> Performing jumpthreading on %+F\n", irg));
 
-       remove_critical_cf_edges(irg);
-
-       /* ugly: jump threading might get confused by garbage nodes
-        * of mode_X in copy_and_fix_node(), so remove all garbage edges. */
-       edges_deactivate(irg);
-
-       edges_assure(irg);
        ir_reserve_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_IRN_VISITED);
 
-       changed = 0;
+       changed = false;
        do {
-               rerun = 0;
+               rerun = false;
                irg_block_walk_graph(irg, thread_jumps, NULL, &rerun);
                changed |= rerun;
        } while (rerun);
 
        ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_IRN_VISITED);
 
-       if (changed) {
-               /* control flow changed, some blocks may become dead */
-               set_irg_doms_inconsistent(irg);
-               set_irg_extblk_inconsistent(irg);
-               set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
-       }
+       confirm_irg_properties(irg,
+               changed ? IR_GRAPH_PROPERTIES_NONE : IR_GRAPH_PROPERTIES_ALL);
 }
 
 /* Creates an ir_graph pass for opt_jumpthreading. */