aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJoern Rennecke <joern.rennecke@embecosm.com>2014-04-11 18:12:53 +0000
committerJoern Rennecke <amylaar@gcc.gnu.org>2014-04-11 19:12:53 +0100
commit473fd99a4ca248ade8f6d648e4b688695055c1ee (patch)
tree905e1d1e868f4a9ffc9623f4e3fc998cb02a312a /gcc
parent6ace1161e62a9f09b36ef2dc0dacad97371e9dd0 (diff)
downloadgcc-473fd99a4ca248ade8f6d648e4b688695055c1ee.zip
gcc-473fd99a4ca248ade8f6d648e4b688695055c1ee.tar.gz
gcc-473fd99a4ca248ade8f6d648e4b688695055c1ee.tar.bz2
re PR rtl-optimization/60651 (Mode switching instructions are sometimes emitted in the wrong order)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/doc/tm.texi2
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/mode-switching.c26
-rw-r--r--gcc/testsuite/ChangeLog5
5 files changed, 45 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6d99d17..32ed05f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index f7024a7..b8ca17e 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -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
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index 6dcbde4..d793d26 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -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
diff --git a/gcc/mode-switching.c b/gcc/mode-switching.c
index 3166539..2848da3 100644
--- a/gcc/mode-switching.c
+++ b/gcc/mode-switching.c
@@ -96,12 +96,18 @@ static void make_preds_opaque (basic_block, int);
/* 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);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index fdacc9c..e7f800a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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