aboutsummaryrefslogtreecommitdiff
path: root/gcc/genmodes.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@linaro.org>2018-01-03 21:43:28 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2018-01-03 21:43:28 +0000
commitc6561a1af68d6439cedde6dc79d19eda9981a4be (patch)
treee7c537aa897178d8d89fe0a7d45e08bfb47cce28 /gcc/genmodes.c
parent6ce12f6a1647ec2831f3c5908ecf9c23ae191d02 (diff)
downloadgcc-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.c69
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);