X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;f=ir%2Fir%2Frm_bads.c;h=831a646c9dc753692d5bf9e6e3a084d23cd7156b;hb=2f8553d98a05815a9d24eb5746cab1e17858a2a0;hp=bc948fa35e4a6470730f18849914cb171df1a7ce;hpb=6c1b0479bfe94f209b6fe8d8161ea36d17bdef24;p=libfirm diff --git a/ir/ir/rm_bads.c b/ir/ir/rm_bads.c index bc948fa35..831a646c9 100644 --- a/ir/ir/rm_bads.c +++ b/ir/ir/rm_bads.c @@ -38,7 +38,7 @@ */ static int count_non_bads(ir_node *node) { - int arity = get_irn_arity(node); + int arity = get_Block_n_cfgpreds(node); int count = 0; int i; for (i = 0; i < arity; ++i) { @@ -52,28 +52,23 @@ static int count_non_bads(ir_node *node) * Block-walker, remove Bad block predecessors and shorten Phis. * Phi links must be uptodate. */ -static void block_remove_bads(ir_node *block, void *env) +static void block_remove_bads(ir_node *block) { - int *changed = (int *)env; - int i, j; - ir_node **new_in, *new_block, *phi; - ir_node *next; + ir_graph *irg = get_irn_irg(block); + const int max = get_Block_n_cfgpreds(block); + const int new_max = count_non_bads(block); + ir_node **new_in = ALLOCAN(ir_node*, new_max); + int i; + int j; + ir_node *new_block; + ir_node *phi; + ir_node *next; ir_entity *block_entity; - const int max = get_irn_arity(block); - const int new_max = count_non_bads(block); assert(max >= new_max); - if (is_Bad(block) || max == new_max) - return; - - new_in = ALLOCAN(ir_node*, new_max); - *changed = 1; - - assert(get_Block_dom_depth(block) >= 0); - /* 1. Create a new block without Bad inputs */ for (i = j = 0; i < max; ++i) { - ir_node *block_pred = get_irn_n(block, i); + ir_node *const block_pred = get_Block_cfgpred(block, i); if (!is_Bad(block_pred)) { new_in[j++] = block_pred; } @@ -82,14 +77,14 @@ static void block_remove_bads(ir_node *block, void *env) /* If the end block is unreachable, it might have zero predecessors. */ if (new_max == 0) { - ir_node *end_block = get_irg_end_block(get_irn_irg(block)); + ir_node *end_block = get_irg_end_block(irg); if (block == end_block) { set_irn_in(block, new_max, new_in); return; } } - new_block = new_r_Block(get_irn_irg(block), new_max, new_in); + new_block = new_r_Block(irg, new_max, new_in); block_entity = get_Block_entity(block); if (block_entity) set_Block_entity(new_block, block_entity); @@ -102,8 +97,7 @@ static void block_remove_bads(ir_node *block, void *env) assert(get_irn_arity(phi) == max); for (i = j = 0; i < max; ++i) { - ir_node *block_pred = get_irn_n(block, i); - + ir_node *const block_pred = get_Block_cfgpred(block, i); if (!is_Bad(block_pred)) { ir_node *pred = get_irn_n(phi, i); new_in[j++] = pred; @@ -118,26 +112,38 @@ static void block_remove_bads(ir_node *block, void *env) exchange(block, new_block); } -/* Remove Bad nodes from Phi and Block inputs. - * - * This does NOT remove unreachable code. - * - * Postcondition: No Bad nodes. - */ -int remove_bads(ir_graph *irg) +static void collect(ir_node *node, void *env) { - int changed = 0; + firm_collect_block_phis(node, NULL); + if (is_Block(node)) { + ir_node ***blocks_to_process = (ir_node***)env; + int arity = get_Block_n_cfgpreds(node); + int non_bads = count_non_bads(node); + if (arity != non_bads) + ARR_APP1(ir_node*, *blocks_to_process, node); + } +} + +void remove_bads(ir_graph *irg) +{ + size_t i; + size_t n_to_process; + ir_node **blocks_to_process = NEW_ARR_F(ir_node*, 0); + /* build phi list per block */ - irg_walk_graph(irg, firm_clear_block_phis, firm_collect_block_phis, NULL); + irg_walk_graph(irg, firm_clear_block_phis, collect, &blocks_to_process); - /* actually remove Bads */ - irg_block_walk_graph(irg, NULL, block_remove_bads, (void *)&changed); + n_to_process = ARR_LEN(blocks_to_process); + for (i = 0; i < n_to_process; ++i) { + ir_node *block = blocks_to_process[i]; + block_remove_bads(block); + } + DEL_ARR_F(blocks_to_process); - if (changed) { + if (n_to_process > 0) { edges_deactivate(irg); - clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_OUTS); - clear_irg_state(irg, IR_GRAPH_STATE_CONSISTENT_DOMINANCE); + clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUTS); + clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_DOMINANCE); } - - return changed; + add_irg_properties(irg, IR_GRAPH_PROPERTY_NO_BADS); }