re PR rtl-optimization/84058 (RTl partitioning fixup should drag very small blocks...
authorJan Hubicka <jh@suse.cz>
Mon, 9 Apr 2018 16:33:51 +0000 (18:33 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 9 Apr 2018 16:33:51 +0000 (16:33 +0000)
PR rtl/84058
* cfgcleanup.c (try_forward_edges): Do not give up on crossing
jumps; choose last target that matches the criteria (i.e.
no partition changes for non-crossing jumps).
* cfgrtl.c (cfg_layout_redirect_edge_and_branch): Add basic
support for redirecting crossing jumps to non-crossing.

From-SVN: r259244

gcc/ChangeLog
gcc/cfgcleanup.c
gcc/cfgrtl.c

index 102acd7..601a9ab 100644 (file)
@@ -1,3 +1,12 @@
+2018-04-09  Jan Hubicka  <jh@suse.cz>
+
+       PR rtl/84058
+       * cfgcleanup.c (try_forward_edges): Do not give up on crossing
+       jumps; choose last target that matches the criteria (i.e.
+       no partition changes for non-crossing jumps).
+       * cfgrtl.c (cfg_layout_redirect_edge_and_branch): Add basic
+       support for redirecting crossing jumps to non-crossing.
+
 2018-04-09  Alexey Brodkin  <abrodkin@synopsys.com>
 
        * config/arc/arc.c (arc_expand_prologue): Set stack usage info
index 4f72153..4a5dc29 100644 (file)
@@ -394,19 +394,6 @@ try_forward_edges (int mode, basic_block b)
   edge_iterator ei;
   edge e, *threaded_edges = NULL;
 
-  /* If we are partitioning hot/cold basic blocks, we don't want to
-     mess up unconditional or indirect jumps that cross between hot
-     and cold sections.
-
-     Basic block partitioning may result in some jumps that appear to
-     be optimizable (or blocks that appear to be mergeable), but which really
-     must be left untouched (they are required to make it safely across
-     partition boundaries).  See the comments at the top of
-     bb-reorder.c:partition_hot_cold_basic_blocks for complete details.  */
-
-  if (JUMP_P (BB_END (b)) && CROSSING_JUMP_P (BB_END (b)))
-    return false;
-
   for (ei = ei_start (b->succs); (e = ei_safe_edge (ei)); )
     {
       basic_block target, first;
@@ -415,6 +402,7 @@ try_forward_edges (int mode, basic_block b)
       bool threaded = false;
       int nthreaded_edges = 0;
       bool may_thread = first_pass || (b->flags & BB_MODIFIED) != 0;
+      bool new_target_threaded = false;
 
       /* Skip complex edges because we don't know how to update them.
 
@@ -431,29 +419,12 @@ try_forward_edges (int mode, basic_block b)
       counter = NUM_FIXED_BLOCKS;
       goto_locus = e->goto_locus;
 
-      /* If we are partitioning hot/cold basic_blocks, we don't want to mess
-        up jumps that cross between hot/cold sections.
-
-        Basic block partitioning may result in some jumps that appear
-        to be optimizable (or blocks that appear to be mergeable), but which
-        really must be left untouched (they are required to make it safely
-        across partition boundaries).  See the comments at the top of
-        bb-reorder.c:partition_hot_cold_basic_blocks for complete
-        details.  */
-
-      if (first != EXIT_BLOCK_PTR_FOR_FN (cfun)
-         && JUMP_P (BB_END (first))
-         && CROSSING_JUMP_P (BB_END (first)))
-       return changed;
-
       while (counter < n_basic_blocks_for_fn (cfun))
        {
          basic_block new_target = NULL;
-         bool new_target_threaded = false;
          may_thread |= (target->flags & BB_MODIFIED) != 0;
 
          if (FORWARDER_BLOCK_P (target)
-             && !(single_succ_edge (target)->flags & EDGE_CROSSING)
              && single_succ (target) != EXIT_BLOCK_PTR_FOR_FN (cfun))
            {
              /* Bypass trivial infinite loops.  */
@@ -543,8 +514,14 @@ try_forward_edges (int mode, basic_block b)
            break;
 
          counter++;
-         target = new_target;
-         threaded |= new_target_threaded;
+         /* Do not turn non-crossing jump to crossing.  Depending on target
+            it may require different instruction pattern.  */
+         if ((e->flags & EDGE_CROSSING)
+             || BB_PARTITION (first) == BB_PARTITION (new_target))
+           {
+             target = new_target;
+             threaded |= new_target_threaded;
+           }
        }
 
       if (counter >= n_basic_blocks_for_fn (cfun))
index fd095ac..de704ce 100644 (file)
@@ -4361,6 +4361,18 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
   if (e->dest == dest)
     return e;
 
+  if (e->flags & EDGE_CROSSING
+      && BB_PARTITION (e->src) == BB_PARTITION (dest)
+      && simplejump_p (BB_END (src)))
+    {
+      if (dump_file)
+       fprintf (dump_file,
+                "Removing crossing jump while redirecting edge form %i to %i\n",
+                e->src->index, dest->index);
+      delete_insn (BB_END (src));
+      e->flags |= EDGE_FALLTHRU;
+    }
+
   if (e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun)
       && (ret = try_redirect_by_replacing_jump (e, dest, true)))
     {
@@ -4424,8 +4436,9 @@ cfg_layout_redirect_edge_and_branch (edge e, basic_block dest)
   else
     ret = redirect_branch_edge (e, dest);
 
+  fixup_partition_crossing (ret);
   /* We don't want simplejumps in the insn stream during cfglayout.  */
-  gcc_assert (!simplejump_p (BB_END (src)));
+  gcc_assert (!simplejump_p (BB_END (src)) || CROSSING_JUMP_P (BB_END (src)));
 
   df_set_bb_dirty (src);
   return ret;