From: Michael Beck Date: Wed, 10 Dec 2008 19:59:57 +0000 (+0000) Subject: - changed handling of block walks: we might reach a block through a kept node only ... X-Git-Url: http://nsz.repo.hu/git/?a=commitdiff_plain;h=3e1337f622b15ca6edf9d40e588444bee3418ccd;p=libfirm - changed handling of block walks: we might reach a block through a kept node only ... - this should fix the gigo_return problem [r24502] --- diff --git a/ir/ana/irdom.c b/ir/ana/irdom.c index 829f36cee..d9a4dc72b 100644 --- a/ir/ana/irdom.c +++ b/ir/ana/irdom.c @@ -632,18 +632,19 @@ static int init_construction(ir_graph *irg, irg_walk_func *pre) { for (i = j = 0; i < arity; i++) { ir_node *pred = get_End_keepalive(end, i); - if (is_Block(pred)) { - if (Block_block_visited(pred)) + if (!is_Block(pred)) { + pred = get_nodes_block(pred); + if (!is_Block(pred)) { + /* a node which has a bad block input: kill it */ continue; - - /* we found an endless loop */ - dec_irg_block_visited(irg); - irg_block_walk(pred, pre, NULL, &n_blocks); + } } + dec_irg_block_visited(irg); + irg_block_walk(pred, pre, NULL, &n_blocks); in[j++] = pred; } if (j != arity) { - /* we kill some Block keep-alives */ + /* we kill some keep-alives */ set_End_keepalives(end, j, in); set_irg_outs_inconsistent(irg); } diff --git a/ir/ir/irgwalk.c b/ir/ir/irgwalk.c index 78daadee3..732ae4e6e 100644 --- a/ir/ir/irgwalk.c +++ b/ir/ir/irgwalk.c @@ -574,13 +574,13 @@ static void irg_block_walk_2(ir_node *node, irg_walk_func *pre, irg_walk_func *p if (!Block_block_visited(node)) { mark_Block_block_visited(node); - if(pre) pre(node, env); + if (pre) pre(node, env); for(i = get_Block_n_cfgpreds(node) - 1; i >= 0; --i) { /* find the corresponding predecessor block. */ ir_node *pred = get_cf_op(get_Block_cfgpred(node, i)); pred = get_nodes_block(pred); - if(get_irn_opcode(pred) == iro_Block) { + if (get_irn_opcode(pred) == iro_Block) { /* recursion */ irg_block_walk_2(pred, pre, post, env); } @@ -589,7 +589,7 @@ static void irg_block_walk_2(ir_node *node, irg_walk_func *pre, irg_walk_func *p } } - if(post) post(node, env); + if (post) post(node, env); } } @@ -606,7 +606,7 @@ void irg_block_walk(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void assert(node); assert(!get_interprocedural_view()); /* interprocedural_view not implemented, because it - * interleaves with irg_walk */ + * interleaves with irg_walk */ ir_reserve_resources(irg, IR_RESOURCE_BLOCK_VISITED); inc_irg_block_visited(irg); block = is_Block(node) ? node : get_nodes_block(node); @@ -618,19 +618,16 @@ void irg_block_walk(ir_node *node, irg_walk_func *pre, irg_walk_func *post, void int arity = get_irn_arity(node); for (i = 0; i < arity; i++) { pred = get_irn_n(node, i); - if (is_Block(pred)) - irg_block_walk_2(pred, pre, post, env); - } - /* Sometimes the blocks died, but are still reachable through Phis. - * Make sure the algorithms that try to remove these reach them. */ - for (i = 0; i < arity; i++) { - pred = get_irn_n(node, i); - if (get_irn_op(pred) == op_Phi) { - ir_node *block = get_nodes_block(pred); - - if (! is_Bad(block)) - irg_block_walk_2(block, pre, post, env); + if (!is_Block(pred)) { + pred = get_nodes_block(pred); + if (!is_Block(pred)) { + /* if rare cases a kept node might have a bad block input */ + continue; + } } + /* Sometimes the blocks died, but are still reachable through kept nodes. + * Make sure the algorithms that try to remove these reach them. */ + irg_block_walk_2(pred, pre, post, env); } }