aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2017-02-06 20:19:49 +0100
committerSegher Boessenkool <segher@gcc.gnu.org>2017-02-06 20:19:49 +0100
commit176274c9bf515f3b71f00b2be71a9ee4771b271f (patch)
treeeebb74792325dc6a931fd34554fc77bf0e7a321a /gcc
parent2568d8a1f6d3912e53c457a1ea080050a834cf32 (diff)
downloadgcc-176274c9bf515f3b71f00b2be71a9ee4771b271f.zip
gcc-176274c9bf515f3b71f00b2be71a9ee4771b271f.tar.gz
gcc-176274c9bf515f3b71f00b2be71a9ee4771b271f.tar.bz2
sched: Do not move expensive insns speculatively (PR68664)
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/rs6000/rs6000.c20
-rw-r--r--gcc/doc/tm.texi8
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/sched-rgn.c19
-rw-r--r--gcc/target.def9
6 files changed, 62 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f0c773b..7113dce 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index e446641..b1c9ef5 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -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;
+ }
+}
/* Length in units of the trampoline for entering a nested function. */
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index 909589c..b34ee03 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -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
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index ea74d37..756c118 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -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
diff --git a/gcc/sched-rgn.c b/gcc/sched-rgn.c
index 2af3a03..a09fc5d 100644
--- a/gcc/sched-rgn.c
+++ b/gcc/sched-rgn.c
@@ -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 ()
diff --git a/gcc/target.def b/gcc/target.def
index 7308da1..43600ae 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -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\