diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a1916347c4e184513da1efac9d8d09dcfb73e88c..5981be87a1de7a8a274946d3d77719282fc66be1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2015-02-09 Kaz Kojima <kkojima@gcc.gnu.org> + + PR target/64761 + * config/sh/sh.c (sh_option_override): Don't change + -freorder-blocks-and-partition to -freorder-blocks even when + unwinding is enabled. + (sh_can_follow_jump): Return false if the followee jump is + a crossing jump when -freorder-blocks-and-partition is specified. + * config/sh/sh.md (*jump_compact_crossing): New insn. + 2015-02-09 Joern Rennecke <joern.rennecke@embecosm.com> Kaz Kojima <kkojima@gcc.gnu.org> diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index f8434d1fbcc0e614acfad5dc2c97d9f86910c176..2afd44ebde61fb41d0e4b9b43400f8479ee93bb5 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -1065,29 +1065,6 @@ sh_option_override (void) TARGET_ACCUMULATE_OUTGOING_ARGS = 1; } - /* Unwinding with -freorder-blocks-and-partition does not work on this - architecture, because it requires far jumps to label crossing between - hot/cold sections which are rejected on this architecture. */ - if (flag_reorder_blocks_and_partition) - { - if (flag_exceptions) - { - inform (input_location, - "-freorder-blocks-and-partition does not work with " - "exceptions on this architecture"); - flag_reorder_blocks_and_partition = 0; - flag_reorder_blocks = 1; - } - else if (flag_unwind_tables) - { - inform (input_location, - "-freorder-blocks-and-partition does not support unwind " - "info on this architecture"); - flag_reorder_blocks_and_partition = 0; - flag_reorder_blocks = 1; - } - } - /* Adjust loop, jump and function alignment values (in bytes), if those were not specified by the user using -falign-loops, -falign-jumps and -falign-functions options. @@ -10828,6 +10805,14 @@ mark_constant_pool_use (rtx x) static bool sh_can_follow_jump (const rtx_insn *branch1, const rtx_insn *branch2) { + /* Don't follow if BRANCH2 is possible to be a jump crossing between + hot and cold partitions. */ + if (TARGET_SH1 + && flag_reorder_blocks_and_partition + && simplejump_p (branch2) + && CROSSING_JUMP_P (branch2)) + return false; + if (flag_expensive_optimizations && simplejump_p (branch2)) { rtx dest = XEXP (SET_SRC (single_set (branch2)), 0); diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md index 4a39e12d8db29fb070b3711d04b4334e479ca54e..fe372b15bf7865818d6f16124d24a84aa88a566c 100644 --- a/gcc/config/sh/sh.md +++ b/gcc/config/sh/sh.md @@ -9358,6 +9358,19 @@ label: [(set_attr "type" "jump") (set_attr "needs_delay_slot" "yes")]) +(define_insn "*jump_compact_crossing" + [(set (pc) + (label_ref (match_operand 0 "" "")))] + "TARGET_SH1 + && flag_reorder_blocks_and_partition + && CROSSING_JUMP_P (insn)" +{ + /* The length is 16 if the delay slot is unfilled. */ + return output_far_jump(insn, operands[0]); +} + [(set_attr "type" "jump") + (set_attr "length" "16")]) + ;; ??? It would be much saner to explicitly use the scratch register ;; in the jump insn, and have indirect_jump_scratch only set it, ;; but fill_simple_delay_slots would refuse to do delay slot filling