public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH] sparc: Add scheduling information for LEON5
@ 2021-09-15  9:36 Daniel Cederman
  2021-09-15  9:36 ` [PATCH] sparc: Print out bit names for LEON and LEON3 with -mdebug Daniel Cederman
                   ` (5 more replies)
  0 siblings, 6 replies; 13+ messages in thread
From: Daniel Cederman @ 2021-09-15  9:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: daniel, ebotcazou

The LEON5 can often dual issue instructions from the same 64-bit aligned
double word if there are no data dependencies. Add scheduling information
to avoid scheduling unpairable instructions back-to-back.

gcc/ChangeLog:

        * config/sparc/sparc-opts.h (enum sparc_processor_type): Add LEON5
        * config/sparc/sparc.c (struct processor_costs): Add LEON5 costs
        (leon5_adjust_cost): Increase cost of store with data dependency
        on ALU instruction and FPU anti-dependencies.
        (sparc_option_override): Add LEON5 costs
        (sparc_adjust_cost): Add LEON5 cost adjustments
        * config/sparc/sparc.h: Add LEON5
        * config/sparc/sparc.md: Include LEON5 scheduling information
        * config/sparc/sparc.opt: Add LEON5
        * doc/invoke.texi: Add LEON5
        * config/sparc/leon5.md: New file.
---
 gcc/config/sparc/leon5.md     | 103 ++++++++++++++++++++++++++++++++++
 gcc/config/sparc/sparc-opts.h |   1 +
 gcc/config/sparc/sparc.c      |  84 +++++++++++++++++++++++++++
 gcc/config/sparc/sparc.h      |  36 ++++++------
 gcc/config/sparc/sparc.md     |   2 +
 gcc/config/sparc/sparc.opt    |   3 +
 gcc/doc/invoke.texi           |  13 +++--
 7 files changed, 220 insertions(+), 22 deletions(-)
 create mode 100644 gcc/config/sparc/leon5.md

diff --git a/gcc/config/sparc/leon5.md b/gcc/config/sparc/leon5.md
new file mode 100644
index 00000000000..3f72a9f53e0
--- /dev/null
+++ b/gcc/config/sparc/leon5.md
@@ -0,0 +1,103 @@
+;; Scheduling description for LEON5.
+;;   Copyright (C) 2021 Free Software Foundation, Inc.
+;;
+;; This file is part of GCC.
+;;
+;; GCC is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+;;
+;; GCC is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+;;
+;; You should have received a copy of the GNU General Public License
+;; along with GCC; see the file COPYING3.  If not see
+;; <http://www.gnu.org/licenses/>.
+
+
+;; The LEON5 can often dual issue instructions from the same 64-bit aligned
+;; double word if there are no data dependencies.
+;;
+;; Avoid scheduling load/store, FPU, and multiplication instructions back to
+;; back, regardless of data dependencies.
+;;
+;; Push comparisons away from the associated branch instruction.
+;;
+;; Avoid scheduling ALU instructions with data dependencies back to back.
+;;
+;; Schedule three instructions between load and dependant instruction.
+
+(define_automaton "leon5")
+
+(define_cpu_unit "leon5_memory" "leon5")
+(define_cpu_unit "leon5_mul" "leon5")
+(define_cpu_unit "grfpu_d" "grfpu")
+(define_cpu_unit "grfpu_s" "grfpu")
+
+(define_insn_reservation "leon5_load" 4
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "load,sload"))
+  "leon5_memory * 2, nothing * 2")
+
+(define_insn_reservation "leon5_fpload" 2
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpload"))
+  "leon5_memory * 2 + grfpu_alu * 2")
+
+(define_insn_reservation "leon5_store" 2
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "store"))
+  "leon5_memory * 2")
+
+(define_insn_reservation "leon5_fpstore" 2
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpstore"))
+  "leon5_memory * 2 + grfpu_alu * 2")
+
+(define_insn_reservation "leon5_ialu" 2
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "ialu, shift, ialuX"))
+  "nothing * 2")
+
+(define_insn_reservation "leon5_compare" 5
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "compare"))
+  "nothing * 5")
+
+(define_insn_reservation "leon5_imul" 4
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "imul"))
+  "leon5_mul * 2, nothing * 2")
+
+(define_insn_reservation "leon5_idiv" 35
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "imul"))
+  "nothing * 35")
+
+(define_insn_reservation "leon5_fp_alu" 5
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fp,fpcmp,fpmul,fpmove"))
+  "grfpu_alu * 2, nothing*3")
+
+(define_insn_reservation "leon5_fp_divs" 17
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpdivs"))
+  "grfpu_alu * 2 + grfpu_d*16, nothing")
+
+(define_insn_reservation "leon5_fp_divd" 18
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpdivd"))
+  "grfpu_alu * 2 + grfpu_d*17, nothing")
+
+(define_insn_reservation "leon5_fp_sqrts" 25
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpsqrts"))
+  "grfpu_alu * 2 + grfpu_s*24, nothing")
+
+(define_insn_reservation "leon5_fp_sqrtd" 26
+  (and (eq_attr "cpu" "leon5")
+  (eq_attr "type" "fpsqrtd"))
+  "grfpu_alu * 2 + grfpu_s*25, nothing")
diff --git a/gcc/config/sparc/sparc-opts.h b/gcc/config/sparc/sparc-opts.h
index 1af556e1156..9299cf6a2ff 100644
--- a/gcc/config/sparc/sparc-opts.h
+++ b/gcc/config/sparc/sparc-opts.h
@@ -31,6 +31,7 @@ enum sparc_processor_type {
   PROCESSOR_HYPERSPARC,
   PROCESSOR_LEON,
   PROCESSOR_LEON3,
+  PROCESSOR_LEON5,
   PROCESSOR_LEON3V7,
   PROCESSOR_SPARCLITE,
   PROCESSOR_F930,
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 5177d48793d..607dcbbad39 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -269,6 +269,31 @@ struct processor_costs leon3_costs = {
   3 /* branch cost */
 };
 
+static const
+struct processor_costs leon5_costs = {
+  COSTS_N_INSNS (1), /* int load */
+  COSTS_N_INSNS (1), /* int signed load */
+  COSTS_N_INSNS (1), /* int zeroed load */
+  COSTS_N_INSNS (1), /* float load */
+  COSTS_N_INSNS (1), /* fmov, fneg, fabs */
+  COSTS_N_INSNS (1), /* fadd, fsub */
+  COSTS_N_INSNS (1), /* fcmp */
+  COSTS_N_INSNS (1), /* fmov, fmovr */
+  COSTS_N_INSNS (1), /* fmul */
+  COSTS_N_INSNS (17), /* fdivs */
+  COSTS_N_INSNS (18), /* fdivd */
+  COSTS_N_INSNS (25), /* fsqrts */
+  COSTS_N_INSNS (26), /* fsqrtd */
+  COSTS_N_INSNS (4), /* imul */
+  COSTS_N_INSNS (4), /* imulX */
+  0, /* imul bit factor */
+  COSTS_N_INSNS (35), /* idiv */
+  COSTS_N_INSNS (35), /* idivX */
+  COSTS_N_INSNS (1), /* movcc/movr */
+  0, /* shift penalty */
+  3 /* branch cost */
+};
+
 static const
 struct processor_costs sparclet_costs = {
   COSTS_N_INSNS (3), /* int load */
@@ -575,6 +600,7 @@ static int function_arg_slotno (const CUMULATIVE_ARGS *, machine_mode,
 
 static int supersparc_adjust_cost (rtx_insn *, int, rtx_insn *, int);
 static int hypersparc_adjust_cost (rtx_insn *, int, rtx_insn *, int);
+static int leon5_adjust_cost (rtx_insn *, int, rtx_insn *, int);
 
 static void sparc_emit_set_const32 (rtx, rtx);
 static void sparc_emit_set_const64 (rtx, rtx);
@@ -1677,6 +1703,7 @@ sparc_option_override (void)
     { TARGET_CPU_hypersparc, PROCESSOR_HYPERSPARC },
     { TARGET_CPU_leon, PROCESSOR_LEON },
     { TARGET_CPU_leon3, PROCESSOR_LEON3 },
+    { TARGET_CPU_leon5, PROCESSOR_LEON5 },
     { TARGET_CPU_leon3v7, PROCESSOR_LEON3V7 },
     { TARGET_CPU_sparclite, PROCESSOR_F930 },
     { TARGET_CPU_sparclite86x, PROCESSOR_SPARCLITE86X },
@@ -1708,6 +1735,7 @@ sparc_option_override (void)
     { "hypersparc",	MASK_ISA, MASK_V8 },
     { "leon",		MASK_ISA|MASK_FSMULD, MASK_V8|MASK_LEON },
     { "leon3",		MASK_ISA, MASK_V8|MASK_LEON3 },
+    { "leon5",		MASK_ISA, MASK_V8|MASK_LEON3 },
     { "leon3v7",	MASK_ISA, MASK_LEON3 },
     { "sparclite",	MASK_ISA, MASK_SPARCLITE },
     /* The Fujitsu MB86930 is the original sparclite chip, with no FPU.  */
@@ -2018,6 +2046,9 @@ sparc_option_override (void)
     case PROCESSOR_LEON3V7:
       sparc_costs = &leon3_costs;
       break;
+    case PROCESSOR_LEON5:
+      sparc_costs = &leon5_costs;
+      break;
     case PROCESSOR_SPARCLET:
     case PROCESSOR_TSC701:
       sparc_costs = &sparclet_costs;
@@ -10164,12 +10195,65 @@ hypersparc_adjust_cost (rtx_insn *insn, int dtype, rtx_insn *dep_insn,
   return cost;
 }
 
+static int
+leon5_adjust_cost (rtx_insn *insn, int dtype, rtx_insn *dep_insn,
+		   int cost)
+{
+  enum attr_type insn_type, dep_type;
+  rtx pat = PATTERN (insn);
+  rtx dep_pat = PATTERN (dep_insn);
+
+  if (recog_memoized (insn) < 0 || recog_memoized (dep_insn) < 0)
+    return cost;
+
+  insn_type = get_attr_type (insn);
+  dep_type = get_attr_type (dep_insn);
+
+  switch (dtype)
+    {
+    case REG_DEP_TRUE:
+      /* Data dependency; DEP_INSN writes a register that INSN reads some
+	 cycles later.  */
+
+      switch (insn_type)
+	{
+	case TYPE_STORE:
+	  /* Try to schedule three instructions between the store and
+	     the ALU instruction that generated the data.  */
+	  if (dep_type == TYPE_IALU || dep_type == TYPE_SHIFT)
+	    {
+	      if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
+		break;
+
+	      if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
+		return 4;
+	    }
+	  break;
+	default:
+	  break;
+	}
+      break;
+    case REG_DEP_ANTI:
+      /* Penalize anti-dependencies for FPU instructions.  */
+      if (fpop_insn_p (insn) || insn_type == TYPE_FPLOAD)
+	return 4;
+      break;
+    default:
+      break;
+    }
+
+  return cost;
+}
+
 static int
 sparc_adjust_cost (rtx_insn *insn, int dep_type, rtx_insn *dep, int cost,
 		   unsigned int)
 {
   switch (sparc_cpu)
     {
+    case PROCESSOR_LEON5:
+      cost = leon5_adjust_cost (insn, dep_type, dep, cost);
+      break;
     case PROCESSOR_SUPERSPARC:
       cost = supersparc_adjust_cost (insn, dep_type, dep, cost);
       break;
diff --git a/gcc/config/sparc/sparc.h b/gcc/config/sparc/sparc.h
index 4da5a06df2f..edafa998370 100644
--- a/gcc/config/sparc/sparc.h
+++ b/gcc/config/sparc/sparc.h
@@ -120,21 +120,22 @@ along with GCC; see the file COPYING3.  If not see
 #define TARGET_CPU_leon		4
 #define TARGET_CPU_leon3	5
 #define TARGET_CPU_leon3v7	6
-#define TARGET_CPU_sparclite	7
-#define TARGET_CPU_f930		7       /* alias */
-#define TARGET_CPU_f934		7       /* alias */
-#define TARGET_CPU_sparclite86x	8
-#define TARGET_CPU_sparclet	9
-#define TARGET_CPU_tsc701	9       /* alias */
-#define TARGET_CPU_v9		10	/* generic v9 implementation */
-#define TARGET_CPU_sparcv9	10	/* alias */
-#define TARGET_CPU_sparc64	10	/* alias */
-#define TARGET_CPU_ultrasparc	11
-#define TARGET_CPU_ultrasparc3	12
-#define TARGET_CPU_niagara	13
-#define TARGET_CPU_niagara2	14
-#define TARGET_CPU_niagara3	15
-#define TARGET_CPU_niagara4	16
+#define TARGET_CPU_leon5	7
+#define TARGET_CPU_sparclite	8
+#define TARGET_CPU_f930		8       /* alias */
+#define TARGET_CPU_f934		8       /* alias */
+#define TARGET_CPU_sparclite86x	9
+#define TARGET_CPU_sparclet	10
+#define TARGET_CPU_tsc701	10       /* alias */
+#define TARGET_CPU_v9		11	/* generic v9 implementation */
+#define TARGET_CPU_sparcv9	11	/* alias */
+#define TARGET_CPU_sparc64	11	/* alias */
+#define TARGET_CPU_ultrasparc	12
+#define TARGET_CPU_ultrasparc3	13
+#define TARGET_CPU_niagara	14
+#define TARGET_CPU_niagara2	15
+#define TARGET_CPU_niagara3	16
+#define TARGET_CPU_niagara4	17
 #define TARGET_CPU_niagara7	19
 #define TARGET_CPU_m8		20
 
@@ -229,7 +230,8 @@ along with GCC; see the file COPYING3.  If not see
 #endif
 
 #if TARGET_CPU_DEFAULT == TARGET_CPU_leon \
- || TARGET_CPU_DEFAULT == TARGET_CPU_leon3
+ || TARGET_CPU_DEFAULT == TARGET_CPU_leon3 \
+ || TARGET_CPU_DEFAULT == TARGET_CPU_leon5
 #define CPP_CPU32_DEFAULT_SPEC "-D__leon__ -D__sparc_v8__"
 #define ASM_CPU32_DEFAULT_SPEC AS_LEON_FLAG
 #endif
@@ -285,6 +287,7 @@ along with GCC; see the file COPYING3.  If not see
 %{mcpu=hypersparc:-D__hypersparc__ -D__sparc_v8__} \
 %{mcpu=leon:-D__leon__ -D__sparc_v8__} \
 %{mcpu=leon3:-D__leon__ -D__sparc_v8__} \
+%{mcpu=leon5:-D__leon__ -D__sparc_v8__} \
 %{mcpu=leon3v7:-D__leon__} \
 %{mcpu=v9:-D__sparc_v9__} \
 %{mcpu=ultrasparc:-D__sparc_v9__} \
@@ -337,6 +340,7 @@ along with GCC; see the file COPYING3.  If not see
 %{mcpu=hypersparc:-Av8} \
 %{mcpu=leon:" AS_LEON_FLAG "} \
 %{mcpu=leon3:" AS_LEON_FLAG "} \
+%{mcpu=leon5:" AS_LEON_FLAG "} \
 %{mcpu=leon3v7:" AS_LEONV7_FLAG "} \
 %{mv8plus:-Av8plus} \
 %{mcpu=v9:-Av9} \
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 3ac074a244d..294c918f660 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -233,6 +233,7 @@
    hypersparc,
    leon,
    leon3,
+   leon5,
    leon3v7,
    sparclite,
    f930,
@@ -638,6 +639,7 @@
 (include "supersparc.md")
 (include "hypersparc.md")
 (include "leon.md")
+(include "leon5.md")
 (include "sparclet.md")
 (include "ultra1_2.md")
 (include "ultra3.md")
diff --git a/gcc/config/sparc/sparc.opt b/gcc/config/sparc/sparc.opt
index fb792676667..658a187f862 100644
--- a/gcc/config/sparc/sparc.opt
+++ b/gcc/config/sparc/sparc.opt
@@ -175,6 +175,9 @@ Enum(sparc_processor) String(leon3) Value(PROCESSOR_LEON3)
 EnumValue
 Enum(sparc_processor) String(leon3v7) Value(PROCESSOR_LEON3V7)
 
+EnumValue
+Enum(sparc_processor) String(leon5) Value(PROCESSOR_LEON5)
+
 EnumValue
 Enum(sparc_processor) String(sparclite) Value(PROCESSOR_SPARCLITE)
 
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 78cfc100ac2..4acb94181d2 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -29662,10 +29662,11 @@ so @option{-mno-lra} needs to be passed to get old Reload.
 Set the instruction set, register set, and instruction scheduling parameters
 for machine type @var{cpu_type}.  Supported values for @var{cpu_type} are
 @samp{v7}, @samp{cypress}, @samp{v8}, @samp{supersparc}, @samp{hypersparc},
-@samp{leon}, @samp{leon3}, @samp{leon3v7}, @samp{sparclite}, @samp{f930},
-@samp{f934}, @samp{sparclite86x}, @samp{sparclet}, @samp{tsc701}, @samp{v9},
-@samp{ultrasparc}, @samp{ultrasparc3}, @samp{niagara}, @samp{niagara2},
-@samp{niagara3}, @samp{niagara4}, @samp{niagara7} and @samp{m8}.
+@samp{leon}, @samp{leon3}, @samp{leon3v7}, @samp{leon5}, @samp{sparclite},
+@samp{f930}, @samp{f934}, @samp{sparclite86x}, @samp{sparclet}, @samp{tsc701},
+@samp{v9}, @samp{ultrasparc}, @samp{ultrasparc3}, @samp{niagara},
+@samp{niagara2}, @samp{niagara3}, @samp{niagara4}, @samp{niagara7} and
+@samp{m8}.
 
 Native Solaris and GNU/Linux toolchains also support the value @samp{native},
 which selects the best architecture option for the host processor.
@@ -29684,7 +29685,7 @@ implementations.
 cypress, leon3v7
 
 @item v8
-supersparc, hypersparc, leon, leon3
+supersparc, hypersparc, leon, leon3, leon5
 
 @item sparclite
 f930, f934, sparclite86x
@@ -29751,7 +29752,7 @@ The same values for @option{-mcpu=@var{cpu_type}} can be used for
 @option{-mtune=@var{cpu_type}}, but the only useful values are those
 that select a particular CPU implementation.  Those are
 @samp{cypress}, @samp{supersparc}, @samp{hypersparc}, @samp{leon},
-@samp{leon3}, @samp{leon3v7}, @samp{f930}, @samp{f934},
+@samp{leon3}, @samp{leon3v7}, @samp{leon5}, @samp{f930}, @samp{f934},
 @samp{sparclite86x}, @samp{tsc701}, @samp{ultrasparc},
 @samp{ultrasparc3}, @samp{niagara}, @samp{niagara2}, @samp{niagara3},
 @samp{niagara4}, @samp{niagara7} and @samp{m8}.  With native Solaris
-- 
2.25.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH] sparc: Print out bit names for LEON and LEON3 with -mdebug
  2021-09-15  9:36 [PATCH] sparc: Add scheduling information for LEON5 Daniel Cederman
@ 2021-09-15  9:36 ` Daniel Cederman
  2021-09-15 10:19   ` Eric Botcazou
  2021-09-15  9:36 ` [PATCH 1/4] sparc: Treat more instructions as load or store in errata workarounds Daniel Cederman
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Daniel Cederman @ 2021-09-15  9:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: daniel, ebotcazou, Andreas Larsson

From: Andreas Larsson <andreas@gaisler.com>

gcc/ChangeLog:

        * config/sparc/sparc.c (dump_target_flag_bits): Print bit names for
        LEON and LEON3.
---
 gcc/config/sparc/sparc.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 06f41d7bb53..d5a0ff7d4ea 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1596,6 +1596,10 @@ dump_target_flag_bits (const int flags)
     fprintf (stderr, "CBCOND ");
   if (flags & MASK_DEPRECATED_V8_INSNS)
     fprintf (stderr, "DEPRECATED_V8_INSNS ");
+  if (flags & MASK_LEON)
+    fprintf (stderr, "LEON ");
+  if (flags & MASK_LEON3)
+    fprintf (stderr, "LEON3 ");
   if (flags & MASK_SPARCLET)
     fprintf (stderr, "SPARCLET ");
   if (flags & MASK_SPARCLITE)
-- 
2.25.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 1/4] sparc: Treat more instructions as load or store in errata workarounds
  2021-09-15  9:36 [PATCH] sparc: Add scheduling information for LEON5 Daniel Cederman
  2021-09-15  9:36 ` [PATCH] sparc: Print out bit names for LEON and LEON3 with -mdebug Daniel Cederman
@ 2021-09-15  9:36 ` Daniel Cederman
  2021-09-15 10:23   ` Eric Botcazou
  2021-09-15  9:36 ` [PATCH 2/4] sparc: Skip all empty assembly statements Daniel Cederman
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Daniel Cederman @ 2021-09-15  9:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: daniel, ebotcazou

Check the attribute of instruction to determine if it performs a store
or load operation. This more generic approach sees the last instruction
in the GOTdata_op model as a potential load and treats the memory barrier
as a potential store instruction.

gcc/ChangeLog:

        * config/sparc/sparc.c (store_insn_p): Add predicate for store
        attributes.
        (load_insn_p): Add predicate for load attributes.
        (sparc_do_work_around_errata): Use new predicates.
---
 gcc/config/sparc/sparc.c | 37 +++++++++++++++++++++++++++++--------
 1 file changed, 29 insertions(+), 8 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index d5a0ff7d4ea..fa78e0dc739 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1045,6 +1045,31 @@ atomic_insn_for_leon3_p (rtx_insn *insn)
     }
 }
 
+/* True if INSN is a store instruction.  */
+
+static bool
+store_insn_p (rtx_insn *insn)
+{
+   if (GET_CODE (PATTERN (insn)) != SET)
+    return false;
+
+   return (get_attr_type (insn) == TYPE_STORE)
+     || (get_attr_type (insn) == TYPE_FPSTORE);
+}
+
+/* True if INSN is a load instruction.  */
+
+static bool
+load_insn_p (rtx_insn *insn)
+{
+   if (GET_CODE (PATTERN (insn)) != SET)
+    return false;
+
+   return (get_attr_type (insn) == TYPE_LOAD)
+     || (get_attr_type (insn) == TYPE_SLOAD)
+     || (get_attr_type (insn) == TYPE_FPLOAD);
+}
+
 /* We use a machine specific pass to enable workarounds for errata.
 
    We need to have the (essentially) final form of the insn stream in order
@@ -1105,9 +1130,7 @@ sparc_do_work_around_errata (void)
 	 instruction at branch target.  */
       if (sparc_fix_ut700
 	  && NONJUMP_INSN_P (insn)
-	  && (set = single_set (insn)) != NULL_RTX
-	  && mem_ref (SET_SRC (set))
-	  && REG_P (SET_DEST (set)))
+	  && load_insn_p (insn))
 	{
 	  if (jump && jump_to_label_p (jump))
 	    {
@@ -1212,7 +1235,7 @@ sparc_do_work_around_errata (void)
       if (sparc_fix_b2bst
 	  && NONJUMP_INSN_P (insn)
 	  && (set = single_set (insn)) != NULL_RTX
-	  && MEM_P (SET_DEST (set)))
+	  && store_insn_p (insn))
 	{
 	  /* Sequence B begins with a double-word store.  */
 	  bool seq_b = GET_MODE_SIZE (GET_MODE (SET_DEST (set))) == 8;
@@ -1245,8 +1268,7 @@ sparc_do_work_around_errata (void)
 	      if (seq_b)
 		{
 		  /* Add NOP if followed by a store.  */
-		  if ((set = single_set (after)) != NULL_RTX
-		      && MEM_P (SET_DEST (set)))
+		  if (store_insn_p (after))
 		    insert_nop = true;
 
 		  /* Otherwise it is ok.  */
@@ -1268,8 +1290,7 @@ sparc_do_work_around_errata (void)
 
 	      /* Add NOP if third instruction is a store.  */
 	      if (i == 1
-		  && (set = single_set (after)) != NULL_RTX
-		  && MEM_P (SET_DEST (set)))
+		  && store_insn_p (after))
 		insert_nop = true;
 	    }
 	}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 2/4] sparc: Skip all empty assembly statements
  2021-09-15  9:36 [PATCH] sparc: Add scheduling information for LEON5 Daniel Cederman
  2021-09-15  9:36 ` [PATCH] sparc: Print out bit names for LEON and LEON3 with -mdebug Daniel Cederman
  2021-09-15  9:36 ` [PATCH 1/4] sparc: Treat more instructions as load or store in errata workarounds Daniel Cederman
@ 2021-09-15  9:36 ` Daniel Cederman
  2021-09-15 10:31   ` Eric Botcazou
  2021-09-15  9:36 ` [PATCH 3/4] sparc: Prevent atomic instructions in beginning of functions for UT700 Daniel Cederman
                   ` (2 subsequent siblings)
  5 siblings, 1 reply; 13+ messages in thread
From: Daniel Cederman @ 2021-09-15  9:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: daniel, ebotcazou

This version detects multiple empty assembly statements in a row and also
detects non-memory barrier empty assembly statements (__asm__("")). It
can be used instead of next_active_insn().

gcc/ChangeLog:

        * config/sparc/sparc.c (next_active_non_empty_insn): New function
        that returns next active non empty assembly instruction.
        (sparc_do_work_around_errata): Use new function.
---
 gcc/config/sparc/sparc.c | 37 +++++++++++++++++++++++--------------
 1 file changed, 23 insertions(+), 14 deletions(-)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index fa78e0dc739..b087c5b3fc8 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1082,6 +1082,26 @@ load_insn_p (rtx_insn *insn)
    && GET_CODE (PATTERN (INSN)) != USE					\
    && GET_CODE (PATTERN (INSN)) != CLOBBER)
 
+rtx_insn *
+next_active_non_empty_insn (rtx_insn *insn)
+{
+  insn = next_active_insn (insn);
+
+  while (insn
+	 && ((GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE)
+	     || (GET_CODE (PATTERN (insn)) == ASM_INPUT)
+	     || (USEFUL_INSN_P (insn)
+		 && (asm_noperands (PATTERN (insn))>=0)
+		 && !strcmp (decode_asm_operands (PATTERN (insn),
+						  NULL, NULL, NULL,
+						  NULL, NULL), ""))))
+    {
+      insn = next_active_insn (insn);
+    }
+
+  return insn;
+}
+
 static unsigned int
 sparc_do_work_around_errata (void)
 {
@@ -1139,7 +1159,7 @@ sparc_do_work_around_errata (void)
 		emit_insn_before (gen_nop (), target);
 	    }
 
-	  next = next_active_insn (insn);
+	  next = next_active_non_empty_insn (insn);
 	  if (!next)
 	    break;
 
@@ -1242,23 +1262,12 @@ sparc_do_work_around_errata (void)
 	  rtx_insn *after;
 	  int i;
 
-	  next = next_active_insn (insn);
+	  next = next_active_non_empty_insn (insn);
 	  if (!next)
 	    break;
 
 	  for (after = next, i = 0; i < 2; i++)
 	    {
-	      /* Skip empty assembly statements.  */
-	      if ((GET_CODE (PATTERN (after)) == UNSPEC_VOLATILE)
-		  || (USEFUL_INSN_P (after)
-		      && (asm_noperands (PATTERN (after))>=0)
-		      && !strcmp (decode_asm_operands (PATTERN (after),
-						       NULL, NULL, NULL,
-						       NULL, NULL), "")))
-		after = next_active_insn (after);
-	      if (!after)
-		break;
-
 	      /* If the insn is a branch, then it cannot be problematic.  */
 	      if (!NONJUMP_INSN_P (after)
 		  || GET_CODE (PATTERN (after)) == SEQUENCE)
@@ -1283,7 +1292,7 @@ sparc_do_work_around_errata (void)
 		      && (MEM_P (SET_DEST (set)) || mem_ref (SET_SRC (set))))
 		    break;
 
-		  after = next_active_insn (after);
+		  after = next_active_non_empty_insn (after);
 		  if (!after)
 		    break;
 		}
-- 
2.25.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 3/4] sparc: Prevent atomic instructions in beginning of functions for UT700
  2021-09-15  9:36 [PATCH] sparc: Add scheduling information for LEON5 Daniel Cederman
                   ` (2 preceding siblings ...)
  2021-09-15  9:36 ` [PATCH 2/4] sparc: Skip all empty assembly statements Daniel Cederman
@ 2021-09-15  9:36 ` Daniel Cederman
  2021-09-15 10:32   ` Eric Botcazou
  2021-09-15  9:36 ` [PATCH 4/4] sparc: Add NOP in stack_protect_setsi if sparc_fix_b2bst enabled Daniel Cederman
  2021-09-15 10:18 ` [PATCH] sparc: Add scheduling information for LEON5 Eric Botcazou
  5 siblings, 1 reply; 13+ messages in thread
From: Daniel Cederman @ 2021-09-15  9:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: daniel, ebotcazou

A call to the function might have a load instruction in the delay slot
and a load followed by an atomic function could cause a deadlock.

gcc/ChangeLog:

        * config/sparc/sparc.c (sparc_do_work_around_errata): Do not begin
        functions with atomic instruction in the UT700 errata workaround.
---
 gcc/config/sparc/sparc.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index b087c5b3fc8..5177d48793d 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1106,6 +1106,7 @@ static unsigned int
 sparc_do_work_around_errata (void)
 {
   rtx_insn *insn, *next;
+  bool find_first_useful = true;
 
   /* Force all instructions to be split into their final form.  */
   split_all_insns_noflow ();
@@ -1130,6 +1131,16 @@ sparc_do_work_around_errata (void)
       else
 	jump = NULL;
 
+      /* Do not begin function with atomic instruction.  */
+      if (sparc_fix_ut700
+	  && find_first_useful
+	  && USEFUL_INSN_P (insn))
+	{
+	  find_first_useful = false;
+	  if (atomic_insn_for_leon3_p (insn))
+	    emit_insn_before (gen_nop (), insn);
+	}
+
       /* Place a NOP at the branch target of an integer branch if it is a
 	 floating-point operation or a floating-point branch.  */
       if (sparc_fix_gr712rc
-- 
2.25.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* [PATCH 4/4] sparc: Add NOP in stack_protect_setsi if sparc_fix_b2bst enabled
  2021-09-15  9:36 [PATCH] sparc: Add scheduling information for LEON5 Daniel Cederman
                   ` (3 preceding siblings ...)
  2021-09-15  9:36 ` [PATCH 3/4] sparc: Prevent atomic instructions in beginning of functions for UT700 Daniel Cederman
@ 2021-09-15  9:36 ` Daniel Cederman
  2021-09-15 10:37   ` Eric Botcazou
  2021-09-15 10:18 ` [PATCH] sparc: Add scheduling information for LEON5 Eric Botcazou
  5 siblings, 1 reply; 13+ messages in thread
From: Daniel Cederman @ 2021-09-15  9:36 UTC (permalink / raw)
  To: gcc-patches; +Cc: daniel, ebotcazou

This is needed to prevent the Store -> (Non-store or load) -> Store
sequence.

gcc/ChangeLog:

        * config/sparc/sparc.md: Add NOP to prevent sensitive sequence for
        B2BST errata workaround.
---
 gcc/config/sparc/sparc.md | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 24b76e0cacd..3ac074a244d 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -8353,9 +8353,15 @@ visl")
 	(unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
    (set (match_scratch:SI 2 "=&r") (const_int 0))]
   "TARGET_ARCH32"
-  "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2"
+{
+  if (sparc_fix_b2bst)
+    return "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2\;nop";
+  else
+    return "ld\t%1, %2\;st\t%2, %0\;mov\t0, %2";
+}
   [(set_attr "type" "multi")
-   (set_attr "length" "3")])
+   (set (attr "length") (if_then_else (eq_attr "fix_b2bst" "true")
+		      (const_int 4) (const_int 3)))])
 
 (define_insn "stack_protect_set64"
   [(set (match_operand:DI 0 "memory_operand" "=m")
-- 
2.25.1


^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] sparc: Add scheduling information for LEON5
  2021-09-15  9:36 [PATCH] sparc: Add scheduling information for LEON5 Daniel Cederman
                   ` (4 preceding siblings ...)
  2021-09-15  9:36 ` [PATCH 4/4] sparc: Add NOP in stack_protect_setsi if sparc_fix_b2bst enabled Daniel Cederman
@ 2021-09-15 10:18 ` Eric Botcazou
  2021-09-15 11:04   ` Daniel Cederman
  5 siblings, 1 reply; 13+ messages in thread
From: Eric Botcazou @ 2021-09-15 10:18 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, daniel

> The LEON5 can often dual issue instructions from the same 64-bit aligned
> double word if there are no data dependencies. Add scheduling information
> to avoid scheduling unpairable instructions back-to-back.
> 
> gcc/ChangeLog:
> 
>         * config/sparc/sparc-opts.h (enum sparc_processor_type): Add LEON5
>         * config/sparc/sparc.c (struct processor_costs): Add LEON5 costs
>         (leon5_adjust_cost): Increase cost of store with data dependency
>         on ALU instruction and FPU anti-dependencies.
>         (sparc_option_override): Add LEON5 costs
>         (sparc_adjust_cost): Add LEON5 cost adjustments
>         * config/sparc/sparc.h: Add LEON5
>         * config/sparc/sparc.md: Include LEON5 scheduling information
>         * config/sparc/sparc.opt: Add LEON5
>         * doc/invoke.texi: Add LEON5
>         * config/sparc/leon5.md: New file.

OK for whatever branches you deem relevant, modulo a couple of nits:

> +;; Avoid scheduling load/store, FPU, and multiplication instructions back

and multiply instructions

> +;; Schedule three instructions between load and dependant instruction.

dependent

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] sparc: Print out bit names for LEON and LEON3 with -mdebug
  2021-09-15  9:36 ` [PATCH] sparc: Print out bit names for LEON and LEON3 with -mdebug Daniel Cederman
@ 2021-09-15 10:19   ` Eric Botcazou
  0 siblings, 0 replies; 13+ messages in thread
From: Eric Botcazou @ 2021-09-15 10:19 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, daniel, Andreas Larsson

> gcc/ChangeLog:
> 
>         * config/sparc/sparc.c (dump_target_flag_bits): Print bit names for
>         LEON and LEON3.

OK everywhere.

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 1/4] sparc: Treat more instructions as load or store in errata workarounds
  2021-09-15  9:36 ` [PATCH 1/4] sparc: Treat more instructions as load or store in errata workarounds Daniel Cederman
@ 2021-09-15 10:23   ` Eric Botcazou
  0 siblings, 0 replies; 13+ messages in thread
From: Eric Botcazou @ 2021-09-15 10:23 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, daniel

> gcc/ChangeLog:
> 
>         * config/sparc/sparc.c (store_insn_p): Add predicate for store
>         attributes.
>         (load_insn_p): Add predicate for load attributes.
>         (sparc_do_work_around_errata): Use new predicates.

OK everywhere on principle, but can we avoid the multiple calls to 
get_attr_type?  See div_sqrt_insn_p and fpop_insn_p for a model.

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 2/4] sparc: Skip all empty assembly statements
  2021-09-15  9:36 ` [PATCH 2/4] sparc: Skip all empty assembly statements Daniel Cederman
@ 2021-09-15 10:31   ` Eric Botcazou
  0 siblings, 0 replies; 13+ messages in thread
From: Eric Botcazou @ 2021-09-15 10:31 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, daniel

> gcc/ChangeLog:
> 
>         * config/sparc/sparc.c (next_active_non_empty_insn): New function
>         that returns next active non empty assembly instruction.
>         (sparc_do_work_around_errata): Use new function.

OK everywhere, modulo a couple of nits:

> +rtx_insn *
> +next_active_non_empty_insn (rtx_insn *insn)
> +{
> +  insn = next_active_insn (insn);
> +
> +  while (insn
> +	 && ((GET_CODE (PATTERN (insn)) == UNSPEC_VOLATILE)

Superfluous parentheses 

> +	     || (GET_CODE (PATTERN (insn)) == ASM_INPUT)

Likewise.

> +	     || (USEFUL_INSN_P (insn)
> +		 && (asm_noperands (PATTERN (insn))>=0)

Missing spaces around >=

> +    {
> +      insn = next_active_insn (insn);
> +    }

Superfluous curly braces, even for readability.

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 3/4] sparc: Prevent atomic instructions in beginning of functions for UT700
  2021-09-15  9:36 ` [PATCH 3/4] sparc: Prevent atomic instructions in beginning of functions for UT700 Daniel Cederman
@ 2021-09-15 10:32   ` Eric Botcazou
  0 siblings, 0 replies; 13+ messages in thread
From: Eric Botcazou @ 2021-09-15 10:32 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, daniel

> gcc/ChangeLog:
> 
>         * config/sparc/sparc.c (sparc_do_work_around_errata): Do not begin
>         functions with atomic instruction in the UT700 errata workaround.

OK everywhere.

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH 4/4] sparc: Add NOP in stack_protect_setsi if sparc_fix_b2bst enabled
  2021-09-15  9:36 ` [PATCH 4/4] sparc: Add NOP in stack_protect_setsi if sparc_fix_b2bst enabled Daniel Cederman
@ 2021-09-15 10:37   ` Eric Botcazou
  0 siblings, 0 replies; 13+ messages in thread
From: Eric Botcazou @ 2021-09-15 10:37 UTC (permalink / raw)
  To: Daniel Cederman; +Cc: gcc-patches, daniel

> gcc/ChangeLog:
> 
>         * config/sparc/sparc.md: Add NOP to prevent sensitive sequence for
>         B2BST errata workaround.

OK everywhere, but the ChangeLog entry should be:

	* config/sparc/sparc.md (stack_protect_set32): Add NOP...

Note that it's stack_protect_set32 on mainline and stack_protect_setsi before.

-- 
Eric Botcazou



^ permalink raw reply	[flat|nested] 13+ messages in thread

* Re: [PATCH] sparc: Add scheduling information for LEON5
  2021-09-15 10:18 ` [PATCH] sparc: Add scheduling information for LEON5 Eric Botcazou
@ 2021-09-15 11:04   ` Daniel Cederman
  0 siblings, 0 replies; 13+ messages in thread
From: Daniel Cederman @ 2021-09-15 11:04 UTC (permalink / raw)
  To: Eric Botcazou; +Cc: gcc-patches, daniel

Thank you for reviewing the patches! I will address your comments and 
push the patches after testing.

Thanks again,
Daniel

On 2021-09-15 12:18, Eric Botcazou wrote:
>> The LEON5 can often dual issue instructions from the same 64-bit aligned
>> double word if there are no data dependencies. Add scheduling information
>> to avoid scheduling unpairable instructions back-to-back.
>>
>> gcc/ChangeLog:
>>
>>          * config/sparc/sparc-opts.h (enum sparc_processor_type): Add LEON5
>>          * config/sparc/sparc.c (struct processor_costs): Add LEON5 costs
>>          (leon5_adjust_cost): Increase cost of store with data dependency
>>          on ALU instruction and FPU anti-dependencies.
>>          (sparc_option_override): Add LEON5 costs
>>          (sparc_adjust_cost): Add LEON5 cost adjustments
>>          * config/sparc/sparc.h: Add LEON5
>>          * config/sparc/sparc.md: Include LEON5 scheduling information
>>          * config/sparc/sparc.opt: Add LEON5
>>          * doc/invoke.texi: Add LEON5
>>          * config/sparc/leon5.md: New file.
> OK for whatever branches you deem relevant, modulo a couple of nits:
>
>> +;; Avoid scheduling load/store, FPU, and multiplication instructions back
> and multiply instructions
>
>> +;; Schedule three instructions between load and dependant instruction.
> dependent
>

^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2021-09-15 11:04 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-09-15  9:36 [PATCH] sparc: Add scheduling information for LEON5 Daniel Cederman
2021-09-15  9:36 ` [PATCH] sparc: Print out bit names for LEON and LEON3 with -mdebug Daniel Cederman
2021-09-15 10:19   ` Eric Botcazou
2021-09-15  9:36 ` [PATCH 1/4] sparc: Treat more instructions as load or store in errata workarounds Daniel Cederman
2021-09-15 10:23   ` Eric Botcazou
2021-09-15  9:36 ` [PATCH 2/4] sparc: Skip all empty assembly statements Daniel Cederman
2021-09-15 10:31   ` Eric Botcazou
2021-09-15  9:36 ` [PATCH 3/4] sparc: Prevent atomic instructions in beginning of functions for UT700 Daniel Cederman
2021-09-15 10:32   ` Eric Botcazou
2021-09-15  9:36 ` [PATCH 4/4] sparc: Add NOP in stack_protect_setsi if sparc_fix_b2bst enabled Daniel Cederman
2021-09-15 10:37   ` Eric Botcazou
2021-09-15 10:18 ` [PATCH] sparc: Add scheduling information for LEON5 Eric Botcazou
2021-09-15 11:04   ` Daniel Cederman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).