Commit 98d775a0 authored by Matthias Braun's avatar Matthias Braun
Browse files

make get_Block_cfgpred_block return NULL on Bad cfopt

Previously a Bad node was returned which could hide problems and more
importantly you create new nodes (the BadBB) in an operation that apparently
only queries the graph.
parent 7fe78d2b
...@@ -242,8 +242,7 @@ FIRM_API int get_Block_cfgpred_pos(const ir_node *block, const ir_node *pred); ...@@ -242,8 +242,7 @@ FIRM_API int get_Block_cfgpred_pos(const ir_node *block, const ir_node *pred);
* *
* Returns the block corresponding to the predecessor pos of block. * Returns the block corresponding to the predecessor pos of block.
* *
* If we encounter the Bad node, this function does not return Start block, but * If we encounter the Bad node as controlflow predecessor NULL is returned.
* the Bad node.
*/ */
FIRM_API ir_node *get_Block_cfgpred_block(const ir_node *node, int pos); FIRM_API ir_node *get_Block_cfgpred_block(const ir_node *node, int pos);
......
...@@ -90,7 +90,7 @@ static void cdep_pre(ir_node *node, void *ctx) ...@@ -90,7 +90,7 @@ static void cdep_pre(ir_node *node, void *ctx)
(void)ctx; (void)ctx;
for (int i = get_Block_n_cfgpreds(node); i-- > 0; ) { for (int i = get_Block_n_cfgpreds(node); i-- > 0; ) {
ir_node *pred = get_Block_cfgpred_block(node, i); ir_node *pred = get_Block_cfgpred_block(node, i);
if (is_Bad(pred)) if (pred == NULL)
continue; continue;
ir_node *pdom = get_Block_ipostdom(pred); ir_node *pdom = get_Block_ipostdom(pred);
......
...@@ -160,7 +160,7 @@ static double get_cf_probability(const ir_node *bb, int pos, ...@@ -160,7 +160,7 @@ static double get_cf_probability(const ir_node *bb, int pos,
double inv_loop_weight) double inv_loop_weight)
{ {
const ir_node *pred = get_Block_cfgpred_block(bb, pos); const ir_node *pred = get_Block_cfgpred_block(bb, pos);
if (is_Bad(pred)) if (pred == NULL)
return 0; return 0;
const ir_loop *loop = get_irn_loop(bb); const ir_loop *loop = get_irn_loop(bb);
......
...@@ -300,7 +300,7 @@ static int is_head(ir_node *n, ir_node *root) ...@@ -300,7 +300,7 @@ static int is_head(ir_node *n, ir_node *root)
for (int i = 0, arity = get_Block_n_cfgpreds(n); i < arity; i++) { for (int i = 0, arity = get_Block_n_cfgpreds(n); i < arity; i++) {
ir_node *pred = get_Block_cfgpred_block(n, i); ir_node *pred = get_Block_cfgpred_block(n, i);
/* ignore Bad control flow: it cannot happen */ /* ignore Bad control flow: it cannot happen */
if (is_Bad(pred)) if (pred == NULL)
continue; continue;
if (is_backedge(n, i)) if (is_backedge(n, i))
continue; continue;
...@@ -333,7 +333,7 @@ static int is_endless_head(ir_node *n, ir_node *root) ...@@ -333,7 +333,7 @@ static int is_endless_head(ir_node *n, ir_node *root)
for (int i = 0, arity = get_Block_n_cfgpreds(n); i < arity; i++) { for (int i = 0, arity = get_Block_n_cfgpreds(n); i < arity; i++) {
ir_node *pred = get_Block_cfgpred_block(n, i); ir_node *pred = get_Block_cfgpred_block(n, i);
/* ignore Bad control flow: it cannot happen */ /* ignore Bad control flow: it cannot happen */
if (is_Bad(pred)) if (pred == NULL)
continue; continue;
if (is_backedge(n, i)) if (is_backedge(n, i))
continue; continue;
...@@ -358,7 +358,7 @@ static int smallest_dfn_pred(ir_node *n, int limit) ...@@ -358,7 +358,7 @@ static int smallest_dfn_pred(ir_node *n, int limit)
for (int i = 0, arity = get_Block_n_cfgpreds(n); i < arity; i++) { for (int i = 0, arity = get_Block_n_cfgpreds(n); i < arity; i++) {
ir_node *pred = get_Block_cfgpred_block(n, i); ir_node *pred = get_Block_cfgpred_block(n, i);
/* ignore Bad control flow: it cannot happen */ /* ignore Bad control flow: it cannot happen */
if (is_Bad(pred)) if (pred == NULL)
continue; continue;
if (is_backedge(n, i) || !irn_is_in_stack(pred)) if (is_backedge(n, i) || !irn_is_in_stack(pred))
continue; continue;
...@@ -380,7 +380,7 @@ static int largest_dfn_pred(ir_node *n) ...@@ -380,7 +380,7 @@ static int largest_dfn_pred(ir_node *n)
for (int i = 0, arity = get_Block_n_cfgpreds(n); i < arity; i++) { for (int i = 0, arity = get_Block_n_cfgpreds(n); i < arity; i++) {
ir_node *pred = get_Block_cfgpred_block(n, i); ir_node *pred = get_Block_cfgpred_block(n, i);
/* ignore Bad control flow: it cannot happen */ /* ignore Bad control flow: it cannot happen */
if (is_Bad(pred)) if (pred == NULL)
continue; continue;
if (is_backedge(n, i) || !irn_is_in_stack(pred)) if (is_backedge(n, i) || !irn_is_in_stack(pred))
continue; continue;
...@@ -488,7 +488,7 @@ static void cfscc(ir_node *n) ...@@ -488,7 +488,7 @@ static void cfscc(ir_node *n)
continue; continue;
ir_node *m = get_Block_cfgpred_block(n, i); ir_node *m = get_Block_cfgpred_block(n, i);
/* ignore Bad control flow: it cannot happen */ /* ignore Bad control flow: it cannot happen */
if (is_Bad(m)) if (m == NULL)
continue; continue;
cfscc(m); cfscc(m);
......
...@@ -427,7 +427,7 @@ static void init_tmp_pdom_info(ir_node *block, tmp_dom_info *parent, ...@@ -427,7 +427,7 @@ static void init_tmp_pdom_info(ir_node *block, tmp_dom_info *parent,
/* Iterate */ /* Iterate */
for (int i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) { for (int i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
ir_node *pred = get_Block_cfgpred_block(block, i); ir_node *pred = get_Block_cfgpred_block(block, i);
if (is_Bad(pred)) if (pred == NULL)
continue; continue;
init_tmp_pdom_info(pred, tdi, tdi_list, used, n_blocks); init_tmp_pdom_info(pred, tdi, tdi_list, used, n_blocks);
} }
......
...@@ -332,6 +332,8 @@ unsigned lv_chk_bl_xxx(lv_chk_t *lv, const ir_node *bl, const ir_node *var) ...@@ -332,6 +332,8 @@ unsigned lv_chk_bl_xxx(lv_chk_t *lv, const ir_node *bl, const ir_node *var)
if (is_Phi(user)) { if (is_Phi(user)) {
int pos = get_edge_src_pos(edge); int pos = get_edge_src_pos(edge);
use_bl = get_Block_cfgpred_block(use_bl, pos); use_bl = get_Block_cfgpred_block(use_bl, pos);
if (use_bl == NULL)
continue;
mask |= lv_chk_state_end; mask |= lv_chk_state_end;
} }
......
...@@ -1340,6 +1340,8 @@ void be_gas_begin_block(const ir_node *block, bool needs_label) ...@@ -1340,6 +1340,8 @@ void be_gas_begin_block(const ir_node *block, bool needs_label)
} else { } else {
for (int i = 0; i < arity; ++i) { for (int i = 0; i < arity; ++i) {
ir_node *predblock = get_Block_cfgpred_block(block, i); ir_node *predblock = get_Block_cfgpred_block(block, i);
if (predblock == NULL)
continue;
be_emit_char(' '); be_emit_char(' ');
be_gas_emit_block_name(predblock); be_gas_emit_block_name(predblock);
} }
......
...@@ -159,7 +159,7 @@ static ir_node *set_phi_arguments(ir_node *phi, int pos) ...@@ -159,7 +159,7 @@ static ir_node *set_phi_arguments(ir_node *phi, int pos)
for (i = 0; i < arity; ++i) { for (i = 0; i < arity; ++i) {
ir_node *cfgpred = get_Block_cfgpred_block(block, i); ir_node *cfgpred = get_Block_cfgpred_block(block, i);
ir_node *value; ir_node *value;
if (is_Bad(cfgpred)) { if (cfgpred == NULL) {
value = new_r_Bad(irg, mode); value = new_r_Bad(irg, mode);
} else { } else {
value = get_r_value_internal(cfgpred, pos, mode); value = get_r_value_internal(cfgpred, pos, mode);
...@@ -461,7 +461,9 @@ static ir_mode *guess_recursively(ir_node *block, int pos) ...@@ -461,7 +461,9 @@ static ir_mode *guess_recursively(ir_node *block, int pos)
n_preds = get_irn_arity(block); n_preds = get_irn_arity(block);
for (i = 0; i < n_preds; ++i) { for (i = 0; i < n_preds; ++i) {
ir_node *pred_block = get_Block_cfgpred_block(block, i); ir_node *pred_block = get_Block_cfgpred_block(block, i);
ir_mode *mode = guess_recursively(pred_block, pos); if (pred_block == NULL)
continue;
ir_mode *mode = guess_recursively(pred_block, pos);
if (mode != NULL) if (mode != NULL)
return mode; return mode;
} }
......
...@@ -340,16 +340,13 @@ static inline int is_binop_(const ir_node *node) ...@@ -340,16 +340,13 @@ static inline int is_binop_(const ir_node *node)
* *
* Returns the block corresponding to the predecessor pos. * Returns the block corresponding to the predecessor pos.
* *
* If we encounter the Bad node, this function does not return the Start block, * If we encounter the Bad node, this function returns NULL.
* but the Bad node.
*/ */
static inline ir_node *get_Block_cfgpred_block_(const ir_node *node, int pos) static inline ir_node *get_Block_cfgpred_block_(const ir_node *node, int pos)
{ {
ir_node *res = get_Block_cfgpred(node, pos); ir_node *res = get_Block_cfgpred(node, pos);
if (is_Bad(res)) { if (is_Bad(res)) {
/* must return a Bad with mode_BB! */ return NULL;
ir_graph *irg = get_irn_irg(node);
return new_r_Bad(irg, mode_BB);
} else { } else {
return get_nodes_block(res); return get_nodes_block(res);
} }
......
...@@ -283,7 +283,7 @@ static void fix_ssa(ir_node *bb, void *data) ...@@ -283,7 +283,7 @@ static void fix_ssa(ir_node *bb, void *data)
mem = get_irg_initial_mem(irg); mem = get_irg_initial_mem(irg);
} else if (arity == 1) { } else if (arity == 1) {
ir_node *pred = get_Block_cfgpred_block(bb, 0); ir_node *pred = get_Block_cfgpred_block(bb, 0);
if (!is_Bad(pred)) if (pred != NULL)
mem = (ir_node*) get_irn_link(pred); mem = (ir_node*) get_irn_link(pred);
else else
mem = new_r_NoMem(irg); mem = new_r_NoMem(irg);
...@@ -291,7 +291,7 @@ static void fix_ssa(ir_node *bb, void *data) ...@@ -291,7 +291,7 @@ static void fix_ssa(ir_node *bb, void *data)
ir_node **ins = ALLOCAN(ir_node*, arity); ir_node **ins = ALLOCAN(ir_node*, arity);
for (n = arity - 1; n >= 0; --n) { for (n = arity - 1; n >= 0; --n) {
ir_node *pred = get_Block_cfgpred_block(bb, n); ir_node *pred = get_Block_cfgpred_block(bb, n);
if (!is_Bad(pred)) if (pred != NULL)
ins[n] = (ir_node*) get_irn_link(pred); ins[n] = (ir_node*) get_irn_link(pred);
else else
ins[n] = new_r_NoMem(irg); ins[n] = new_r_NoMem(irg);
...@@ -351,6 +351,8 @@ static void instrument_irg(ir_graph *irg, ir_entity *counters, ...@@ -351,6 +351,8 @@ static void instrument_irg(ir_graph *irg, ir_entity *counters,
for (i = get_Block_n_cfgpreds(endbb) - 1; i >= 0; --i) { for (i = get_Block_n_cfgpreds(endbb) - 1; i >= 0; --i) {
ir_node *node = skip_Proj(get_Block_cfgpred(endbb, i)); ir_node *node = skip_Proj(get_Block_cfgpred(endbb, i));
ir_node *bb = get_Block_cfgpred_block(endbb, i); ir_node *bb = get_Block_cfgpred_block(endbb, i);
if (bb == NULL)
continue;
ir_node *mem; ir_node *mem;
switch (get_irn_opcode(node)) { switch (get_irn_opcode(node)) {
......
...@@ -936,9 +936,12 @@ static bool check_dominance_for_node(const ir_node *use) ...@@ -936,9 +936,12 @@ static bool check_dominance_for_node(const ir_node *use)
continue; continue;
ir_node *use_bl = bl; ir_node *use_bl = bl;
if (is_Phi(use)) if (is_Phi(use)) {
use_bl = get_Block_cfgpred_block(bl, i); use_bl = get_Block_cfgpred_block(bl, i);
if (!is_Block(use_bl) || get_Block_dom_depth(use_bl) == -1) if (use_bl == NULL)
continue;
}
if (get_Block_dom_depth(use_bl) == -1)
continue; continue;
if (!block_dominates(def_bl, use_bl)) { if (!block_dominates(def_bl, use_bl)) {
......
...@@ -584,6 +584,8 @@ restart: ...@@ -584,6 +584,8 @@ restart:
ir_node *const cond_selector = get_Cond_selector(cond); ir_node *const cond_selector = get_Cond_selector(cond);
ir_node *const lower_pred = get_Block_cfgpred_block(lower_block, 0); ir_node *const lower_pred = get_Block_cfgpred_block(lower_block, 0);
if (lower_pred == NULL)
continue;
for (up_idx = 0; up_idx < n_cfgpreds; ++up_idx) { for (up_idx = 0; up_idx < n_cfgpreds; ++up_idx) {
ir_node *upper_block; ir_node *upper_block;
ir_node *upper_cf; ir_node *upper_cf;
......
...@@ -415,7 +415,7 @@ static void optimize_blocks(ir_node *b, void *ctx) ...@@ -415,7 +415,7 @@ static void optimize_blocks(ir_node *b, void *ctx)
for (int i = k+1; i < get_Block_n_cfgpreds(b); i++) { for (int i = k+1; i < get_Block_n_cfgpreds(b); i++) {
ir_node *phi_pred = get_Block_cfgpred_block(b, i); ir_node *phi_pred = get_Block_cfgpred_block(b, i);
if (is_Bad(phi_pred)) { if (phi_pred == NULL) {
ir_graph *irg = get_irn_irg(b); ir_graph *irg = get_irn_irg(b);
ir_mode *mode = get_irn_mode(phi); ir_mode *mode = get_irn_mode(phi);
in[q_preds++] = new_r_Bad(irg, mode); in[q_preds++] = new_r_Bad(irg, mode);
......
...@@ -180,7 +180,7 @@ static ir_node *consumer_dom_dca(ir_node *dca, ir_node *consumer, ...@@ -180,7 +180,7 @@ static ir_node *consumer_dom_dca(ir_node *dca, ir_node *consumer,
for (int i = 0; i < arity; i++) { for (int i = 0; i < arity; i++) {
if (get_Phi_pred(consumer, i) == producer) { if (get_Phi_pred(consumer, i) == producer) {
ir_node *new_block = get_Block_cfgpred_block(phi_block, i); ir_node *new_block = get_Block_cfgpred_block(phi_block, i);
if (is_Bad(new_block)) if (new_block == NULL)
continue; continue;
assert(is_block_reachable(new_block)); assert(is_block_reachable(new_block));
......
...@@ -530,7 +530,7 @@ static void infinite_loop_walker(ir_node *block, void *env) ...@@ -530,7 +530,7 @@ static void infinite_loop_walker(ir_node *block, void *env)
/* reachable block: mark all cf predecessors */ /* reachable block: mark all cf predecessors */
for (i = 0; i < arity; ++i) { for (i = 0; i < arity; ++i) {
ir_node *pred = get_Block_cfgpred_block(block, i); ir_node *pred = get_Block_cfgpred_block(block, i);
if (is_Bad(pred)) if (pred == NULL)
continue; continue;
set_Block_mark(pred, 1); set_Block_mark(pred, 1);
} }
...@@ -549,8 +549,7 @@ static void infinite_loop_walker(ir_node *block, void *env) ...@@ -549,8 +549,7 @@ static void infinite_loop_walker(ir_node *block, void *env)
/* passing information to the cf predecessors */ /* passing information to the cf predecessors */
for (i = 0; i < arity; ++i) { for (i = 0; i < arity; ++i) {
ir_node *pred = get_Block_cfgpred_block(block, i); ir_node *pred = get_Block_cfgpred_block(block, i);
if (pred == NULL)
if (is_Bad(pred))
continue; continue;
/* If our cf predecessor is in the same endless loop, /* If our cf predecessor is in the same endless loop,
......
...@@ -53,11 +53,7 @@ static ir_node *ssa_second_def_block; ...@@ -53,11 +53,7 @@ static ir_node *ssa_second_def_block;
static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
bool first) bool first)
{ {
/* In case of a bad input to a block we need to return the bad value */ assert(is_Block(block));
if (is_Bad(block)) {
ir_graph *irg = get_irn_irg(block);
return new_r_Bad(irg, mode);
}
/* the other defs can't be marked for cases where a user of the original /* the other defs can't be marked for cases where a user of the original
* value is in the same block as the alternative definition. * value is in the same block as the alternative definition.
...@@ -81,8 +77,13 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, ...@@ -81,8 +77,13 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
int n_cfgpreds = get_Block_n_cfgpreds(block); int n_cfgpreds = get_Block_n_cfgpreds(block);
if (n_cfgpreds == 1) { if (n_cfgpreds == 1) {
ir_node *pred_block = get_Block_cfgpred_block(block, 0); ir_node *pred_block = get_Block_cfgpred_block(block, 0);
ir_node *value = search_def_and_create_phis(pred_block, mode, ir_node *value;
false); if (pred_block == NULL) {
ir_graph *irg = get_irn_irg(block);
value = new_r_Bad(irg, mode);
} else {
value = search_def_and_create_phis(pred_block, mode, false);
}
set_irn_link(block, value); set_irn_link(block, value);
mark_irn_visited(block); mark_irn_visited(block);
return value; return value;
...@@ -101,8 +102,13 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode, ...@@ -101,8 +102,13 @@ static ir_node *search_def_and_create_phis(ir_node *block, ir_mode *mode,
/* set Phi predecessors */ /* set Phi predecessors */
for (int i = 0; i < n_cfgpreds; ++i) { for (int i = 0; i < n_cfgpreds; ++i) {
ir_node *pred_block = get_Block_cfgpred_block(block, i); ir_node *pred_block = get_Block_cfgpred_block(block, i);
ir_node *pred_val = search_def_and_create_phis(pred_block, mode, ir_node *pred_val;
false); if (pred_block == NULL) {
ir_graph *irg = get_irn_irg(block);
pred_val = new_r_Bad(irg, mode);
} else {
pred_val = search_def_and_create_phis(pred_block, mode, false);
}
set_irn_n(phi, i, pred_val); set_irn_n(phi, i, pred_val);
} }
...@@ -146,7 +152,12 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val, ...@@ -146,7 +152,12 @@ static void construct_ssa(ir_node *orig_block, ir_node *orig_val,
ir_node *newval; ir_node *newval;
if (is_Phi(user)) { if (is_Phi(user)) {
ir_node *pred_block = get_Block_cfgpred_block(user_block, j); ir_node *pred_block = get_Block_cfgpred_block(user_block, j);
newval = search_def_and_create_phis(pred_block, mode, true); if (pred_block == NULL) {
ir_graph *irg = get_irn_irg(user_block);
newval = new_r_Bad(irg, mode);
} else {
newval = search_def_and_create_phis(pred_block, mode, true);
}
} else { } else {
newval = search_def_and_create_phis(user_block, mode, true); newval = search_def_and_create_phis(user_block, mode, true);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment