X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fcfopt.c;h=6043c3715abbb1325600058a0792b3694b64fd24;hb=529678cf846e774807b0e3e1b58de1e76019789c;hp=1303baddd8d1b3a182c629edc3bd9520c6fe398e;hpb=d05be8acf683be63c90cc49f37d2677491e29fdc;p=libfirm diff --git a/ir/opt/cfopt.c b/ir/opt/cfopt.c index 1303baddd..6043c3715 100644 --- a/ir/opt/cfopt.c +++ b/ir/opt/cfopt.c @@ -240,11 +240,10 @@ static int is_pred_of(ir_node *pred, ir_node *b) { **/ static int test_whether_dispensable(ir_node *b, int pos) { int i, j, n_preds = 1; - ir_node *cfop = get_Block_cfgpred(b, pos); - ir_node *pred = get_nodes_block(cfop); + ir_node *pred = get_Block_cfgpred_block(b, pos); /* Bad blocks will be optimized away, so we don't need space for them */ - if (is_Bad(pred)) + if (is_Block_dead(pred)) return 0; if (get_Block_block_visited(pred) + 1 @@ -265,7 +264,8 @@ static int test_whether_dispensable(ir_node *b, int pos) { Handle all pred blocks with preds < pos as if they were already removed. */ for (i = 0; i < pos; i++) { ir_node *b_pred = get_Block_cfgpred_block(b, i); - if (get_Block_block_visited(b_pred) + 1 + if (! is_Block_dead(b_pred) && + get_Block_block_visited(b_pred) + 1 < get_irg_block_visited(current_ir_graph)) { for (j = 0; j < get_Block_n_cfgpreds(b_pred); j++) { ir_node *b_pred_pred = get_Block_cfgpred_block(b_pred, j); @@ -615,8 +615,7 @@ void optimize_cf(ir_graph *irg) { assert(get_irg_phase_state(irg) != phase_building); if (get_irg_outs_state(current_ir_graph) == outs_consistent) set_irg_outs_inconsistent(current_ir_graph); - if (get_irg_dom_state(current_ir_graph) == dom_consistent) - set_irg_dom_inconsistent(current_ir_graph); + set_irg_doms_inconsistent(current_ir_graph); if (dom_state == dom_consistent && get_opt_optimize() && get_opt_unreachable_code()) { ir_node *end = get_irg_end(irg); @@ -629,14 +628,16 @@ void optimize_cf(ir_graph *irg) { ir_node *ka = get_End_keepalive(end, i); if (is_Block(ka)) { + /* do NOT keep dead blocks */ if (get_Block_dom_depth(ka) == -1) set_End_keepalive(end, i, new_Bad()); } - else if (is_Block_dead(get_nodes_block(ka)) || get_Block_dom_depth(get_nodes_block(ka)) == -1) + else if (is_Block_dead(get_nodes_block(ka)) || + get_Block_dom_depth(get_nodes_block(ka)) == -1) + /* do NOT keep nodes in dead blocks */ set_End_keepalive(end, i, new_Bad()); } } - irg_block_walk_graph(current_ir_graph, NULL, remove_senseless_conds, NULL); /* Use block visited flag to mark non-empty blocks. */ @@ -652,29 +653,33 @@ void optimize_cf(ir_graph *irg) { in[0] = get_nodes_block(end); inc_irg_visited(current_ir_graph); - for (i = 0; i < get_End_n_keepalives(end); i++) { + /* fix the keep alive */ + for (i = 0, n = get_End_n_keepalives(end); i < n; i++) { ir_node *ka = get_End_keepalive(end, i); if (irn_not_visited(ka)) { - if ((get_irn_op(ka) == op_Block) && Block_not_block_visited(ka)) { + ir_op *op = get_irn_op(ka); + + if ((op == op_Block) && Block_not_block_visited(ka)) { set_irg_block_visited(current_ir_graph, /* Don't walk all the way to Start. */ get_irg_block_visited(current_ir_graph)-1); irg_block_walk(ka, optimize_blocks, NULL, NULL); mark_irn_visited(ka); ARR_APP1 (ir_node *, in, ka); - } else if (get_irn_op(ka) == op_Phi) { + } else if (op == op_Phi) { mark_irn_visited(ka); - ARR_APP1 (ir_node *, in, ka); - } else if (get_irn_op(ka) == op_IJmp) { + if (! is_Block_dead(get_nodes_block(ka))) + ARR_APP1 (ir_node *, in, ka); + } else if (is_op_keep(op)) { mark_irn_visited(ka); - ARR_APP1 (ir_node *, in, ka); + if (! is_Block_dead(get_nodes_block(ka))) + ARR_APP1 (ir_node *, in, ka); } } } - /* DEL_ARR_F(end->in); GL @@@ tut nicht ! */ + DEL_ARR_F(end->in); end->in = in; - /* the verifier doesn't work yet with floating nodes */ if (get_irg_pinned(irg) == op_pin_state_pinned) { /* after optimize_cf(), only Bad data flow may remain. */