From d808ecdd4e263f2d19a2decafbff945a4bc5d447 Mon Sep 17 00:00:00 2001
From: Kaz Kojima <kkojima@gcc.gnu.org>
Date: Tue, 10 Feb 2015 00:00:54 +0000
Subject: [PATCH] re PR target/64761 (-freorder-blocks-and-partition causes
 some failures on SH)

PR target/64761
[SH] Add jump insn for -freorder-blocks-and-partition.  Don't degrade
-freorder-blocks-and-partition to -freorder-blocks even when unwinding
is enabled.

* [SH] Add jump insn for -freorder-blocks-and-partition.

From-SVN: r220553
---
 gcc/ChangeLog       | 10 ++++++++++
 gcc/config/sh/sh.c  | 31 ++++++++-----------------------
 gcc/config/sh/sh.md | 13 +++++++++++++
 3 files changed, 31 insertions(+), 23 deletions(-)

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a1916347c4e1..5981be87a1de 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 f8434d1fbcc0..2afd44ebde61 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 4a39e12d8db2..fe372b15bf78 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
-- 
GitLab