target.def (TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P): New hook.
authorSimon Dardis <simon.dardis@imgtec.com>
Mon, 26 Oct 2015 16:29:31 +0000 (16:29 +0000)
committerSimon Dardis <dardiss@gcc.gnu.org>
Mon, 26 Oct 2015 16:29:31 +0000 (16:29 +0000)
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
gcc/config/mips/mips.c
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/reorg.c
gcc/target.def
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/mips/ds-schedule-1.c [new file with mode: 0644]
gcc/testsuite/gcc.target/mips/ds-schedule-2.c [new file with mode: 0644]

index b5cfa1e693fc81f8b98bf7261fce7c0f2b4fac71..b2be8cf74113eb2a9027092a63725f993b783fb0 100644 (file)
@@ -1,3 +1,11 @@
+2015-10-26  Simon Dardis <simon.dardis@imgtec.com>
+
+       * 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  <law@redhat.com>
 
        PR tree-optimization/68013
index c5affc897124f9cb8757d5fc44387f8301b7d009..95d5ca34befaf3260a5715f5ff39040d61df559b 100644 (file)
@@ -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;
+}
 \f
 /* 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
 
index e6f712a4046d7ec7274ec9b8e2c03f80b03af7ca..a8666b1a8b45e946eb928c7631fd120b5841dc8c 100644 (file)
@@ -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
 
index 6f0c252bf172b788341a1ac57c13e2d48a6b6109..69b6cf90e21f1f170d961ce237b8ae68a6f6e8bf 100644 (file)
@@ -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
 
index 47b938b46d05ae94b5a75fd4bcf2726bd84fd14a..ccd0d71d1f705f2413ca12d3f536b25ac879ceb6 100644 (file)
@@ -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);
     }
 
index e4bc249939a53f6d1814d4c0b83b0d49c07f3468..b74887d733179ffd9a8bf75ad26d4885e0039e53 100644 (file)
@@ -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,
index 688f7456fe84863eec250bfbda75208e71a7bc91..04700fbf8421bfc80dd94604b924994146e99a84 100644 (file)
@@ -1,3 +1,8 @@
+2015-10-26  Simon Dardis  <simon.dardis@imgtec.com>
+
+       * gcc.target/mips/ds-schedule-1.c: New.
+       * gcc.target/mips/ds-schedule-2.c: New.
+
 2015-10-26  Jeff Law  <law@redhat.com>
 
        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 (file)
index 0000000..9cc5daa
--- /dev/null
@@ -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 (file)
index 0000000..6c5de5d
--- /dev/null
@@ -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);
+}