aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAlexandre Oliva <aoliva@redhat.com>2012-11-04 18:44:13 +0000
committerAlexandre Oliva <aoliva@gcc.gnu.org>2012-11-04 18:44:13 +0000
commit447a704564e850ccba796bb688b5bc83fd3ee892 (patch)
tree9b2764e159a783f231719c21b79e4b32df016978 /gcc
parent48e3b832bd1f56a8a3b10df5aada6eec28ca14c1 (diff)
downloadgcc-447a704564e850ccba796bb688b5bc83fd3ee892.zip
gcc-447a704564e850ccba796bb688b5bc83fd3ee892.tar.gz
gcc-447a704564e850ccba796bb688b5bc83fd3ee892.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/tree-ssa-threadedge.c106
2 files changed, 95 insertions, 19 deletions
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 <aoliva@redhat.com>
+
+ 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 <dehao@google.com>
* 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);
+ }
}
}