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>
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>
* 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,
/* Copy edges from BB into its copy constructed earlier, scale profile
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)
{
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)
edge old_edge;
gimple_stmt_iterator si;
int flags;
bool need_debug_cleanup = false;
/* Use the indices from the original blocks to create edges for the
new ones. */
......@@ -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)
return;
return false;
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)
if (can_throw || nonlocal_goto)
{
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
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)
update_ssa_across_abnormal_edges (gimple_bb (copy_stmt), ret_bb,
can_throw, nonlocal_goto);
}
return need_debug_cleanup;
}
/* 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)
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
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,
struct function *cfun_to_copy;
basic_block bb;
tree new_fndecl = NULL;
bool need_debug_cleanup = false;
gcov_type count_scale;
int last;
......@@ -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. */
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))
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,
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;
bb->aux = NULL;
}
......@@ -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
insertion. */
for (; last < last_basic_block; last++)
BASIC_BLOCK (last)->aux = NULL;
{
if (need_debug_cleanup)
maybe_move_debug_stmts_to_successors (id, BASIC_BLOCK (last));
BASIC_BLOCK (last)->aux = NULL;
}
entry_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