From 149167f9a2f92e8f1ccc21caf2ec4592b9f6fb84 Mon Sep 17 00:00:00 2001 From: Michael Beck Date: Wed, 12 Oct 2005 14:20:51 +0000 Subject: [PATCH] added code to detect loops in unreachable code, these would cause endless loops else :-( [r6684] --- ir/ana/irextbb.c | 50 +++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) diff --git a/ir/ana/irextbb.c b/ir/ana/irextbb.c index 05f09d3d6..2d5ee83e4 100644 --- a/ir/ana/irextbb.c +++ b/ir/ana/irextbb.c @@ -70,17 +70,14 @@ static void pre_walk_calc_extbb(ir_node *block, void *ctx) if (n <= 0 || n > 1 || block == get_irg_start_block(current_ir_graph)) { /* - * block is a JOIN-node ie he control flow from + * block is a JOIN-node ie the control flow from * many other blocks joins here. block is a leader. * Note that we handle unreachable blocks (n <= 0) here too. */ allocate_extblk(block, env); } - else { - ir_node *add_to = get_Block_cfgpred(block, 0); - - if (! is_Bad(add_to)) - add_to = get_irn_n(add_to, -1); + else { /* we have only one control flow predecessor */ + ir_node *add_to = get_Block_cfgpred_block(block, 0); /* blocks with only one BAD predecessors are leaders too */ if (is_Bad(add_to)) { @@ -96,25 +93,52 @@ static void pre_walk_calc_extbb(ir_node *block, void *ctx) } } +static int _sentinel; + /** * Post block-walker. Calculates the extended block info. * During construction, we use the (free) block input of all basic blocks * to point to there previous block. */ -static void post_walk_calc_extbb(ir_node *block, void *env) +static void post_walk_calc_extbb(ir_node *block, void *ctx) { ir_extblk *extbb = get_Block_extbb(block); + env_t *env = ctx; + ir_extblk *sentinel = (ir_extblk *)&_sentinel; if (! extbb) { - ir_node *prev = block; + ir_node *curr, *prev; - /* search the leader */ - do { - prev = get_irn_n(get_Block_cfgpred(prev, 0), -1); + /* + * Search the leader. It can happen, that we fall into an endless + * loop, because we enter an unreachable loop that is not yet detected. + * We break the loop using a sentinel. + */ + for (curr = block; !extbb; curr = prev) { + prev = get_Block_cfgpred_block(curr, 0); extbb = get_Block_extbb(prev); - } while (! extbb); + set_Block_extbb(curr, sentinel); + } - addto_extblk(extbb, block); + if (extbb == sentinel) { + /* We detect a dead loop. We fix this by allocating an + * special Extended block + */ + ir_printf("Dead loop detected starting with %+F::%+F\n", get_irg_entity(current_ir_graph), block); + + allocate_extblk(block, env); + extbb = get_Block_extbb(block); + set_Block_extbb(block, sentinel); + } + + /* replace all sentinels by the extbb info */ + prev = block; + while (1) { + if (get_Block_extbb(prev) != sentinel) + break; + set_Block_extbb(prev, extbb); + prev = get_Block_cfgpred_block(prev, 0); + } } } -- 2.20.1