diff mbox

RFA: Fix PR rtl-optimization/60651

Message ID CAMqJFCoN41VfgCg5juxYR084=OvBz5R-XgvFpq=eaB6MH5mo3A@mail.gmail.com
State New
Headers show

Commit Message

Joern Rennecke April 2, 2014, 5:40 p.m. UTC
On 2 April 2014 17:34, Joern Rennecke <joern.rennecke@embecosm.com> wrote:
> Hmm, the sanity check in new_seginfo caused a boostrap failure
> building libjava on x86.
> There was a block with CODE_LABEL as basic block head, otherwise empty.

I've added the testcase - and a bit more detail on this issue - in the PR.

I've attached an updated patch, which skips past the CODE_LABEL.
And this one bootstraps on i686-pc-linuc-gnu.
2014-04-02  Joern Rennecke  <joern.rennecke@embecosm.com>

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.

Comments

Eric Botcazou April 5, 2014, 9:54 a.m. UTC | #1
> I've added the testcase - and a bit more detail on this issue - in the PR.
> 
> I've attached an updated patch, which skips past the CODE_LABEL.
> And this one bootstraps on i686-pc-linuc-gnu.

OK for stage 1 modulo the typo ("an" instead of "en") in a comment.
Jeff Law May 19, 2014, 8:30 p.m. UTC | #2
On 04/02/14 11:40, Joern Rennecke wrote:
> On 2 April 2014 17:34, Joern Rennecke <joern.rennecke@embecosm.com> wrote:
>> Hmm, the sanity check in new_seginfo caused a boostrap failure
>> building libjava on x86.
>> There was a block with CODE_LABEL as basic block head, otherwise empty.
>
> I've added the testcase - and a bit more detail on this issue - in the PR.
>
> I've attached an updated patch, which skips past the CODE_LABEL.
> And this one bootstraps on i686-pc-linuc-gnu.
In optimize_mode_switching, you've got "archive" in a comment where it 
should be "achieve"

Fix that and it's good to go.



jeff
diff mbox

Patch

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 88543b2..088156c 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 en 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);
 		    }
--- /dev/null	2014-03-19 18:18:19.244212660 +0000
+++ b/gcc/testsuite/gcc.target/epiphany/mode-switch.c	2014-03-25 13:31:41.186140611 +0000
@@ -0,0 +1,12 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler "#-917506" } } */
+/* PR 60651 */
+
+int a;
+int c;
+
+void __attribute__((interrupt))
+misc_handler (void) {
+   a*= c;
+}