Commit 8b3057b3 by Jan Hubicka Committed by Jan Hubicka

ipa-split-2.c: New testcase.


	* gcc.dg/tree-ssa/ipa-split-2.c: New testcase.
	* ipa-split.c (consider_split): PHI in entry block is OK as long as all
	edges comming from header are equivalent.
	(visit_bb): Handle PHIs correctly.
	* tree-inline.c (copy_phis_for_bb): Be able to copy
	PHI from entry edge.
	(copy_cfg_body): Produce edge from entry BB before copying
	PHIs.

From-SVN: r161433
parent 6bfd4302
2010-06-26 Jan Hubicka <jh@suse.cz>
* ipa-split.c (consider_split): PHI in entry block is OK as long as all
edges comming from header are equivalent.
(visit_bb): Handle PHIs correctly.
* tree-inline.c (copy_phis_for_bb): Be able to copy
PHI from entry edge.
(copy_cfg_body): Produce edge from entry BB before copying
PHIs.
2010-06-26 Richard Guenther <rguenther@suse.de> 2010-06-26 Richard Guenther <rguenther@suse.de>
PR middle-end/44674 PR middle-end/44674
......
...@@ -171,17 +171,25 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, ...@@ -171,17 +171,25 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
unsigned int call_overhead; unsigned int call_overhead;
edge e; edge e;
edge_iterator ei; edge_iterator ei;
gimple_stmt_iterator bsi;
unsigned int i;
int incomming_freq = 0;
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
dump_split_point (dump_file, current); dump_split_point (dump_file, current);
FOR_EACH_EDGE (e, ei, current->entry_bb->preds)
if (!bitmap_bit_p (current->split_bbs, e->src->index))
incomming_freq += EDGE_FREQUENCY (e);
/* Do not split when we would end up calling function anyway. */ /* Do not split when we would end up calling function anyway. */
if (current->entry_bb->frequency if (incomming_freq
>= (ENTRY_BLOCK_PTR->frequency >= (ENTRY_BLOCK_PTR->frequency
* PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100)) * PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100))
{ {
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, fprintf (dump_file,
" Refused: split BB frequency is too large.\n"); " Refused: incomming frequency is too large.\n");
return; return;
} }
...@@ -193,15 +201,32 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, ...@@ -193,15 +201,32 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
return; return;
} }
/* FIXME: We can do better: if the split region start with a loop and there /* Verify that PHI args on entry are either virutal or all their operands
is only one entry point from outer wrold, we can update PHI. */ incomming from header are the same. */
if (!gsi_end_p (gsi_start_phis (current->entry_bb))) for (bsi = gsi_start_phis (current->entry_bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
gimple stmt = gsi_stmt (bsi);
tree val = NULL;
if (!is_gimple_reg (gimple_phi_result (stmt)))
continue;
for (i = 0; i < gimple_phi_num_args (stmt); i++)
{
edge e = gimple_phi_arg_edge (stmt, i);
if (!bitmap_bit_p (current->split_bbs, e->src->index))
{
tree edge_val = gimple_phi_arg_def (stmt, i);
if (val && edge_val != val)
{ {
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, fprintf (dump_file,
" Refused: entry BB has PHI\n"); " Refused: entry BB has PHI with multiple variants\n");
return; return;
} }
val = edge_val;
}
}
}
/* See what argument we will pass to the split function and compute /* See what argument we will pass to the split function and compute
...@@ -256,6 +281,7 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, ...@@ -256,6 +281,7 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
we can pass more than that. */ we can pass more than that. */
if (num_args != bitmap_count_bits (current->ssa_names_to_pass)) if (num_args != bitmap_count_bits (current->ssa_names_to_pass))
{ {
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, fprintf (dump_file,
" Refused: need to pass non-param values\n"); " Refused: need to pass non-param values\n");
...@@ -289,8 +315,6 @@ consider_split (struct split_point *current, bitmap non_ssa_vars, ...@@ -289,8 +315,6 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
} }
for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{ {
if (is_gimple_debug (gsi_stmt (bsi)))
continue;
if (walk_stmt_load_store_addr_ops if (walk_stmt_load_store_addr_ops
(gsi_stmt (bsi), non_ssa_vars, test_nonssa_use, (gsi_stmt (bsi), non_ssa_vars, test_nonssa_use,
test_nonssa_use, test_nonssa_use)) test_nonssa_use, test_nonssa_use))
...@@ -510,17 +534,20 @@ visit_bb (basic_block bb, basic_block return_bb, ...@@ -510,17 +534,20 @@ visit_bb (basic_block bb, basic_block return_bb,
for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi))
{ {
gimple stmt = gsi_stmt (bsi); gimple stmt = gsi_stmt (bsi);
tree op; unsigned int i;
ssa_op_iter iter;
if (is_gimple_debug (stmt)) if (is_gimple_debug (stmt))
continue; continue;
if (!is_gimple_reg (gimple_phi_result (stmt))) if (!is_gimple_reg (gimple_phi_result (stmt)))
continue; continue;
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF) bitmap_set_bit (set_ssa_names,
bitmap_set_bit (set_ssa_names, SSA_NAME_VERSION (op)); SSA_NAME_VERSION (gimple_phi_result (stmt)));
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE) for (i = 0; i < gimple_phi_num_args (stmt); i++)
{
tree op = gimple_phi_arg_def (stmt, i);
if (TREE_CODE (op) == SSA_NAME)
bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op)); bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op));
}
can_split &= !walk_stmt_load_store_addr_ops (stmt, non_ssa_vars, can_split &= !walk_stmt_load_store_addr_ops (stmt, non_ssa_vars,
mark_nonssa_use, mark_nonssa_use,
mark_nonssa_use, mark_nonssa_use,
......
2010-06-26 Jan Hubicka <jh@suse.cz>
* gcc.dg/tree-ssa/ipa-split-2.c: New testcase.
2010-06-26 Richard Guenther <rguenther@suse.de> 2010-06-26 Richard Guenther <rguenther@suse.de>
PR middle-end/44674 PR middle-end/44674
......
/* { dg-do compile } */
/* { dg-options "-O3 -fdump-tree-fnsplit" } */
int b;
int c;
int d;
split_me(int a)
{
int t = 0;
if (d>4)
return;
do
{
long_function (t);
long_function (t);
long_function (t);
long_function (t);
long_function (t);
long_function (t);
make_me_irregular:
long_function (t);
long_function (t);
long_function (t);
long_function (t);
long_function (t);
t=b;
}
while (t);
if (c)
goto make_me_irregular;
}
main()
{
split_me (1);
split_me (2);
split_me (3);
split_me (4);
split_me (5);
}
/* { dg-final { scan-tree-dump-times "Splitting function" 1 "fnsplit"} } */
/* { dg-final { cleanup-tree-dump "fnsplit" } } */
...@@ -1969,11 +1969,22 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id) ...@@ -1969,11 +1969,22 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
= new_phi = create_phi_node (new_res, new_bb); = new_phi = create_phi_node (new_res, new_bb);
FOR_EACH_EDGE (new_edge, ei, new_bb->preds) FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
{ {
edge const old_edge edge old_edge = find_edge ((basic_block) new_edge->src->aux, bb);
= find_edge ((basic_block) new_edge->src->aux, bb); tree arg;
tree arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge); tree new_arg;
tree new_arg = arg;
tree block = id->block; tree block = id->block;
edge_iterator ei2;
/* When doing partial clonning, we allow PHIs on the entry block
as long as all the arguments are the same. Find any input
edge to see argument to copy. */
if (!old_edge)
FOR_EACH_EDGE (old_edge, ei2, bb->preds)
if (!old_edge->src->aux)
break;
arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
new_arg = arg;
id->block = NULL_TREE; id->block = NULL_TREE;
walk_tree (&new_arg, copy_tree_body_r, id, NULL); walk_tree (&new_arg, copy_tree_body_r, id, NULL);
id->block = block; id->block = block;
...@@ -2191,12 +2202,6 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, ...@@ -2191,12 +2202,6 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
|| (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index))) || (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index)))
need_debug_cleanup |= 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)
if (!blocks_to_copy
|| (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index)))
copy_phis_for_bb (bb, id);
if (new_entry) if (new_entry)
{ {
edge e; edge e;
...@@ -2205,6 +2210,12 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale, ...@@ -2205,6 +2210,12 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
e->count = entry_block_map->count; e->count = entry_block_map->count;
} }
if (gimple_in_ssa_p (cfun))
FOR_ALL_BB_FN (bb, cfun_to_copy)
if (!blocks_to_copy
|| (bb->index > 0 && bitmap_bit_p (blocks_to_copy, bb->index)))
copy_phis_for_bb (bb, id);
FOR_ALL_BB_FN (bb, cfun_to_copy) FOR_ALL_BB_FN (bb, cfun_to_copy)
if (bb->aux) if (bb->aux)
{ {
......
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