Commit 90a7788b by Jakub Jelinek Committed by Jakub Jelinek

re PR tree-optimization/44182 (-fcompare-debug failure (length) with -O1)

	PR tree-optimization/44182
	* tree-inline.c (copy_edges_for_bb): Don't split bb if a stmt that
	newly needs to end a bb is followed by debug stmts, instead return
	true from the function at the end.
	(maybe_move_debug_stmts_to_successors): New function.
	(copy_cfg_body): Call it if copy_edges_for_bb returned true.

	* g++.dg/debug/pr44182.C: New test.

From-SVN: r160074
parent 1e2c0906
2010-05-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/44182
* tree-inline.c (copy_edges_for_bb): Don't split bb if a stmt that
newly needs to end a bb is followed by debug stmts, instead return
true from the function at the end.
(maybe_move_debug_stmts_to_successors): New function.
(copy_cfg_body): Call it if copy_edges_for_bb returned true.
2010-05-31 Kai Tietz <kai.tietz@onevision.com> 2010-05-31 Kai Tietz <kai.tietz@onevision.com>
PR target/44161 PR target/44161
......
2010-05-31 Jakub Jelinek <jakub@redhat.com>
PR tree-optimization/44182
* g++.dg/debug/pr44182.C: New test.
2010-05-31 Eric Botcazou <ebotcazou@adacore.com> 2010-05-31 Eric Botcazou <ebotcazou@adacore.com>
* gcc.dg/nested-func-7.c: New test. * gcc.dg/nested-func-7.c: New test.
......
// PR tree-optimization/44182
// { dg-do compile }
// { dg-options "-fcompare-debug" }
struct S
{
int i;
S ();
~S ();
void f1 ();
void f2 (S s)
{
f3 (s.i);
for (int j = 0; j < s.i; j++) f1 ();
}
void f3 (int j)
{
if (j > i) f1 ();
}
};
void
f (S *x)
{
x->f2 (S ());
}
...@@ -1834,9 +1834,10 @@ update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb, ...@@ -1834,9 +1834,10 @@ update_ssa_across_abnormal_edges (basic_block bb, basic_block ret_bb,
/* Copy edges from BB into its copy constructed earlier, scale profile /* Copy edges from BB into its copy constructed earlier, scale profile
accordingly. Edges will be taken care of later. Assume aux accordingly. Edges will be taken care of later. Assume aux
pointers to point to the copies of each BB. */ pointers to point to the copies of each BB. Return true if any
debug stmts are left after a statement that must end the basic block. */
static void static bool
copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb) copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
{ {
basic_block new_bb = (basic_block) bb->aux; basic_block new_bb = (basic_block) bb->aux;
...@@ -1844,6 +1845,7 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb) ...@@ -1844,6 +1845,7 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
edge old_edge; edge old_edge;
gimple_stmt_iterator si; gimple_stmt_iterator si;
int flags; int flags;
bool need_debug_cleanup = false;
/* Use the indices from the original blocks to create edges for the /* Use the indices from the original blocks to create edges for the
new ones. */ new ones. */
...@@ -1864,7 +1866,7 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb) ...@@ -1864,7 +1866,7 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
} }
if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK) if (bb->index == ENTRY_BLOCK || bb->index == EXIT_BLOCK)
return; return false;
for (si = gsi_start_bb (new_bb); !gsi_end_p (si);) for (si = gsi_start_bb (new_bb); !gsi_end_p (si);)
{ {
...@@ -1899,6 +1901,13 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb) ...@@ -1899,6 +1901,13 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
if (can_throw || nonlocal_goto) if (can_throw || nonlocal_goto)
{ {
if (!gsi_end_p (si)) if (!gsi_end_p (si))
{
while (!gsi_end_p (si) && is_gimple_debug (gsi_stmt (si)))
gsi_next (&si);
if (gsi_end_p (si))
need_debug_cleanup = true;
}
if (!gsi_end_p (si))
/* Note that bb's predecessor edges aren't necessarily /* Note that bb's predecessor edges aren't necessarily
right at this point; split_block doesn't care. */ right at this point; split_block doesn't care. */
{ {
...@@ -1923,6 +1932,7 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb) ...@@ -1923,6 +1932,7 @@ copy_edges_for_bb (basic_block bb, gcov_type count_scale, basic_block ret_bb)
update_ssa_across_abnormal_edges (gimple_bb (copy_stmt), ret_bb, update_ssa_across_abnormal_edges (gimple_bb (copy_stmt), ret_bb,
can_throw, nonlocal_goto); can_throw, nonlocal_goto);
} }
return need_debug_cleanup;
} }
/* Copy the PHIs. All blocks and edges are copied, some blocks /* Copy the PHIs. All blocks and edges are copied, some blocks
...@@ -2059,6 +2069,63 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count) ...@@ -2059,6 +2069,63 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count)
pop_cfun (); pop_cfun ();
} }
/* Helper function for copy_cfg_body. Move debug stmts from the end
of NEW_BB to the beginning of successor basic blocks when needed. If the
successor has multiple predecessors, reset them, otherwise keep
their value. */
static void
maybe_move_debug_stmts_to_successors (copy_body_data *id, basic_block new_bb)
{
edge e;
edge_iterator ei;
gimple_stmt_iterator si = gsi_last_nondebug_bb (new_bb);
if (gsi_end_p (si)
|| gsi_one_before_end_p (si)
|| !(stmt_can_throw_internal (gsi_stmt (si))
|| stmt_can_make_abnormal_goto (gsi_stmt (si))))
return;
FOR_EACH_EDGE (e, ei, new_bb->succs)
{
gimple_stmt_iterator ssi = gsi_last_bb (new_bb);
gimple_stmt_iterator dsi = gsi_after_labels (e->dest);
while (is_gimple_debug (gsi_stmt (ssi)))
{
gimple stmt = gsi_stmt (ssi), new_stmt;
tree var;
tree value;
/* For the last edge move the debug stmts instead of copying
them. */
if (ei_one_before_end_p (ei))
{
si = ssi;
gsi_prev (&ssi);
if (!single_pred_p (e->dest))
gimple_debug_bind_reset_value (stmt);
gsi_remove (&si, false);
gsi_insert_before (&dsi, stmt, GSI_SAME_STMT);
continue;
}
var = gimple_debug_bind_get_var (stmt);
if (single_pred_p (e->dest))
{
value = gimple_debug_bind_get_value (stmt);
value = unshare_expr (value);
}
else
value = NULL_TREE;
new_stmt = gimple_build_debug_bind (var, value, stmt);
gsi_insert_before (&dsi, new_stmt, GSI_SAME_STMT);
VEC_safe_push (gimple, heap, id->debug_stmts, new_stmt);
gsi_prev (&ssi);
}
}
}
/* Make a copy of the body of FN so that it can be inserted inline in /* Make a copy of the body of FN so that it can be inserted inline in
another function. Walks FN via CFG, returns new fndecl. */ another function. Walks FN via CFG, returns new fndecl. */
...@@ -2072,6 +2139,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, ...@@ -2072,6 +2139,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
struct function *cfun_to_copy; struct function *cfun_to_copy;
basic_block bb; basic_block bb;
tree new_fndecl = NULL; tree new_fndecl = NULL;
bool need_debug_cleanup = false;
gcov_type count_scale; gcov_type count_scale;
int last; int last;
...@@ -2112,7 +2180,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, ...@@ -2112,7 +2180,7 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
/* Now that we've duplicated the blocks, duplicate their edges. */ /* Now that we've duplicated the blocks, duplicate their edges. */
FOR_ALL_BB_FN (bb, cfun_to_copy) FOR_ALL_BB_FN (bb, cfun_to_copy)
copy_edges_for_bb (bb, count_scale, exit_block_map); need_debug_cleanup |= copy_edges_for_bb (bb, count_scale, exit_block_map);
if (gimple_in_ssa_p (cfun)) if (gimple_in_ssa_p (cfun))
FOR_ALL_BB_FN (bb, cfun_to_copy) FOR_ALL_BB_FN (bb, cfun_to_copy)
...@@ -2120,6 +2188,10 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, ...@@ -2120,6 +2188,10 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
FOR_ALL_BB_FN (bb, cfun_to_copy) FOR_ALL_BB_FN (bb, cfun_to_copy)
{ {
if (need_debug_cleanup
&& bb->index != ENTRY_BLOCK
&& bb->index != EXIT_BLOCK)
maybe_move_debug_stmts_to_successors (id, (basic_block) bb->aux);
((basic_block)bb->aux)->aux = NULL; ((basic_block)bb->aux)->aux = NULL;
bb->aux = NULL; bb->aux = NULL;
} }
...@@ -2127,7 +2199,11 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, ...@@ -2127,7 +2199,11 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
/* Zero out AUX fields of newly created block during EH edge /* Zero out AUX fields of newly created block during EH edge
insertion. */ insertion. */
for (; last < last_basic_block; last++) for (; last < last_basic_block; last++)
{
if (need_debug_cleanup)
maybe_move_debug_stmts_to_successors (id, BASIC_BLOCK (last));
BASIC_BLOCK (last)->aux = NULL; BASIC_BLOCK (last)->aux = NULL;
}
entry_block_map->aux = NULL; entry_block_map->aux = NULL;
exit_block_map->aux = NULL; exit_block_map->aux = NULL;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment