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);
/* In case of a bad input to a block we need to return the bad value */
if (is_Bad(block)) {
ir_graph *irg = get_irn_irg(block);
- return new_r_Bad(irg);
+ return new_r_Bad(irg, mode);
}
/* the other defs can't be marked for cases where a user of the original
}
}
+/**
+ * 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 *copy;
ir_mode *mode;
+ if (is_End(node)) {
+ /* edge is a Keep edge. If the end block is unreachable via normal control flow,
+ * we must maintain end's reachability with Keeps.
+ */
+ keep_alive(copy_block);
+ continue;
+ }
/* ignore control flow */
mode = get_irn_mode(node);
if (mode == mode_X || is_Cond(node))
int selector_evaluated;
const ir_edge_t *edge, *next;
ir_graph *irg;
- ir_node *bad;
+ 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;
if (selector_evaluated == 0) {
ir_graph *irg = get_irn_irg(block);
- bad = new_r_Bad(irg);
+ ir_node *bad = new_r_Bad(irg, mode_X);
exchange(projx, bad);
*changed = 1;
return;
if (copy_block == NULL)
return;
+ /* We might thread the condition block of an infinite loop,
+ * such that there is no path to End anymore. */
+ keep_alive(block);
+
/* we have to remove the edge towards the pred as the pred now
* jumps into the true_block. We also have to shorten Phis
* in our block because of this */
- bad = new_r_Bad(irg);
+ badX = new_r_Bad(irg, mode_X);
cnst_pos = env.cnst_pos;
/* shorten Phis */
foreach_out_edge_safe(env.cnst_pred, edge, next) {
ir_node *node = get_edge_src_irn(edge);
- if (is_Phi(node))
+ if (is_Phi(node)) {
+ ir_node *bad = new_r_Bad(irg, get_irn_mode(node));
set_Phi_pred(node, cnst_pos, bad);
+ }
}
- set_Block_cfgpred(env.cnst_pred, cnst_pos, bad);
+ set_Block_cfgpred(env.cnst_pred, cnst_pos, badX);
/* the graph is changed now */
*changed = 1;
if (changed) {
/* control flow changed, some blocks may become dead */
- set_irg_outs_inconsistent(irg);
set_irg_doms_inconsistent(irg);
set_irg_extblk_inconsistent(irg);
- set_irg_loopinfo_inconsistent(irg);
set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
}
}