]> gcc.gnu.org Git - gcc.git/commitdiff
ipa-split-2.c: New testcase.
authorJan Hubicka <jh@suse.cz>
Sat, 26 Jun 2010 14:45:40 +0000 (16:45 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Sat, 26 Jun 2010 14:45:40 +0000 (14:45 +0000)
* 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
gcc/ipa-split.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ipa-split-2.c [new file with mode: 0644]
gcc/tree-inline.c

index 5a2bbac92ef58bc4ba722cc00fddfc4f6e3680c2..e0c312209cad2106a06565fd30f2029e13514647 100644 (file)
@@ -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
index 6085e0b677cf8021ae7df7e1577e9d887c2a99bf..1216b0f2c61e0199eb6019e4e4da6a5ddcd894f1 100644 (file)
@@ -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,
index ae6ce361483750a71420198cf99f83cf7622c500..26d6cbc9a1cd87918fde5c48972b432c1a7e0134 100644 (file)
@@ -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 (file)
index 0000000..bbde73d
--- /dev/null
@@ -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" } } */
index f446fa7c55cbc1e94bc261d7955decff3daee7f2..a419c2612bfd1370e99531df6de25f48b92ddd25 100644 (file)
@@ -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)
       {
This page took 0.087096 seconds and 5 git commands to generate.