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);
}
}
+/**
+ * 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 */
/* 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++;
/* 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++;
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;