X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fopt%2Fcfopt.c;h=8c78879529062205bf80c15d76cc9748b8931990;hb=f274dcf35aa0d3f4748387dbddfe50e8d7d44951;hp=1b2f156cfa8539157eb0513cfa0e11c66e9ac046;hpb=77402d90eda5171ba1377a3fb79cfcc161bc9d25;p=libfirm diff --git a/ir/opt/cfopt.c b/ir/opt/cfopt.c index 1b2f156cf..8c7887952 100644 --- a/ir/opt/cfopt.c +++ b/ir/opt/cfopt.c @@ -13,6 +13,13 @@ # include "config.h" #endif +#ifdef HAVE_MALLOC_H +# include +#endif +#ifdef HAVE_ALLOCA_H +# include +#endif + #include #include "xmalloc.h" @@ -600,7 +607,7 @@ static void optimize_blocks(ir_node *b, void *env) { * we will lose blocks and thereby generate memory leaks. */ void optimize_cf(ir_graph *irg) { - int i, n; + int i, j, n; ir_node **in; ir_node *end = get_irg_end(irg); ir_graph *rem = current_ir_graph; @@ -613,8 +620,9 @@ void optimize_cf(ir_graph *irg) { /* Handle graph state */ 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); + set_irg_outs_inconsistent(current_ir_graph); + set_irg_extblk_inconsistent(current_ir_graph); + set_irg_loopinfo_inconsistent(current_ir_graph); set_irg_doms_inconsistent(current_ir_graph); if (dom_state == dom_consistent && get_opt_optimize() && get_opt_unreachable_code()) { @@ -628,10 +636,13 @@ 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()); } } @@ -646,34 +657,37 @@ void optimize_cf(ir_graph *irg) { /* Walk all keep alives, optimize them if block, add to new in-array for end if useful. */ - in = NEW_ARR_F (ir_node *, 1); - in[0] = get_nodes_block(end); + n = get_End_n_keepalives(end); + if (n > 0) + NEW_ARR_A (ir_node *, in, n); inc_irg_visited(current_ir_graph); - for (i = 0, n = get_End_n_keepalives(end); i < n; i++) { + /* fix the keep alive */ + for (i = j = 0; 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) { + in[j++] = ka; + } else if (op == op_Phi) { mark_irn_visited(ka); if (! is_Block_dead(get_nodes_block(ka))) - ARR_APP1 (ir_node *, in, ka); - } else if (get_irn_op(ka) == op_IJmp) { + in[j++] = ka; + } else if (is_op_keep(op)) { mark_irn_visited(ka); if (! is_Block_dead(get_nodes_block(ka))) - ARR_APP1 (ir_node *, in, ka); + in[j++] = ka; } } } - DEL_ARR_F(end->in); /* GL @@@ tut nicht! MMB Warum? */ - end->in = in; - + if (j != n) + set_End_keepalives(end, j, in); /* the verifier doesn't work yet with floating nodes */ if (get_irg_pinned(irg) == op_pin_state_pinned) {