From 8b3057b30d78d0e30ec9f0db8806229bd8f28dfc Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Sat, 26 Jun 2010 16:45:40 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 10 ++++ gcc/ipa-split.c | 61 +++++++++++++++------ gcc/testsuite/ChangeLog | 4 ++ gcc/testsuite/gcc.dg/tree-ssa/ipa-split-2.c | 41 ++++++++++++++ gcc/tree-inline.c | 31 +++++++---- 5 files changed, 120 insertions(+), 27 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ipa-split-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5a2bbac92ef5..e0c312209cad 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2010-06-26 Jan Hubicka + + * 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 PR middle-end/44674 diff --git a/gcc/ipa-split.c b/gcc/ipa-split.c index 6085e0b677cf..1216b0f2c61e 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 ae6ce3614837..26d6cbc9a1cd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2010-06-26 Jan Hubicka + + * gcc.dg/tree-ssa/ipa-split-2.c: New testcase. + 2010-06-26 Richard Guenther 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 000000000000..bbde73d6c7c3 --- /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 f446fa7c55cb..a419c2612bfd 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) { -- 2.43.5