===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -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);
===================================================================
@@ -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
===================================================================
@@ -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
===================================================================
@@ -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