re PR rtl-optimization/38449 (delay branch scheduling follows REG_CROSSING_JUMP jumps indiscriminately)
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
This commit is contained in:
parent
f84992b001
commit
4b4de898c9
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
39
gcc/reorg.c
39
gcc/reorg.c
@ -2494,22 +2494,25 @@ 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 *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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user