From: Alexandre Oliva Date: Sun, 4 Nov 2012 18:44:13 +0000 (+0000) Subject: re PR debug/54693 (VTA guality issues with loops) X-Git-Tag: upstream/12.2.0~73098 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=447a704564e850ccba796bb688b5bc83fd3ee892;p=platform%2Fupstream%2Fgcc.git re PR debug/54693 (VTA guality issues with loops) PR debug/54693 * tree-ssa-threadedge.c (propagate_threaded_block_debug_into): New, rewritten from debug stmt copying code... (thread_around_empty_block): ... removed from here. (thread_across_edge): Call propagate_threaded_block_debug_into. From-SVN: r193138 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 6725b56..ddffb1a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2012-11-04 Alexandre Oliva + + PR debug/54693 + * tree-ssa-threadedge.c (propagate_threaded_block_debug_into): + New, rewritten from debug stmt copying code... + (thread_around_empty_block): ... removed from here. + (thread_across_edge): Call propagate_threaded_block_debug_into. + 2012-11-04 Dehao Chen * expr.c (expand_expr_real_1): Change to not using input_location. diff --git a/gcc/tree-ssa-threadedge.c b/gcc/tree-ssa-threadedge.c index f43a564..a9c671e 100644 --- a/gcc/tree-ssa-threadedge.c +++ b/gcc/tree-ssa-threadedge.c @@ -610,6 +610,85 @@ cond_arg_set_in_bb (edge e, basic_block bb) return false; } +/* Copy debug stmts from DEST's chain of single predecessors up to + SRC, so that we don't lose the bindings as PHI nodes are introduced + when DEST gains new predecessors. */ +static void +propagate_threaded_block_debug_into (basic_block dest, basic_block src) +{ + if (!MAY_HAVE_DEBUG_STMTS) + return; + + if (!single_pred_p (dest)) + return; + + gcc_checking_assert (dest != src); + + gimple_stmt_iterator gsi = gsi_after_labels (dest); + pointer_set_t *vars = pointer_set_create (); + + for (gimple_stmt_iterator si = gsi; + !gsi_end_p (si); gsi_next (&si)) + { + gimple stmt = gsi_stmt (si); + if (!is_gimple_debug (stmt)) + break; + + tree var; + + if (gimple_debug_bind_p (stmt)) + var = gimple_debug_bind_get_var (stmt); + else if (gimple_debug_source_bind_p (stmt)) + var = gimple_debug_source_bind_get_var (stmt); + else + gcc_unreachable (); + + pointer_set_insert (vars, var); + } + + basic_block bb = dest; + + do + { + bb = single_pred (bb); + for (gimple_stmt_iterator si = gsi_last_bb (bb); + !gsi_end_p (si); gsi_prev (&si)) + { + gimple stmt = gsi_stmt (si); + if (!is_gimple_debug (stmt)) + continue; + + tree var; + + if (gimple_debug_bind_p (stmt)) + var = gimple_debug_bind_get_var (stmt); + else if (gimple_debug_source_bind_p (stmt)) + var = gimple_debug_source_bind_get_var (stmt); + else + gcc_unreachable (); + + /* Discard debug bind overlaps. ??? Unlike stmts from src, + copied into a new block that will precede BB, debug bind + stmts in bypassed BBs may actually be discarded if + they're overwritten by subsequent debug bind stmts, which + might be a problem once we introduce stmt frontier notes + or somesuch. Adding `&& bb == src' to the condition + below will preserve all potentially relevant debug + notes. */ + if (pointer_set_insert (vars, var)) + continue; + + stmt = gimple_copy (stmt); + /* ??? Should we drop the location of the copy to denote + they're artificial bindings? */ + gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); + } + } + while (bb != src && single_pred_p (bb)); + + pointer_set_destroy (vars); +} + /* TAKEN_EDGE represents the an edge taken as a result of jump threading. See if we can thread around TAKEN_EDGE->dest as well. If so, return the edge out of TAKEN_EDGE->dest that we can statically compute will be @@ -637,24 +716,6 @@ thread_around_empty_block (edge taken_edge, if (!single_pred_p (bb)) return NULL; - /* Before threading, copy DEBUG stmts from the predecessor, so that - we don't lose the bindings as we redirect the edges. */ - if (MAY_HAVE_DEBUG_STMTS) - { - gsi = gsi_after_labels (bb); - for (gimple_stmt_iterator si = gsi_last_bb (taken_edge->src); - !gsi_end_p (si); gsi_prev (&si)) - { - stmt = gsi_stmt (si); - if (!is_gimple_debug (stmt)) - continue; - - stmt = gimple_copy (stmt); - /* ??? Should we drop the location of the copy? */ - gsi_insert_before (&gsi, stmt, GSI_NEW_STMT); - } - } - /* This block must have more than one successor. */ if (single_succ_p (bb)) return NULL; @@ -827,6 +888,9 @@ thread_across_edge (gimple dummy_cond, } remove_temporary_equivalences (stack); + if (!taken_edge) + return; + propagate_threaded_block_debug_into (taken_edge->dest, e->dest); register_jump_thread (e, taken_edge, NULL); return; } @@ -892,7 +956,11 @@ thread_across_edge (gimple dummy_cond, same. */ tmp = find_edge (taken_edge->src, e3->dest); if (!tmp || phi_args_equal_on_edges (tmp, e3)) - register_jump_thread (e, taken_edge, e3); + { + propagate_threaded_block_debug_into (e3->dest, + taken_edge->dest); + register_jump_thread (e, taken_edge, e3); + } } }