re PR rtl-optimization/60651 (Mode switching instructions are sometimes emitted in...
authorJoern Rennecke <joern.rennecke@embecosm.com>
Fri, 11 Apr 2014 18:12:53 +0000 (18:12 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Fri, 11 Apr 2014 18:12:53 +0000 (19:12 +0100)
gcc:
        PR rtl-optimization/60651
        * mode-switching.c (optimize_mode_switching): Make sure to emit
        sets of a lower numbered entity before sets of a higher numbered
        entity to a mode of the same or lower priority.
        When creating a seginfo for a basic block that starts with a code
        label, move the insertion point past the code label.
        (new_seginfo): Document and enforce requirement that
        NOTE_INSN_BASIC_BLOCK only appears for empty blocks.
        * doc/tm.texi.in: Document ordering constraint for emitted mode sets.
        * doc/tm.texi: Regenerate.
gcc/testsuite:
        PR rtl-optimization/60651
        * gcc.target/epiphany/mode-switch.c: New test.

From-SVN: r209312

gcc/ChangeLog
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/mode-switching.c
gcc/testsuite/ChangeLog

index 6d99d17..32ed05f 100644 (file)
@@ -1,3 +1,16 @@
+2014-04-11  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+       PR rtl-optimization/60651
+       * mode-switching.c (optimize_mode_switching): Make sure to emit
+       sets of a lower numbered entity before sets of a higher numbered
+       entity to a mode of the same or lower priority.
+       When creating a seginfo for a basic block that starts with a code
+       label, move the insertion point past the code label.
+       (new_seginfo): Document and enforce requirement that
+       NOTE_INSN_BASIC_BLOCK only appears for empty blocks.
+       * doc/tm.texi.in: Document ordering constraint for emitted mode sets.
+       * doc/tm.texi: Regenerate.
+
 2014-01-11  Joern Rennecke  <joern.rennecke@embecosm.com>
 
        PR target/60811
index f7024a7..b8ca17e 100644 (file)
@@ -9778,6 +9778,8 @@ for @var{entity}.  For any fixed @var{entity}, @code{mode_priority_to_mode}
 Generate one or more insns to set @var{entity} to @var{mode}.
 @var{hard_reg_live} is the set of hard registers live at the point where
 the insn(s) are to be inserted.
+Sets of a lower numbered entity will be emitted before sets of a higher
+numbered entity to a mode of the same or lower priority.
 @end defmac
 
 @node Target Attributes
index 6dcbde4..d793d26 100644 (file)
@@ -7447,6 +7447,8 @@ for @var{entity}.  For any fixed @var{entity}, @code{mode_priority_to_mode}
 Generate one or more insns to set @var{entity} to @var{mode}.
 @var{hard_reg_live} is the set of hard registers live at the point where
 the insn(s) are to be inserted.
+Sets of a lower numbered entity will be emitted before sets of a higher
+numbered entity to a mode of the same or lower priority.
 @end defmac
 
 @node Target Attributes
index 3166539..2848da3 100644 (file)
@@ -96,12 +96,18 @@ static void make_preds_opaque (basic_block, int);
 \f
 
 /* This function will allocate a new BBINFO structure, initialized
-   with the MODE, INSN, and basic block BB parameters.  */
+   with the MODE, INSN, and basic block BB parameters.
+   INSN may not be a NOTE_INSN_BASIC_BLOCK, unless it is an empty
+   basic block; that allows us later to insert instructions in a FIFO-like
+   manner.  */
 
 static struct seginfo *
 new_seginfo (int mode, rtx insn, int bb, HARD_REG_SET regs_live)
 {
   struct seginfo *ptr;
+
+  gcc_assert (!NOTE_INSN_BASIC_BLOCK_P (insn)
+             || insn == BB_END (NOTE_BASIC_BLOCK (insn)));
   ptr = XNEW (struct seginfo);
   ptr->mode = mode;
   ptr->insn_ptr = insn;
@@ -534,7 +540,13 @@ optimize_mode_switching (void)
                break;
            if (e)
              {
-               ptr = new_seginfo (no_mode, BB_HEAD (bb), bb->index, live_now);
+               rtx ins_pos = BB_HEAD (bb);
+               if (LABEL_P (ins_pos))
+                 ins_pos = NEXT_INSN (ins_pos);
+               gcc_assert (NOTE_INSN_BASIC_BLOCK_P (ins_pos));
+               if (ins_pos != BB_END (bb))
+                 ins_pos = NEXT_INSN (ins_pos);
+               ptr = new_seginfo (no_mode, ins_pos, bb->index, live_now);
                add_seginfo (info + bb->index, ptr);
                bitmap_clear_bit (transp[bb->index], j);
              }
@@ -733,7 +745,15 @@ optimize_mode_switching (void)
                    {
                      emitted = true;
                      if (NOTE_INSN_BASIC_BLOCK_P (ptr->insn_ptr))
-                       emit_insn_after (mode_set, ptr->insn_ptr);
+                       /* We need to emit the insns in a FIFO-like manner,
+                          i.e. the first to be emitted at our insertion
+                          point ends up first in the instruction steam.
+                          Because we made sure that NOTE_INSN_BASIC_BLOCK is
+                          only used for initially empty basic blocks, we
+                          can archive this by appending at the end of
+                          the block.  */
+                       emit_insn_after
+                         (mode_set, BB_END (NOTE_BASIC_BLOCK (ptr->insn_ptr)));
                      else
                        emit_insn_before (mode_set, ptr->insn_ptr);
                    }
index fdacc9c..e7f800a 100644 (file)
@@ -1,3 +1,8 @@
+2014-04-11  Joern Rennecke  <joern.rennecke@embecosm.com>
+
+       PR rtl-optimization/60651
+       * gcc.target/epiphany/mode-switch.c: New test.
+
 2014-04-11  Paolo Carlini  <paolo.carlini@oracle.com>
 
        PR c++/58600