fix warnings reported by cparser
[libfirm] / ir / opt / jumpthreading.c
index da92b0b..39de745 100644 (file)
@@ -60,7 +60,7 @@ static void add_pred(ir_node* node, ir_node* x)
        int n;
        int i;
 
-       assert(is_Block(node) || is_Phi(node));
+       assert(is_Block(node));
 
        n = get_irn_arity(node);
        NEW_ARR_A(ir_node*, ins, n + 1);
@@ -194,6 +194,29 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val,
        }
 }
 
+/**
+ * jumpthreading produces critical edges, e.g. B-C:
+ *     A         A
+ *  \ /       \  |
+ *   B    =>   B |
+ *  / \       / \|
+ *     C         C
+ *
+ * By splitting this critical edge more threadings might be possible.
+ */
+static void split_critical_edge(ir_node *block, int pos)
+{
+       ir_graph *irg = get_irn_irg(block);
+       ir_node *in[1];
+       ir_node *new_block;
+       ir_node *new_jmp;
+
+       in[0] = get_Block_cfgpred(block, pos);
+       new_block = new_r_Block(irg, 1, in);
+       new_jmp = new_r_Jmp(new_block);
+       set_Block_cfgpred(block, pos, new_jmp);
+}
+
 typedef struct jumpthreading_env_t {
        ir_node       *true_block;
        ir_node       *cmp;        /**< The Compare node that might be partial evaluated */
@@ -455,6 +478,8 @@ static ir_node *find_const_or_confirm(jumpthreading_env_t *env, ir_node *jump,
                /* adjust true_block to point directly towards our jump */
                add_pred(env->true_block, jump);
 
+               split_critical_edge(env->true_block, 0);
+
                /* we need a bigger visited nr when going back */
                env->visited_nr++;
 
@@ -518,6 +543,8 @@ static ir_node *find_candidate(jumpthreading_env_t *env, ir_node *jump,
                /* adjust true_block to point directly towards our jump */
                add_pred(env->true_block, jump);
 
+               split_critical_edge(env->true_block, 0);
+
                /* we need a bigger visited nr when going back */
                env->visited_nr++;
 
@@ -617,6 +644,7 @@ static void thread_jumps(ir_node* block, void* data)
        ir_node *badX;
        int      cnst_pos;
 
+       /* we do not deal with Phis, so restrict this to exactly one cfgpred */
        if (get_Block_n_cfgpreds(block) != 1)
                return;