Patchwork some prep work to make JUMP_TABLE_DATA a non-active_insn_p object

login
register
mail settings
Submitter Steven Bosscher
Date Nov. 8, 2013, 3:10 p.m.
Message ID <CABu31nPsodGhktdze6ZRjaXsPmi=hTPmKNDvmH62K32GPSi2ng@mail.gmail.com>
Download mbox | patch
Permalink /patch/289856/
State New
Headers show

Comments

Steven Bosscher - Nov. 8, 2013, 3:10 p.m.
Hello,

I'd like to make JUMP_TABLE_DATA a non-active insn before the end of
stage1. Most of the work required for this is pretty simple. It
involves finding and fixing the few places where insns are walked
across basic block boundaries and ignoring barriers. Ah, the madness
of that! :-) Fortunately almost no code does this in the shared RTL
middle end, and most targets are also safe.

This is the first patch of what I think will be four to fix those few places.

Bootstrapped&tested on powerpc64-unknown-linux-gnu. Also built SH to be sure.

OK for trunk?

Ciao!
Steven
* cfgrtl.c (can_fallthru): Reorder code to move tablejump check up.
	Make that check explicit.  BB_HEAD cannot be NULL, remove check for it.
	* haifa-sched.c (ready_remove_first_dispatch): Check INSN_P before
	looking at INSN_CODE.
	* reload1.c (delete_dead_insn) Do not expect JUMP_TABLE_DATA to be an
	active_insn_p object, respect basic block boundaries.
	* reorg.c (follow_jumps): Use invariant that JUMP_TABLE_DATA always
	follows immediately after the jump table data label.
	* config/nds32/nds32.c (nds32_output_casesi_pc_relative): Likewise.
	* config/sh/sh.c (barrier_align): Likewise.  Rearrange code such
	that JUMP_TABLE_DATA is not expected to be an active_insn_p object.
Eric Botcazou - Nov. 10, 2013, 5:11 p.m.
> This is the first patch of what I think will be four to fix those few
> places.
> 
> Bootstrapped&tested on powerpc64-unknown-linux-gnu. Also built SH to be
> sure.
> 
> OK for trunk?

The generic part is OK (modulo the additional space after ! in the 3rd hunk of 
the haifa-sched.c patch).
Richard Guenther - Nov. 11, 2013, 11:54 a.m.
On Sun, Nov 10, 2013 at 6:11 PM, Eric Botcazou <ebotcazou@adacore.com> wrote:
>> This is the first patch of what I think will be four to fix those few
>> places.
>>
>> Bootstrapped&tested on powerpc64-unknown-linux-gnu. Also built SH to be
>> sure.
>>
>> OK for trunk?
>
> The generic part is OK (modulo the additional space after ! in the 3rd hunk of
> the haifa-sched.c patch).

The rest is ok as well.

Richard.

> --
> Eric Botcazou

Patch

Index: cfgrtl.c
===================================================================
--- cfgrtl.c	(revision 204543)
+++ cfgrtl.c	(working copy)
@@ -610,7 +610,7 @@  forwarder_block_p (const_basic_block bb)
 }
 
 /* Return nonzero if we can reach target from src by falling through.  */
-/* FIXME: Make this a cfg hook.  */
+/* FIXME: Make this a cfg hook, the result is only valid in legacy cfgrtl mode.  */
 
 bool
 can_fallthru (basic_block src, basic_block target)
@@ -623,17 +623,21 @@  can_fallthru (basic_block src, basic_block target)
   if (target == EXIT_BLOCK_PTR)
     return true;
   if (src->next_bb != target)
-    return 0;
+    return false;
+
+  /* ??? Later we may add code to move jump tables offline.  */
+  if (tablejump_p (insn, NULL, NULL))
+    return false;
+
   FOR_EACH_EDGE (e, ei, src->succs)
     if (e->dest == EXIT_BLOCK_PTR
 	&& e->flags & EDGE_FALLTHRU)
-      return 0;
+      return false;
 
   insn2 = BB_HEAD (target);
-  if (insn2 && !active_insn_p (insn2))
+  if (!active_insn_p (insn2))
     insn2 = next_active_insn (insn2);
 
-  /* ??? Later we may add code to move jump tables offline.  */
   return next_active_insn (insn) == insn2;
 }
 
Index: haifa-sched.c
===================================================================
--- haifa-sched.c	(revision 204543)
+++ haifa-sched.c	(working copy)
@@ -8589,8 +8589,8 @@  ready_remove_first_dispatch (struct ready_list *re
   rtx insn = ready_element (ready, 0);
 
   if (ready->n_ready == 1
+      || !INSN_P (insn)
       || INSN_CODE (insn) < 0
-      || !INSN_P (insn)
       || !active_insn_p (insn)
       || targetm.sched.dispatch (insn, FITS_DISPATCH_WINDOW))
     return ready_remove_first (ready);
@@ -8599,8 +8599,8 @@  ready_remove_first_dispatch (struct ready_list *re
     {
       insn = ready_element (ready, i);
 
-      if (INSN_CODE (insn) < 0
-	  || !INSN_P (insn)
+      if (!INSN_P (insn)
+	  || INSN_CODE (insn) < 0
 	  || !active_insn_p (insn))
 	continue;
 
@@ -8619,8 +8619,8 @@  ready_remove_first_dispatch (struct ready_list *re
     {
       insn = ready_element (ready, i);
 
-      if (INSN_CODE (insn) < 0
-	  || !INSN_P (insn)
+      if (! INSN_P (insn)
+	  || INSN_CODE (insn) < 0
 	  || !active_insn_p (insn))
 	continue;
 
Index: reload1.c
===================================================================
--- reload1.c	(revision 204543)
+++ reload1.c	(working copy)
@@ -2123,7 +2123,8 @@  delete_dead_insn (rtx insn)
      block local equivalences.  Instead of trying to figure out the exact
      circumstances where we can delete the potentially dead insns, just
      let DCE do the job.  */
-  if (prev && GET_CODE (PATTERN (prev)) == SET
+  if (prev && BLOCK_FOR_INSN (prev) == BLOCK_FOR_INSN (insn)
+      && GET_CODE (PATTERN (prev)) == SET
       && (prev_dest = SET_DEST (PATTERN (prev)), REG_P (prev_dest))
       && reg_mentioned_p (prev_dest, PATTERN (insn))
       && find_regno_note (insn, REG_DEAD, REGNO (prev_dest))
Index: reorg.c
===================================================================
--- reorg.c	(revision 204543)
+++ reorg.c	(working copy)
@@ -2302,15 +2302,16 @@  follow_jumps (rtx label, rtx jump, bool *crossing)
        depth++)
     {
       rtx this_label = JUMP_LABEL (insn);
-      rtx tem;
 
       /* If we have found a cycle, make the insn jump to itself.  */
       if (this_label == label)
 	return label;
+
+      /* Cannot follow returns and cannot look through tablejumps.  */
       if (ANY_RETURN_P (this_label))
 	return this_label;
-      tem = next_active_insn (this_label);
-      if (tem && JUMP_TABLE_DATA_P (tem))
+      if (NEXT_INSN (this_label)
+	  && JUMP_TABLE_DATA_P (NEXT_INSN (this_label)))
 	break;
 
       if (!targetm.can_follow_jump (jump, insn))
Index: config/nds32/nds32.c
===================================================================
--- config/nds32/nds32.c	(revision 204543)
+++ config/nds32/nds32.c	(working copy)
@@ -4677,7 +4677,7 @@  nds32_output_casesi_pc_relative (rtx *operands)
   enum machine_mode mode;
   rtx diff_vec;
 
-  diff_vec = PATTERN (next_active_insn (operands[1]));
+  diff_vec = PATTERN (NEXT_INSN (operands[1]));
 
   gcc_assert (GET_CODE (diff_vec) == ADDR_DIFF_VEC);
 
Index: config/sh/sh.c
===================================================================
--- config/sh/sh.c	(revision 204543)
+++ config/sh/sh.c	(working copy)
@@ -5774,24 +5774,18 @@  fixup_addr_diff_vecs (rtx first)
 int
 barrier_align (rtx barrier_or_label)
 {
-  rtx next = next_active_insn (barrier_or_label), pat, prev;
-
-  if (! next)
-    return 0;
-
-  pat = PATTERN (next);
-
-  if (GET_CODE (pat) == ADDR_DIFF_VEC)
-    return 2;
-
-  if (GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_ALIGN)
-    /* This is a barrier in front of a constant table.  */
-    return 0;
-
-  prev = prev_active_insn (barrier_or_label);
-  if (GET_CODE (PATTERN (prev)) == ADDR_DIFF_VEC)
-    {
-      pat = PATTERN (prev);
+  rtx next, pat;
+
+  if (LABEL_P (barrier_or_label)
+      && NEXT_INSN (barrier_or_label)
+      && JUMP_TABLE_DATA_P (NEXT_INSN (barrier_or_label)))
+    return 2;
+
+  if (BARRIER_P (barrier_or_label)
+      && PREV_INSN (barrier_or_label)
+      && JUMP_TABLE_DATA_P (PREV_INSN (barrier_or_label)))
+    {
+      pat = PATTERN (PREV_INSN (barrier_or_label));
       /* If this is a very small table, we want to keep the alignment after
 	 the table to the minimum for proper code alignment.  */
       return ((optimize_size
@@ -5800,6 +5794,17 @@  barrier_align (rtx barrier_or_label)
 	      ? 1 << TARGET_SHMEDIA : align_jumps_log);
     }
 
+  next = next_active_insn (barrier_or_label);
+
+  if (! next)
+    return 0;
+
+  pat = PATTERN (next);
+
+  if (GET_CODE (pat) == UNSPEC_VOLATILE && XINT (pat, 1) == UNSPECV_ALIGN)
+    /* This is a barrier in front of a constant table.  */
+    return 0;
+
   if (optimize_size)
     return 0;
 
@@ -5824,13 +5829,12 @@  barrier_align (rtx barrier_or_label)
 	 (fill_eager_delay_slots) and the branch is to the insn after the insn
 	 after the barrier.  */
 
-      /* PREV is presumed to be the JUMP_INSN for the barrier under
-	 investigation.  Skip to the insn before it.  */
-
       int slot, credit;
       bool jump_to_next = false;
 
-      prev = prev_real_insn (prev);
+      /* Skip to the insn before the JUMP_INSN before the barrier under
+	 investigation.  */
+      rtx prev = prev_real_insn (prev_active_insn (barrier_or_label));
 
       for (slot = 2, credit = (1 << (CACHE_LOG - 2)) + 2;
 	   credit >= 0 && prev && NONJUMP_INSN_P (prev);