Patchwork RFA: Fix PR rtl-optimization/38449 (patch updated)

login
register
mail settings
Submitter Joern Rennecke
Date Sept. 20, 2012, 12:50 a.m.
Message ID <20120919205053.hr0sfz7odcgs0goc-nzlynne@webmail.spamcop.net>
Download mbox | patch
Permalink /patch/185273/
State New
Headers show

Comments

Joern Rennecke - Sept. 20, 2012, 12:50 a.m.
Bootstrapped in revision 191429 on i686-pc-linux-gnu.

The arc.c context can be seen here:

http://gcc.gnu.org/viewcvs/branches/arc-4_4-20090909-branch/gcc/config/arc/arc.c?content-type=text%2Fplain&view=co

The relevant code in arc.c hasn't changed in the port updated to GCC 4.8 .
2012-08-14  Joern Rennecke  <joern.rennecke@embecosm.com>

	PR rtl-optimization/38449:
	* hooks.c (hook_bool_const_rtx_const_rtx_true): New function.
	* hooks.h (hook_bool_const_rtx_const_rtx_true): Declare.
	* target.def: Merge in definitions and documentation for
	TARGET_CAN_FOLLOW_JUMP.
	* doc/tm.texi.in: Add documentation locations for the above.
	* doc/tm.texi: Regenerate.
	* reorg.c (follow_jumps): New parameters jump and cp.
	Changed all callers.
Eric Botcazou - Sept. 29, 2012, 1:41 p.m.
> Bootstrapped in revision 191429 on i686-pc-linux-gnu.

Bootstrap on x86 for a reorg.c patch doesn't say much though. :-)

> The arc.c context can be seen here:
> 
> http://gcc.gnu.org/viewcvs/branches/arc-4_4-20090909-branch/gcc/config/arc/a
> rc.c?content-type=text%2Fplain&view=co

OK, modulo the following changes:

-/* Follow any unconditional jump at LABEL;
+/* Follow any unconditional jump at LABEL, for the purpose of redirecting 
JUMP;
    return the ultimate label reached by any such chain of jumps.
    Return a suitable return rtx if the chain ultimately leads to a
    return instruction.
    If LABEL is not followed by a jump, return LABEL.
    If the chain loops or we can't find end, return LABEL,
-   since that tells caller to avoid changing the insn.  */
+   since that tells caller to avoid changing the insn.
+   If the returned label is obtained by following a REG_CROSSING_JUMP
+   jump, set *cp to (one of) the note(s), otherwise set it to NULL_RTX.  */
 
 static rtx
-follow_jumps (rtx label)
+follow_jumps (rtx label, rtx jump, rtx *cp)

You're using `cp' as a boolean named `crossing' throughout, so change 
follow_jumps accordingly:

   If the returned label is obtained by following a REG_CROSSING_JUMP
   jump, set *CROSSING to true, otherwise set it to false.  */

static rtx
follow_jumps (rtx label, rtx jump, bool *crossing)



@@ -1350,6 +1350,16 @@ HOOK_VECTOR_END (vectorize)
  bool, (void),
  hook_bool_void_false)
 
+/* True if FOLLOWER may be modified to follow FOLLOWEE.  */
+DEFHOOK
+(can_follow_jump,
+ "Return true if FOLLOWER may be modified to follow FOLLOWEE;\
+  false, if it can't.\
+  For example, on some targets, certain kinds of branches can't be made to\
+  follow through a hot/cold partitioning.",
+ bool, (const_rtx follower, const_rtx followee),
+ hook_bool_const_rtx_const_rtx_true)

Explicitly mention that both FOLLOWER and FOLLOWEE are JUMP_INSN instructions.

Patch

Index: reorg.c
===================================================================
--- reorg.c	(revision 191429)
+++ reorg.c	(working copy)
@@ -2494,24 +2494,28 @@  fill_simple_delay_slots (int non_jumps_p
 #endif
 }
 
-/* Follow any unconditional jump at LABEL;
+/* Follow any unconditional jump at LABEL, for the purpose of redirecting JUMP;
    return the ultimate label reached by any such chain of jumps.
    Return a suitable return rtx if the chain ultimately leads to a
    return instruction.
    If LABEL is not followed by a jump, return LABEL.
    If the chain loops or we can't find end, return LABEL,
-   since that tells caller to avoid changing the insn.  */
+   since that tells caller to avoid changing the insn.
+   If the returned label is obtained by following a REG_CROSSING_JUMP
+   jump, set *cp to (one of) the note(s), otherwise set it to NULL_RTX.  */
 
 static rtx
-follow_jumps (rtx label)
+follow_jumps (rtx label, rtx jump, rtx *cp)
 {
   rtx insn;
   rtx next;
   rtx value = label;
   int depth;
+  rtx crossing = NULL_RTX;
 
   if (ANY_RETURN_P (label))
     return label;
+  *cp = 0;
   for (depth = 0;
        (depth < 10
 	&& (insn = next_active_insn (value)) != 0
@@ -2537,10 +2541,15 @@  follow_jumps (rtx label)
 	      || GET_CODE (PATTERN (tem)) == ADDR_DIFF_VEC))
 	break;
 
+      if (!targetm.can_follow_jump (jump, insn))
+	break;
+      if (!crossing)
+	crossing = find_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX);
       value = this_label;
     }
   if (depth == 10)
     return label;
+  *cp = crossing;
   return value;
 }
 
@@ -2984,6 +2993,7 @@  fill_slots_from_thread (rtx insn, rtx co
   if (new_thread != thread)
     {
       rtx label;
+      rtx crossing = NULL_RTX;
 
       gcc_assert (thread_if_true);
 
@@ -2991,7 +3001,7 @@  fill_slots_from_thread (rtx insn, rtx co
 	  && redirect_with_delay_list_safe_p (insn,
 					      JUMP_LABEL (new_thread),
 					      delay_list))
-	new_thread = follow_jumps (JUMP_LABEL (new_thread));
+	new_thread = follow_jumps (JUMP_LABEL (new_thread), insn, &crossing);
 
       if (ANY_RETURN_P (new_thread))
 	label = find_end_label (new_thread);
@@ -3001,7 +3011,11 @@  fill_slots_from_thread (rtx insn, rtx co
 	label = get_label_before (new_thread);
 
       if (label)
-	reorg_redirect_jump (insn, label);
+	{
+	  reorg_redirect_jump (insn, label);
+	  if (crossing)
+	    set_unique_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX);
+	}
     }
 
   return delay_list;
@@ -3347,6 +3361,7 @@  relax_delay_slots (rtx first)
   for (insn = first; insn; insn = next)
     {
       rtx other;
+      rtx crossing;
 
       next = next_active_insn (insn);
 
@@ -3357,7 +3372,9 @@  relax_delay_slots (rtx first)
 	  && (condjump_p (insn) || condjump_in_parallel_p (insn))
 	  && !ANY_RETURN_P (target_label = JUMP_LABEL (insn)))
 	{
-	  target_label = skip_consecutive_labels (follow_jumps (target_label));
+	  target_label
+	    = skip_consecutive_labels (follow_jumps (target_label, insn,
+						     &crossing));
 	  if (ANY_RETURN_P (target_label))
 	    target_label = find_end_label (target_label);
 
@@ -3369,7 +3386,11 @@  relax_delay_slots (rtx first)
 	    }
 
 	  if (target_label && target_label != JUMP_LABEL (insn))
-	    reorg_redirect_jump (insn, target_label);
+	    {
+	      reorg_redirect_jump (insn, target_label);
+	      if (crossing)
+		set_unique_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX);
+	    }
 
 	  /* See if this jump conditionally branches around an unconditional
 	     jump.  If so, invert this jump and point it to the target of the
@@ -3505,7 +3526,8 @@  relax_delay_slots (rtx first)
 
       /* If this jump goes to another unconditional jump, thread it, but
 	 don't convert a jump into a RETURN here.  */
-      trial = skip_consecutive_labels (follow_jumps (target_label));
+      trial = skip_consecutive_labels (follow_jumps (target_label, delay_insn,
+						     &crossing));
       if (ANY_RETURN_P (trial))
 	trial = find_end_label (trial);
 
@@ -3514,6 +3536,8 @@  relax_delay_slots (rtx first)
 	{
 	  reorg_redirect_jump (delay_insn, trial);
 	  target_label = trial;
+	  if (crossing)
+	    set_unique_reg_note (insn, REG_CROSSING_JUMP, NULL_RTX);
 	}
 
       /* If the first insn at TARGET_LABEL is redundant with a previous
Index: hooks.c
===================================================================
--- hooks.c	(revision 191429)
+++ hooks.c	(working copy)
@@ -117,6 +117,14 @@  hook_bool_mode_rtx_true (enum machine_mo
   return true;
 }
 
+/* Generic hook that takes (rtx, rtx) and returns true.  */
+bool
+hook_bool_const_rtx_const_rtx_true (const_rtx follower ATTRIBUTE_UNUSED,
+				    const_rtx followee ATTRIBUTE_UNUSED)
+{
+  return true;
+}
+
 /* Generic hook that takes (enum machine_mode, unsigned HOST_WIDE_INT)
    and returns false.  */
 bool
Index: hooks.h
===================================================================
--- hooks.h	(revision 191429)
+++ hooks.h	(working copy)
@@ -36,6 +36,7 @@  extern bool hook_bool_mode_const_rtx_fal
 extern bool hook_bool_mode_const_rtx_true (enum machine_mode, const_rtx);
 extern bool hook_bool_mode_rtx_false (enum machine_mode, rtx);
 extern bool hook_bool_mode_rtx_true (enum machine_mode, rtx);
+extern bool hook_bool_const_rtx_const_rtx_true (const_rtx, const_rtx);
 extern bool hook_bool_mode_uhwi_false (enum machine_mode,
 				       unsigned HOST_WIDE_INT);
 extern bool hook_bool_tree_false (tree);
Index: target.def
===================================================================
--- target.def	(revision 191429)
+++ target.def	(working copy)
@@ -1350,6 +1350,16 @@  HOOK_VECTOR_END (vectorize)
  bool, (void),
  hook_bool_void_false)
 
+/* True if FOLLOWER may be modified to follow FOLLOWEE.  */
+DEFHOOK
+(can_follow_jump,
+ "Return true if FOLLOWER may be modified to follow FOLLOWEE;\
+  false, if it can't.\
+  For example, on some targets, certain kinds of branches can't be made to\
+  follow through a hot/cold partitioning.",
+ bool, (const_rtx follower, const_rtx followee),
+ hook_bool_const_rtx_const_rtx_true)
+
 /* Return a register class for which branch target register
    optimizations should be applied.  */
 DEFHOOK
Index: doc/tm.texi
===================================================================
--- doc/tm.texi	(revision 191429)
+++ doc/tm.texi	(working copy)
@@ -10957,6 +10957,10 @@  @defmac MD_CAN_REDIRECT_BRANCH (@var{bra
 may in turn cause a branch offset to overflow.
 @end defmac
 
+@deftypefn {Target Hook} bool TARGET_CAN_FOLLOW_JUMP (const_rtx @var{follower}, const_rtx @var{followee})
+Return true if FOLLOWER may be modified to follow FOLLOWEE;  false, if it can't.  For example, on some targets, certain kinds of branches can't be made to  follow through a hot/cold partitioning.
+@end deftypefn
+
 @deftypefn {Target Hook} bool TARGET_COMMUTATIVE_P (const_rtx @var{x}, int @var{outer_code})
 This target hook returns @code{true} if @var{x} is considered to be commutative.
 Usually, this is just COMMUTATIVE_P (@var{x}), but the HP PA doesn't consider
Index: doc/tm.texi.in
===================================================================
--- doc/tm.texi.in	(revision 191429)
+++ doc/tm.texi.in	(working copy)
@@ -10813,6 +10813,8 @@  @defmac MD_CAN_REDIRECT_BRANCH (@var{bra
 may in turn cause a branch offset to overflow.
 @end defmac
 
+@hook TARGET_CAN_FOLLOW_JUMP
+
 @hook TARGET_COMMUTATIVE_P
 This target hook returns @code{true} if @var{x} is considered to be commutative.
 Usually, this is just COMMUTATIVE_P (@var{x}), but the HP PA doesn't consider