From f52a73a48ee7123e3db494c6b0ac72d0d4359ad9 Mon Sep 17 00:00:00 2001 From: Simon Dardis Date: Mon, 26 Oct 2015 16:29:31 +0000 Subject: [PATCH] target.def (TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P): New hook. gcc/ * target.def (TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P): New hook. * doc/tm.texi.in (TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P): Document. * doc/tm.texi: Regenerated. * reorg.c (dbr_schedule): Use new hook. * config/mips/mips.c (mips_no_speculation_in_delay_slots_p): New. testsuite/ * gcc.target/mips/ds-schedule-1.c: New. * gcc.target/mips/ds-schedule-2.c: New. From-SVN: r229383 --- gcc/ChangeLog | 8 +++++ gcc/config/mips/mips.c | 11 +++++++ gcc/doc/tm.texi | 10 +++++++ gcc/doc/tm.texi.in | 2 ++ gcc/reorg.c | 3 +- gcc/target.def | 13 +++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/mips/ds-schedule-1.c | 29 +++++++++++++++++++ gcc/testsuite/gcc.target/mips/ds-schedule-2.c | 28 ++++++++++++++++++ 9 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/mips/ds-schedule-1.c create mode 100644 gcc/testsuite/gcc.target/mips/ds-schedule-2.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b5cfa1e693f..b2be8cf7411 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2015-10-26 Simon Dardis + + * target.def (TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P): New hook. + * doc/tm.texi.in (TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P): Document. + * doc/tm.texi: Regenerated. + * reorg.c (dbr_schedule): Use new hook. + * config/mips/mips.c (mips_no_speculation_in_delay_slots_p): New. + 2015-10-26 Jeff Law PR tree-optimization/68013 diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c index c5affc89712..95d5ca34bef 100644 --- a/gcc/config/mips/mips.c +++ b/gcc/config/mips/mips.c @@ -4312,6 +4312,14 @@ mips_address_cost (rtx addr, machine_mode mode, { return mips_address_insns (addr, mode, false); } + +/* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */ + +static bool +mips_no_speculation_in_delay_slots_p () +{ + return TARGET_CB_MAYBE; +} /* Information about a single instruction in a multi-instruction asm sequence. */ @@ -19823,6 +19831,9 @@ mips_ira_change_pseudo_allocno_class (int regno, reg_class_t allocno_class) #undef TARGET_ADDRESS_COST #define TARGET_ADDRESS_COST mips_address_cost +#undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P +#define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P mips_no_speculation_in_delay_slots_p + #undef TARGET_IN_SMALL_DATA_P #define TARGET_IN_SMALL_DATA_P mips_in_small_data_p diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index e6f712a4046..a8666b1a8b4 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -6450,6 +6450,16 @@ should probably only be given to addresses with different numbers of registers on machines with lots of registers. @end deftypefn +@deftypefn {Target Hook} bool TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P (void) +This predicate controls the use of the eager delay slot filler to disallow +speculatively executed instructions being placed in delay slots. Targets +such as certain MIPS architectures possess both branches with and without +delay slots. As the eager delay slot filler can decrease performance, +disabling it is beneficial when ordinary branches are available. Use of +delay slot branches filled using the basic filler is often still desirable +as the delay slot can hide a pipeline bubble. +@end deftypefn + @node Scheduling @section Adjusting the Instruction Scheduler diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 6f0c252bf17..69b6cf90e21 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -4726,6 +4726,8 @@ Define this macro if a non-short-circuit operation produced by @hook TARGET_ADDRESS_COST +@hook TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P + @node Scheduling @section Adjusting the Instruction Scheduler diff --git a/gcc/reorg.c b/gcc/reorg.c index 47b938b46d0..ccd0d71d1f7 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -3726,7 +3726,8 @@ dbr_schedule (rtx_insn *first) { fill_simple_delay_slots (1); fill_simple_delay_slots (0); - fill_eager_delay_slots (); + if (!targetm.no_speculation_in_delay_slots_p ()) + fill_eager_delay_slots (); relax_delay_slots (first); } diff --git a/gcc/target.def b/gcc/target.def index e4bc249939a..b74887d7331 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -3506,6 +3506,19 @@ registers on machines with lots of registers.", int, (rtx address, machine_mode mode, addr_space_t as, bool speed), default_address_cost) +/* Permit speculative instructions in delay slots during delayed-branch + scheduling. */ +DEFHOOK +(no_speculation_in_delay_slots_p, + "This predicate controls the use of the eager delay slot filler to disallow\n\ +speculatively executed instructions being placed in delay slots. Targets\n\ +such as certain MIPS architectures possess both branches with and without\n\ +delay slots. As the eager delay slot filler can decrease performance,\n\ +disabling it is beneficial when ordinary branches are available. Use of\n\ +delay slot branches filled using the basic filler is often still desirable\n\ +as the delay slot can hide a pipeline bubble.", bool, (void), + hook_bool_void_false) + /* Return where to allocate pseudo for a given hard register initial value. */ DEFHOOK (allocate_initial_value, diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 688f7456fe8..04700fbf842 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2015-10-26 Simon Dardis + + * gcc.target/mips/ds-schedule-1.c: New. + * gcc.target/mips/ds-schedule-2.c: New. + 2015-10-26 Jeff Law PR tree-optimization/68013 diff --git a/gcc/testsuite/gcc.target/mips/ds-schedule-1.c b/gcc/testsuite/gcc.target/mips/ds-schedule-1.c new file mode 100644 index 00000000000..9cc5daa831c --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/ds-schedule-1.c @@ -0,0 +1,29 @@ +/* { dg-options "isa_rev>=6 -mcompact-branches=optimal -mno-abicalls -G4" } */ +/* { dg-final { scan-assembler-not "bne\t" } } */ +/* { dg-final { scan-assembler-not "beq\t" } } */ +/* { dg-final { scan-assembler-times "\\(foo\\)" 1 } } */ + +/* Test that when compact branches are used, that a compact branch is + produced in the case where code expansion would have occurred if a + delay slot branch would have be used. 'foo' should only be + referenced once in the program text. */ + +struct list +{ + struct list *next; + int element; +}; + +struct list *gr; + +int foo; + +extern void t (int, int, int*); + +void +f (struct list **ptr) +{ + if (gr) + *ptr = gr->next; + t (1, foo, &gr->element); +} diff --git a/gcc/testsuite/gcc.target/mips/ds-schedule-2.c b/gcc/testsuite/gcc.target/mips/ds-schedule-2.c new file mode 100644 index 00000000000..6c5de5dac92 --- /dev/null +++ b/gcc/testsuite/gcc.target/mips/ds-schedule-2.c @@ -0,0 +1,28 @@ +/* { dg-options "-mcompact-branches=never -mno-abicalls -G4" } */ +/* { dg-skip-if "code quality test" { *-*-* } { "-O0" "-O1" "-Os" } { "" } } */ +/* { dg-final { scan-assembler "beq.*\n\tlw" } } */ +/* { dg-final { scan-assembler-times "\\(foo\\)" 2 } } */ + +/* Test that when compact branches are explicitly disabled, that a non-compact + branch is produced. 'foo' should be referenced twice in the program text as the + eager delay slot filler will duplicate the load of foo. */ + +struct list +{ + struct list *next; + int element; +}; + +struct list *gr; + +int foo; + +extern void t (int, int, int*); + +void +f (struct list **ptr) +{ + if (gr) + *ptr = gr->next; + t (1, foo, &gr->element); +} -- 2.30.2