diff options
author | Richard Sandiford <richard.sandiford@linaro.org> | 2018-01-03 21:43:28 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2018-01-03 21:43:28 +0000 |
commit | c6561a1af68d6439cedde6dc79d19eda9981a4be (patch) | |
tree | e7c537aa897178d8d89fe0a7d45e08bfb47cce28 /gcc/genmodes.c | |
parent | 6ce12f6a1647ec2831f3c5908ecf9c23ae191d02 (diff) | |
download | gcc-c6561a1af68d6439cedde6dc79d19eda9981a4be.zip gcc-c6561a1af68d6439cedde6dc79d19eda9981a4be.tar.gz gcc-c6561a1af68d6439cedde6dc79d19eda9981a4be.tar.bz2 |
Add support for adjusting the number of units in a mode
We already allow the target to change the size and alignment of a mode.
This patch does the same thing for the number of units, which is needed
to give command-line control of the SVE vector length.
2018-01-03 Richard Sandiford <richard.sandiford@linaro.org>
Alan Hayward <alan.hayward@arm.com>
David Sherwood <david.sherwood@arm.com>
gcc/
* machmode.h (mode_precision): Prefix with CONST_MODE_PRECISION.
(mode_nunits): Likewise CONST_MODE_NUNITS.
* machmode.def (ADJUST_NUNITS): Document.
* genmodes.c (mode_data::need_nunits_adj): New field.
(blank_mode): Update accordingly.
(adj_nunits): New variable.
(print_maybe_const_decl): Replace CATEGORY with a NEEDS_ADJ
parameter.
(emit_mode_size_inline): Set need_bytesize_adj for all modes
listed in adj_nunits.
(emit_mode_nunits_inline): Set need_nunits_adj for all modes
listed in adj_nunits. Don't emit case statements for such modes.
(emit_insn_modes_h): Emit definitions of CONST_MODE_NUNITS
and CONST_MODE_PRECISION. Make CONST_MODE_SIZE expand to
nothing if adj_nunits is nonnull.
(emit_mode_precision, emit_mode_nunits): Use print_maybe_const_decl.
(emit_mode_unit_size, emit_mode_base_align, emit_mode_ibit)
(emit_mode_fbit): Update use of print_maybe_const_decl.
(emit_move_size): Likewise. Treat the array as non-const
if adj_nunits.
(emit_mode_adjustments): Handle adj_nunits.
Co-Authored-By: Alan Hayward <alan.hayward@arm.com>
Co-Authored-By: David Sherwood <david.sherwood@arm.com>
From-SVN: r256204
Diffstat (limited to 'gcc/genmodes.c')
-rw-r--r-- | gcc/genmodes.c | 69 |
1 files changed, 52 insertions, 17 deletions
diff --git a/gcc/genmodes.c b/gcc/genmodes.c index 7d58865..c096434 100644 --- a/gcc/genmodes.c +++ b/gcc/genmodes.c @@ -72,7 +72,9 @@ struct mode_data unsigned int counter; /* Rank ordering of modes */ unsigned int ibit; /* the number of integral bits */ unsigned int fbit; /* the number of fractional bits */ - bool need_bytesize_adj; /* true if this mode need dynamic size + bool need_nunits_adj; /* true if this mode needs dynamic nunits + adjustment */ + bool need_bytesize_adj; /* true if this mode needs dynamic size adjustment */ unsigned int int_n; /* If nonzero, then __int<INT_N> will be defined */ }; @@ -85,7 +87,7 @@ static const struct mode_data blank_mode = { 0, "<unknown>", MAX_MODE_CLASS, -1U, -1U, -1U, -1U, 0, 0, 0, 0, 0, 0, - "<unknown>", 0, 0, 0, 0, false, 0 + "<unknown>", 0, 0, 0, 0, false, false, 0 }; static htab_t modes_by_name; @@ -103,6 +105,7 @@ struct mode_adjust unsigned int line; }; +static struct mode_adjust *adj_nunits; static struct mode_adjust *adj_bytesize; static struct mode_adjust *adj_alignment; static struct mode_adjust *adj_format; @@ -780,6 +783,7 @@ make_vector_mode (enum mode_class bclass, #define _ADD_ADJUST(A, M, X, C1, C2) \ new_adjust (#M, &adj_##A, #A, #X, MODE_##C1, MODE_##C2, __FILE__, __LINE__) +#define ADJUST_NUNITS(M, X) _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM) #define ADJUST_BYTESIZE(M, X) _ADD_ADJUST (bytesize, M, X, RANDOM, RANDOM) #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, RANDOM, RANDOM) #define ADJUST_FLOAT_FORMAT(M, X) _ADD_ADJUST (format, M, X, FLOAT, FLOAT) @@ -949,9 +953,9 @@ calc_wider_mode (void) #define print_decl(TYPE, NAME, ASIZE) \ puts ("\nconst " TYPE " " NAME "[" ASIZE "] =\n{"); -#define print_maybe_const_decl(TYPE, NAME, ASIZE, CATEGORY) \ +#define print_maybe_const_decl(TYPE, NAME, ASIZE, NEEDS_ADJ) \ printf ("\n" TYPE " " NAME "[" ASIZE "] = \n{\n", \ - adj_##CATEGORY ? "" : "const ") + NEEDS_ADJ ? "" : "const ") #define print_closer() puts ("};") @@ -1009,6 +1013,11 @@ emit_mode_size_inline (void) m->need_bytesize_adj = true; } + /* Changing the number of units by a factor of X also changes the size + by a factor of X. */ + for (mode_adjust *a = adj_nunits; a; a = a->next) + a->mode->need_bytesize_adj = true; + printf ("\ #ifdef __cplusplus\n\ inline __attribute__((__always_inline__))\n\ @@ -1021,7 +1030,7 @@ mode_size_inline (machine_mode mode)\n\ extern %spoly_uint16_pod mode_size[NUM_MACHINE_MODES];\n\ gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\ switch (mode)\n\ - {\n", adj_bytesize ? "" : "const "); + {\n", adj_nunits || adj_bytesize ? "" : "const "); for_all_modes (c, m) if (!m->need_bytesize_adj) @@ -1040,7 +1049,10 @@ emit_mode_nunits_inline (void) int c; struct mode_data *m; - puts ("\ + for (mode_adjust *a = adj_nunits; a; a = a->next) + a->mode->need_nunits_adj = true; + + printf ("\ #ifdef __cplusplus\n\ inline __attribute__((__always_inline__))\n\ #else\n\ @@ -1049,12 +1061,13 @@ extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\ poly_uint16\n\ mode_nunits_inline (machine_mode mode)\n\ {\n\ - extern poly_uint16_pod mode_nunits[NUM_MACHINE_MODES];\n\ + extern %spoly_uint16_pod mode_nunits[NUM_MACHINE_MODES];\n\ switch (mode)\n\ - {"); + {\n", adj_nunits ? "" : "const "); for_all_modes (c, m) - printf (" case E_%smode: return %u;\n", m->name, m->ncomponents); + if (!m->need_nunits_adj) + printf (" case E_%smode: return %u;\n", m->name, m->ncomponents); puts ("\ default: return mode_nunits[mode];\n\ @@ -1271,7 +1284,10 @@ enum machine_mode\n{"); };\n"); /* I can't think of a better idea, can you? */ - printf ("#define CONST_MODE_SIZE%s\n", adj_bytesize ? "" : " const"); + printf ("#define CONST_MODE_NUNITS%s\n", adj_nunits ? "" : " const"); + printf ("#define CONST_MODE_PRECISION%s\n", adj_nunits ? "" : " const"); + printf ("#define CONST_MODE_SIZE%s\n", + adj_bytesize || adj_nunits ? "" : " const"); printf ("#define CONST_MODE_UNIT_SIZE%s\n", adj_bytesize ? "" : " const"); printf ("#define CONST_MODE_BASE_ALIGN%s\n", adj_alignment ? "" : " const"); #if 0 /* disabled for backward compatibility, temporary */ @@ -1386,7 +1402,8 @@ emit_mode_precision (void) int c; struct mode_data *m; - print_decl ("poly_uint16_pod", "mode_precision", "NUM_MACHINE_MODES"); + print_maybe_const_decl ("%spoly_uint16_pod", "mode_precision", + "NUM_MACHINE_MODES", adj_nunits); for_all_modes (c, m) if (m->precision != (unsigned int)-1) @@ -1405,7 +1422,7 @@ emit_mode_size (void) struct mode_data *m; print_maybe_const_decl ("%spoly_uint16_pod", "mode_size", - "NUM_MACHINE_MODES", bytesize); + "NUM_MACHINE_MODES", adj_nunits || adj_bytesize); for_all_modes (c, m) tagged_printf ("{ %u" ZERO_COEFFS " }", m->bytesize, m->name); @@ -1419,7 +1436,8 @@ emit_mode_nunits (void) int c; struct mode_data *m; - print_decl ("poly_uint16_pod", "mode_nunits", "NUM_MACHINE_MODES"); + print_maybe_const_decl ("%spoly_uint16_pod", "mode_nunits", + "NUM_MACHINE_MODES", adj_nunits); for_all_modes (c, m) tagged_printf ("{ %u" ZERO_COEFFS " }", m->ncomponents, m->name); @@ -1557,7 +1575,7 @@ emit_mode_unit_size (void) struct mode_data *m; print_maybe_const_decl ("%sunsigned char", "mode_unit_size", - "NUM_MACHINE_MODES", bytesize); + "NUM_MACHINE_MODES", adj_bytesize); for_all_modes (c, m) tagged_printf ("%u", @@ -1598,7 +1616,7 @@ emit_mode_base_align (void) print_maybe_const_decl ("%sunsigned short", "mode_base_align", "NUM_MACHINE_MODES", - alignment); + adj_alignment); for_all_modes (c, m) tagged_printf ("%u", m->alignment, m->name); @@ -1679,6 +1697,23 @@ emit_mode_adjustments (void) \n poly_uint16 ps ATTRIBUTE_UNUSED;\n\ size_t s ATTRIBUTE_UNUSED;"); + for (a = adj_nunits; a; a = a->next) + { + m = a->mode; + printf ("\n" + " {\n" + " /* %s:%d */\n ps = %s;\n", + a->file, a->line, a->adjustment); + printf (" int old_factor = vector_element_size" + " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n", + m->name, m->name); + printf (" mode_precision[E_%smode] = ps * old_factor;\n", m->name); + printf (" mode_size[E_%smode] = exact_div (mode_precision[E_%smode]," + " BITS_PER_UNIT);\n", m->name, m->name); + printf (" mode_nunits[E_%smode] = ps;\n", m->name); + printf (" }\n"); + } + /* Size adjustments must be propagated to all containing modes. A size adjustment forces us to recalculate the alignment too. */ for (a = adj_bytesize; a; a = a->next) @@ -1819,7 +1854,7 @@ emit_mode_ibit (void) print_maybe_const_decl ("%sunsigned char", "mode_ibit", "NUM_MACHINE_MODES", - ibit); + adj_ibit); for_all_modes (c, m) tagged_printf ("%u", m->ibit, m->name); @@ -1837,7 +1872,7 @@ emit_mode_fbit (void) print_maybe_const_decl ("%sunsigned char", "mode_fbit", "NUM_MACHINE_MODES", - fbit); + adj_fbit); for_all_modes (c, m) tagged_printf ("%u", m->fbit, m->name); |