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
This commit is contained in:
parent
2568d8a1f6
commit
176274c9bf
6 changed files with 62 additions and 6 deletions
|
@ -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
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 ()
|
||||
|
|
|
@ -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\
|
||||
|
|
Loading…
Add table
Reference in a new issue