* cfglayout.c (fixup_reorder_chain): When ensuring that there is at
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 24 Oct 2010 07:45:26 +0000 (07:45 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 24 Oct 2010 07:45:26 +0000 (07:45 +0000)
least one insn with a locus corresponding to an edge's goto_locus,
disregard non-fallthru edges to the exit block and merge the blocks
created for the same goto_locus.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@165897 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cfglayout.c

index 809f3be..189f349 100644 (file)
@@ -1,3 +1,10 @@
+2010-10-24  Eric Botcazou  <ebotcazou@adacore.com>
+
+       * cfglayout.c (fixup_reorder_chain): When ensuring that there is at
+       least one insn with a locus corresponding to an edge's goto_locus,
+       disregard non-fallthru edges to the exit block and merge the blocks
+       created for the same goto_locus.
+
 2010-10-23  Joseph Myers  <joseph@codesourcery.com>
 
        * gcc.c (n_switches_alloc_debug_check): New.
index 8a0d35c..d599b36 100644 (file)
@@ -940,7 +940,9 @@ fixup_reorder_chain (void)
         FOR_EACH_EDGE (e, ei, bb->succs)
          if (e->goto_locus && !(e->flags & EDGE_ABNORMAL))
            {
-             basic_block nb;
+             edge e2;
+             edge_iterator ei2;
+             basic_block dest, nb;
              rtx end;
 
              insn = BB_END (e->src);
@@ -957,10 +959,17 @@ fixup_reorder_chain (void)
                  INSN_LOCATOR (BB_END (e->src)) = e->goto_locus;
                  continue;
                }
-             if (e->dest != EXIT_BLOCK_PTR)
+             dest = e->dest;
+             if (dest == EXIT_BLOCK_PTR)
                {
-                 insn = BB_HEAD (e->dest);
-                 end = NEXT_INSN (BB_END (e->dest));
+                 /* Non-fallthru edges to the exit block cannot be split.  */
+                 if (!(e->flags & EDGE_FALLTHRU))
+                   continue;
+               }
+             else
+               {
+                 insn = BB_HEAD (dest);
+                 end = NEXT_INSN (BB_END (dest));
                  while (insn != end && !NONDEBUG_INSN_P (insn))
                    insn = NEXT_INSN (insn);
                  if (insn != end && INSN_LOCATOR (insn)
@@ -972,6 +981,18 @@ fixup_reorder_chain (void)
                BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
                                                     nb);
              INSN_LOCATOR (BB_END (nb)) = e->goto_locus;
+
+             /* If there are other incoming edges to the destination block
+                with the same goto locus, redirect them to the new block as
+                well, this can prevent other such blocks from being created
+                in subsequent iterations of the loop.  */
+             for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
+               if (e2->goto_locus
+                   && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
+                   && locator_eq (e->goto_locus, e2->goto_locus))
+                 redirect_edge_and_branch (e2, nb);
+               else
+                 ei_next (&ei2);
            }
       }
 }