diff options
author | Joern Rennecke <joern.rennecke@embecosm.com> | 2014-04-11 18:12:53 +0000 |
---|---|---|
committer | Joern Rennecke <amylaar@gcc.gnu.org> | 2014-04-11 19:12:53 +0100 |
commit | 473fd99a4ca248ade8f6d648e4b688695055c1ee (patch) | |
tree | 905e1d1e868f4a9ffc9623f4e3fc998cb02a312a /gcc | |
parent | 6ace1161e62a9f09b36ef2dc0dacad97371e9dd0 (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 2 | ||||
-rw-r--r-- | gcc/doc/tm.texi.in | 2 | ||||
-rw-r--r-- | gcc/mode-switching.c | 26 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 |
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 |