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.renne...@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. 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