From d50c81778642f0a14a3eec1a1a5d96d11f7ade77 Mon Sep 17 00:00:00 2001 From: =?utf8?q?G=C3=B6tz=20Lindenmaier?= Date: Thu, 17 Jun 2004 14:02:04 +0000 Subject: [PATCH] various bugfixes for the unreachable loop problem [r3139] --- ir/ana/irscc.c | 17 +++++++++++++++-- ir/debug/dbginfo.h | 1 + ir/ir/irgopt.c | 4 +++- ir/ir/irgraph.c | 9 ++++++++- ir/ir/irgraph.h | 2 ++ ir/ir/iropt.c | 7 +++++-- ir/ir/iropt_dbg.h | 14 ++++++++++++++ 7 files changed, 48 insertions(+), 6 deletions(-) diff --git a/ir/ana/irscc.c b/ir/ana/irscc.c index 1035bfc07..a1dca68b6 100644 --- a/ir/ana/irscc.c +++ b/ir/ana/irscc.c @@ -1242,6 +1242,8 @@ static void reset_backedges(ir_node *n) { } } + +/* static void loop_reset_backedges(ir_loop *l) { int i; reset_backedges(get_loop_node(l, 0)); @@ -1251,12 +1253,23 @@ static void loop_reset_backedges(ir_loop *l) { loop_reset_backedges(get_loop_son(l, i)); } } +*/ + +static void loop_reset_node(ir_node *n, void *env) { + set_irn_loop(n, NULL); + reset_backedges(n); +} + /** Removes all loop information. Resets all backedges */ void free_loop_information(ir_graph *irg) { - if (get_irg_loop(irg)) - loop_reset_backedges(get_irg_loop(irg)); + /* We can not use this recursion, as the loop might contain + illegal nodes by now. Why else would we throw away the + representation? + if (get_irg_loop(irg)) loop_reset_backedges(get_irg_loop(irg)); + */ + irg_walk_graph(irg, loop_reset_node, NULL, NULL); set_irg_loop(irg, NULL); set_irg_loopinfo_state(current_ir_graph, loopinfo_none); /* We cannot free the loop nodes, they are on the obstack. */ diff --git a/ir/debug/dbginfo.h b/ir/debug/dbginfo.h index a74920659..20eee75ba 100644 --- a/ir/debug/dbginfo.h +++ b/ir/debug/dbginfo.h @@ -111,6 +111,7 @@ typedef enum { dbg_write_after_read, /**< A Firm subgraph was replaced because of a write after read optimization. */ dbg_rem_poly_call, /**< Remove polymorphic call. */ + dbg_dead_code, /**< Removing unreachable code, I.e. blocks that are never executed. */ dbg_max /**< Maximum value. */ } dbg_action; diff --git a/ir/ir/irgopt.c b/ir/ir/irgopt.c index 528b59a15..e9cc720e3 100644 --- a/ir/ir/irgopt.c +++ b/ir/ir/irgopt.c @@ -95,6 +95,8 @@ local_optimize_graph (ir_graph *irg) { 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_loopinfo_inconsistent(current_ir_graph); + /* Clean the value_table in irg for the cse. */ del_identities(irg->value_table); @@ -1573,7 +1575,7 @@ void place_code(ir_graph *irg) { if (get_irg_dom_state(irg) != dom_consistent) compute_doms(irg); - if (get_irg_loopinfo_state(irg) != loopinfo_consistent) { + if (1 || get_irg_loopinfo_state(irg) != loopinfo_consistent) { free_loop_information(irg); construct_backedges(irg); } diff --git a/ir/ir/irgraph.c b/ir/ir/irgraph.c index 3003d3dcd..ac197ac55 100644 --- a/ir/ir/irgraph.c +++ b/ir/ir/irgraph.c @@ -561,8 +561,15 @@ void set_irg_loopinfo_inconsistent(ir_graph *irg) { if (irg->loopinfo_state == loopinfo_ip_consistent) irg->loopinfo_state = loopinfo_ip_inconsistent; - else + + else if (irg->loopinfo_state == loopinfo_consistent) irg->loopinfo_state = loopinfo_inconsistent; + + else if (irg->loopinfo_state == loopinfo_cf_ip_consistent) + irg->loopinfo_state = loopinfo_cf_ip_inconsistent; + + else if (irg->loopinfo_state == loopinfo_cf_consistent) + irg->loopinfo_state = loopinfo_cf_inconsistent; } INLINE void diff --git a/ir/ir/irgraph.h b/ir/ir/irgraph.h index 401ab6b69..4282b3bfe 100644 --- a/ir/ir/irgraph.h +++ b/ir/ir/irgraph.h @@ -267,6 +267,8 @@ typedef enum { } irg_loopinfo_state; irg_loopinfo_state get_irg_loopinfo_state(ir_graph *irg); void set_irg_loopinfo_state(ir_graph *irg, irg_loopinfo_state s); +/* Sets the loopinformation state to the appropriate inconsistent state. + If state is 'none' does not change. */ void set_irg_loopinfo_inconsistent(ir_graph *irg); diff --git a/ir/ir/iropt.c b/ir/ir/iropt.c index 6d862ab45..01ca74b45 100644 --- a/ir/ir/iropt.c +++ b/ir/ir/iropt.c @@ -498,9 +498,12 @@ static ir_node *equivalent_node_Block(ir_node *n) (get_irn_op(get_Block_cfgpred(n, 0)) == op_Jmp) && (get_opt_control_flow_straightening())) { n = get_nodes_Block(get_Block_cfgpred(n, 0)); - if (n == oldn) + if (n == oldn) { /* Jmp jumps into the block it is in -- deal self cycle. */ - n = new_Bad(); DBG_OPT_STG; + n = new_Bad(); + } else { + DBG_OPT_STG; + } } else if ((get_Block_n_cfgpreds(n) == 2) && (get_opt_control_flow_weak_simplification())) { diff --git a/ir/ir/iropt_dbg.h b/ir/ir/iropt_dbg.h index 07b40d7f5..cc2bf3fd4 100644 --- a/ir/ir/iropt_dbg.h +++ b/ir/ir/iropt_dbg.h @@ -16,6 +16,20 @@ #define SIZ(x) sizeof(x)/sizeof((x)[0]) + +/** + * Merge the debug info due to dead code elimination + */ +#define DBG_OPT_DEAD \ + do { \ + ir_node *ons[2]; \ + ons[0] = oldn; \ + ons[1] = get_Block_cfgpred(oldn, 0); \ + stat_merge_nodes(&n, 1, ons, SIZ(ons), STAT_OPT_STG); \ + __dbg_info_merge_sets(&n, 1, ons, SIZ(ons), dbg_dead_code); \ + } while(0) + + /** * Merge the debug info due to a straightening optimization */ -- 2.20.1