The interesting case where we encounter a basic block head is when the
check of return_copy for BB_HEAD check succeeds with return_copy being a label;
then last_insn is a NOTE_INSN_BASIC_BLOCK, and we must not try to split
off a part of the basic block before that note.
That can be properly tested for by changing the !INSN_P (last_insn) check into a
NOTE_INSN_BASIC_BLOCK_P (last_insn) check.

last_insn == BB_HEAD (src_bb) can't actually be true, because we don't copy
return_copy to last_insn when we've bit BB_HEAD, so I removed that test.

bootstrapped / regtested on i686-pc-linux-gnu .



AFAICT, the second block split is useless, and could be replaced with
pre_exit = src_bb;
, and then the slack space allocated for post_entry / pre_exit blocks reduced
to two. However, I didn't want to tie a bugfix with a potentialy destabilizing cleanup - maybe there's some target port code (in the context of likely spilled classes?) that relies on the MODE_EXIT switch note only before, but in a block separate from the return value copy?
2013-07-29  Joern Rennecke  <joern.renne...@embecosm.com>

        PR rtl-optimization/58021
        * mode-switching.c (create_pre_exit): Always split of preceding
        insns if we are not at the basic block head.

Index: mode-switching.c
===================================================================
--- mode-switching.c    (revision 201313)
+++ mode-switching.c    (working copy)
@@ -420,7 +420,7 @@ create_pre_exit (int n_entities, int *en
                        || (GET_MODE_CLASS (GET_MODE (ret_reg)) != MODE_INT
                            && nregs != 1));
 
-           if (INSN_P (last_insn))
+           if (!NOTE_INSN_BASIC_BLOCK_P (last_insn))
              {
                before_return_copy
                  = emit_note_before (NOTE_INSN_DELETED, last_insn);
@@ -428,9 +428,8 @@ create_pre_exit (int n_entities, int *en
                   require a different mode than MODE_EXIT, so if we might
                   have such instructions, keep them in a separate block
                   from pre_exit.  */
-               if (last_insn != BB_HEAD (src_bb))
-                 src_bb = split_block (src_bb,
-                                       PREV_INSN (before_return_copy))->dest;
+               src_bb = split_block (src_bb,
+                                     PREV_INSN (before_return_copy))->dest;
              }
            else
              before_return_copy = last_insn;

Reply via email to