+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
{
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. */
#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
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
@hook TARGET_ADDRESS_COST
+@hook TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
+
@node Scheduling
@section Adjusting the Instruction Scheduler
{
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);
}
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,
+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
--- /dev/null
+/* { 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);
+}
--- /dev/null
+/* { 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);
+}