]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR rtl-optimization/38449 (delay branch scheduling follows REG_CROSSING_JUMP jumps...
authorJoern Rennecke <joern.rennecke@embecosm.com>
Sun, 30 Sep 2012 19:25:49 +0000 (19:25 +0000)
committerJoern Rennecke <amylaar@gcc.gnu.org>
Sun, 30 Sep 2012 19:25:49 +0000 (20:25 +0100)
        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 crossing.
        Changed all callers.

From-SVN: r191878

gcc/ChangeLog
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/hooks.c
gcc/hooks.h
gcc/reorg.c
gcc/target.def

index 050756d9fd62487a8b47cc80bbc8ec7d9907f3a5..d338ee37d2318fd6a17c21638bd7c0d5e5942c27 100644 (file)
@@ -1,3 +1,15 @@
+2012-09-30  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 crossing.
+       Changed all callers.
+
 2012-09-30  Eric Botcazou  <ebotcazou@adacore.com>
 
        * reorg.c (relax_delay_slots): Use delay_insn consistently.
index a14a4fc9a8859726bf0a974b04284b6a7949abc9..b36c764a3b5ae7e04c925562d02ec15538270ea0 100644 (file)
@@ -10958,6 +10958,10 @@ filling of delay slots can result in branches being redirected, and this
 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})
+FOLLOWER and FOLLOWEE are JUMP_INSN instructions;  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 a85fee1b4a140d98ad80a0356464ed6f61a5404e..4858d97e27fffdbad0db2826895d46760655772d 100644 (file)
@@ -10814,6 +10814,8 @@ filling of delay slots can result in branches being redirected, and this
 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
index 775da3c3d2f6c361c493b477e71974e47eb0420a..b26252203f7ffe34d391c6c91911fde1e6afb0df 100644 (file)
@@ -117,6 +117,14 @@ hook_bool_mode_rtx_true (enum machine_mode mode ATTRIBUTE_UNUSED,
   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 1774816d4e92a04b1e576faab72c261cacbe9dd5..71b391a1b49e665c5d41a64653e4c391d4bcd262 100644 (file)
@@ -36,6 +36,7 @@ extern bool hook_bool_mode_const_rtx_false (enum machine_mode, const_rtx);
 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 dd50d211532d5fafa969d76302ab1d1231303ba6..89442e395aa4bb55e7dd8c7e9e706ef832789e7a 100644 (file)
@@ -2494,22 +2494,25 @@ fill_simple_delay_slots (int non_jumps_p)
 #endif
 }
 \f
-/* 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 *CROSSING to true, otherwise set it to false.  */
 
 static rtx
-follow_jumps (rtx label)
+follow_jumps (rtx label, rtx jump, bool *crossing)
 {
   rtx insn;
   rtx next;
   rtx value = label;
   int depth;
 
+  *crossing = false;
   if (ANY_RETURN_P (label))
     return label;
   for (depth = 0;
@@ -2537,6 +2540,11 @@ 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) != NULL_RTX;
       value = this_label;
     }
   if (depth == 10)
@@ -2984,6 +2992,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
   if (new_thread != thread)
     {
       rtx label;
+      bool crossing = false;
 
       gcc_assert (thread_if_true);
 
@@ -2991,7 +3000,7 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
          && 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 +3010,11 @@ fill_slots_from_thread (rtx insn, rtx condition, rtx thread,
        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 +3360,7 @@ relax_delay_slots (rtx first)
   for (insn = first; insn; insn = next)
     {
       rtx other;
+      bool crossing;
 
       next = next_active_insn (insn);
 
@@ -3357,7 +3371,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 +3385,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
@@ -3503,7 +3523,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);
 
@@ -3512,6 +3533,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 8922c783e04bf07d2a5263c34b7cb672c3a331d2..2d79290b311b5c321edf710d8a768f2ea09fafa4 100644 (file)
@@ -1350,6 +1350,17 @@ DEFHOOK
  bool, (void),
  hook_bool_void_false)
 
+/* True if FOLLOWER may be modified to follow FOLLOWEE.  */
+DEFHOOK
+(can_follow_jump,
+ "FOLLOWER and FOLLOWEE are JUMP_INSN instructions;\
+  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