[PATCH 2/3] [SH] Add jump insn for -freorder-blocks-and-partition

Kaz Kojima kkojima@rr.iij4u.or.jp
Tue Jan 27 03:50:00 GMT 2015


This patch adds a new jump insn for the jump crossing between hot/cold
pertitions and reenables -freorder-blocks-and-partition on SH in
some cases.

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

diff --git a/config/sh/sh.c b/config/sh/sh.c
index 886ffc3..a6ca208 100644
--- a/config/sh/sh.c
+++ b/config/sh/sh.c
@@ -1060,29 +1060,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.
@@ -10750,6 +10727,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/config/sh/sh.md b/config/sh/sh.md
index 50f374c..b3b0012 100644
--- a/config/sh/sh.md
+++ b/config/sh/sh.md
@@ -9003,6 +9003,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



More information about the Gcc-patches mailing list