aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2010-06-26 16:45:40 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2010-06-26 14:45:40 +0000
commit8b3057b30d78d0e30ec9f0db8806229bd8f28dfc (patch)
tree48fb4136d3d63a84f88676d81afbfd202920e87e /gcc
parent6bfd4302547d10962648eb1dddd4020cf8017ada (diff)
downloadgcc-8b3057b30d78d0e30ec9f0db8806229bd8f28dfc.zip
gcc-8b3057b30d78d0e30ec9f0db8806229bd8f28dfc.tar.gz
gcc-8b3057b30d78d0e30ec9f0db8806229bd8f28dfc.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/ipa-split.c61
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ipa-split-2.c41
-rw-r--r--gcc/tree-inline.c31
5 files changed, 120 insertions, 27 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 5a2bbac..e0c3122 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+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>
PR middle-end/44674
diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c
index 6085e0b..1216b0f 100644
--- a/gcc/ipa-split.c
+++ b/gcc/ipa-split.c
@@ -171,17 +171,25 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
unsigned int call_overhead;
edge e;
edge_iterator ei;
+ gimple_stmt_iterator bsi;
+ unsigned int i;
+ int incomming_freq = 0;
+
if (dump_file && (dump_flags & TDF_DETAILS))
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. */
- if (current->entry_bb->frequency
+ if (incomming_freq
>= (ENTRY_BLOCK_PTR->frequency
* PARAM_VALUE (PARAM_PARTIAL_INLINING_ENTRY_PROBABILITY) / 100))
{
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
- " Refused: split BB frequency is too large.\n");
+ " Refused: incomming frequency is too large.\n");
return;
}
@@ -193,14 +201,31 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
return;
}
- /* FIXME: We can do better: if the split region start with a loop and there
- is only one entry point from outer wrold, we can update PHI. */
- if (!gsi_end_p (gsi_start_phis (current->entry_bb)))
+ /* Verify that PHI args on entry are either virutal or all their operands
+ incomming from header are the same. */
+ for (bsi = gsi_start_phis (current->entry_bb); !gsi_end_p (bsi); gsi_next (&bsi))
{
- if (dump_file && (dump_flags & TDF_DETAILS))
- fprintf (dump_file,
- " Refused: entry BB has PHI\n");
- return;
+ 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))
+ fprintf (dump_file,
+ " Refused: entry BB has PHI with multiple variants\n");
+ return;
+ }
+ val = edge_val;
+ }
+ }
}
@@ -256,6 +281,7 @@ consider_split (struct split_point *current, bitmap non_ssa_vars,
we can pass more than that. */
if (num_args != bitmap_count_bits (current->ssa_names_to_pass))
{
+
if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file,
" Refused: need to pass non-param values\n");
@@ -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))
{
- if (is_gimple_debug (gsi_stmt (bsi)))
- continue;
if (walk_stmt_load_store_addr_ops
(gsi_stmt (bsi), non_ssa_vars, test_nonssa_use,
test_nonssa_use, test_nonssa_use))
@@ -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))
{
gimple stmt = gsi_stmt (bsi);
- tree op;
- ssa_op_iter iter;
+ unsigned int i;
if (is_gimple_debug (stmt))
continue;
if (!is_gimple_reg (gimple_phi_result (stmt)))
continue;
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
- bitmap_set_bit (set_ssa_names, SSA_NAME_VERSION (op));
- FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_USE)
- bitmap_set_bit (used_ssa_names, SSA_NAME_VERSION (op));
+ bitmap_set_bit (set_ssa_names,
+ SSA_NAME_VERSION (gimple_phi_result (stmt)));
+ 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));
+ }
can_split &= !walk_stmt_load_store_addr_ops (stmt, non_ssa_vars,
mark_nonssa_use,
mark_nonssa_use,
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index ae6ce36..26d6cbc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+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>
PR middle-end/44674
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-2.c
new file mode 100644
index 0000000..bbde73d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ipa-split-2.c
@@ -0,0 +1,41 @@
+/* { 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" } } */
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index f446fa7..a419c26 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -1969,11 +1969,22 @@ copy_phis_for_bb (basic_block bb, copy_body_data *id)
= new_phi = create_phi_node (new_res, new_bb);
FOR_EACH_EDGE (new_edge, ei, new_bb->preds)
{
- edge const old_edge
- = find_edge ((basic_block) new_edge->src->aux, bb);
- tree arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
- tree new_arg = arg;
+ edge old_edge = find_edge ((basic_block) new_edge->src->aux, bb);
+ tree arg;
+ tree new_arg;
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;
walk_tree (&new_arg, copy_tree_body_r, id, NULL);
id->block = block;
@@ -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)))
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)
{
edge e;
@@ -2205,6 +2210,12 @@ copy_cfg_body (copy_body_data * id, gcov_type count, int frequency_scale,
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)
if (bb->aux)
{