sched: Do not move expensive insns speculatively (PR68664)
authorSegher Boessenkool <segher@kernel.crashing.org>
Mon, 6 Feb 2017 19:19:49 +0000 (20:19 +0100)
committerSegher Boessenkool <segher@gcc.gnu.org>
Mon, 6 Feb 2017 19:19:49 +0000 (20:19 +0100)
Scheduling should never move very expensive instructions to places they
are executed more frequently.  This patch fixes that, reducing the
execution time of c-ray by over 40% (I tested on a BE Power7 system).

This introduces a new target hook sched.can_speculate_insn which returns
whether the scheduler is allowed to speculate a given instruction.  The
rs6000 implementation disallows all divide and square root instructions.

PR rtl-optimization/68664
* target.def (can_speculate_insn): New hook.
* doc/tm.texi.in (TARGET_SCHED_CAN_SPECULATE_INSN): New hook.
* doc/tm.texi: Regenerate.
* sched-rgn.c (can_schedule_ready_p): Use the new hook.
* config/rs6000/rs6000.c (TARGET_SCHED_CAN_SPECULATE_INSN): New macro.
(rs6000_sched_can_speculate_insn): New function.

From-SVN: r245215

gcc/ChangeLog
gcc/config/rs6000/rs6000.c
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/sched-rgn.c
gcc/target.def

index f0c773bda7581e2065acef4c36d3528ee2feb41a..7113dce7e1b44b170ea949e96030a49331ffd01e 100644 (file)
@@ -1,3 +1,13 @@
+2017-02-06  Segher Boessenkool  <segher@kernel.crashing.org>
+
+       PR rtl-optimization/68664
+       * target.def (can_speculate_insn): New hook.
+       * doc/tm.texi.in (TARGET_SCHED_CAN_SPECULATE_INSN): New hook.
+       * doc/tm.texi: Regenerate.
+       * sched-rgn.c (can_schedule_ready_p): Use the new hook.
+       * config/rs6000/rs6000.c (TARGET_SCHED_CAN_SPECULATE_INSN): New macro.
+       (rs6000_sched_can_speculate_insn): New function.
+
 2017-02-06  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/79284
index e44664124466418d730e16d69047cc11dc65cd7f..b1c9ef543150516e08e4f02a2fad269f88a94a46 100644 (file)
@@ -1607,6 +1607,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
 #undef TARGET_SCHED_FREE_SCHED_CONTEXT
 #define TARGET_SCHED_FREE_SCHED_CONTEXT rs6000_free_sched_context
 
+#undef TARGET_SCHED_CAN_SPECULATE_INSN
+#define TARGET_SCHED_CAN_SPECULATE_INSN rs6000_sched_can_speculate_insn
+
 #undef TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD
 #define TARGET_VECTORIZE_BUILTIN_MASK_FOR_LOAD rs6000_builtin_mask_for_load
 #undef TARGET_VECTORIZE_SUPPORT_VECTOR_MISALIGNMENT
@@ -34840,6 +34843,23 @@ rs6000_free_sched_context (void *_sc)
   free (_sc);
 }
 
+static bool
+rs6000_sched_can_speculate_insn (rtx_insn *insn)
+{
+  switch (get_attr_type (insn))
+    {
+    case TYPE_DIV:
+    case TYPE_SDIV:
+    case TYPE_DDIV:
+    case TYPE_VECDIV:
+    case TYPE_SSQRT:
+    case TYPE_DSQRT:
+      return false;
+
+    default:
+      return true;
+  }
+}
 \f
 /* Length in units of the trampoline for entering a nested function.  */
 
index 909589c373b9cce6cfce2f15bab37226c3ab0320..b34ee03278b62475bbbd74eab7606a7f0f89cba1 100644 (file)
@@ -7000,6 +7000,14 @@ The structure *@var{spec_info} should be filled in by the target.
 The structure describes speculation types that can be used in the scheduler.
 @end deftypefn
 
+@deftypefn {Target Hook} bool TARGET_SCHED_CAN_SPECULATE_INSN (rtx_insn *@var{insn})
+Some instructions should never be speculated by the schedulers, usually
+ because the instruction is too expensive to get this wrong.  Often such
+ instructions have long latency, and often they are not fully modeled in the
+ pipeline descriptions.  This hook should return @code{false} if @var{insn}
+ should not be speculated.
+@end deftypefn
+
 @deftypefn {Target Hook} int TARGET_SCHED_SMS_RES_MII (struct ddg *@var{g})
 This hook is called by the swing modulo scheduler to calculate a
 resource-based lower bound which is based on the resources available in
index ea74d37fa9a36af3b40471bcb8b248daf84234e1..756c1182493eeea3a50e3b07fb1f413c0f3a0148 100644 (file)
@@ -4882,6 +4882,8 @@ them: try the first ones in this list first.
 
 @hook TARGET_SCHED_SET_SCHED_FLAGS
 
+@hook TARGET_SCHED_CAN_SPECULATE_INSN
+
 @hook TARGET_SCHED_SMS_RES_MII
 
 @hook TARGET_SCHED_DISPATCH
index 2af3a03d1ff47727a6207466aa0d962f980528ca..a09fc5d1066ac17a5cd2215d3f4552c51abc5dbe 100644 (file)
@@ -2147,12 +2147,19 @@ static int
 can_schedule_ready_p (rtx_insn *insn)
 {
   /* An interblock motion?  */
-  if (INSN_BB (insn) != target_bb
-      && IS_SPECULATIVE_INSN (insn)
-      && !check_live (insn, INSN_BB (insn)))
-    return 0;
-  else
-    return 1;
+  if (INSN_BB (insn) != target_bb && IS_SPECULATIVE_INSN (insn))
+    {
+      /* Cannot schedule this insn unless all operands are live.  */
+      if (!check_live (insn, INSN_BB (insn)))
+       return 0;
+
+      /* Should not move expensive instructions speculatively.  */
+      if (GET_CODE (PATTERN (insn)) != CLOBBER
+         && !targetm.sched.can_speculate_insn (insn))
+       return 0;
+    }
+
+  return 1;
 }
 
 /* Updates counter and other information.  Split from can_schedule_ready_p ()
index 7308da16cdba033859b5b520d2b0063a3420d69c..43600aecd3f30b0819c2dd6cd4b5fa282528405a 100644 (file)
@@ -1480,6 +1480,15 @@ DEFHOOK_UNDOC
  "Return speculation types that are checked for instruction @var{insn}",
  unsigned int, (rtx_insn *insn), NULL)
 
+DEFHOOK
+(can_speculate_insn,
+ "Some instructions should never be speculated by the schedulers, usually\n\
+ because the instruction is too expensive to get this wrong.  Often such\n\
+ instructions have long latency, and often they are not fully modeled in the\n\
+ pipeline descriptions.  This hook should return @code{false} if @var{insn}\n\
+ should not be speculated.",
+ bool, (rtx_insn *insn), hook_bool_rtx_insn_true)
+
 DEFHOOK_UNDOC
 (skip_rtx_p,
  "Return bool if rtx scanning should just skip current layer and\