* Add support for adjusting the number of units in a mode
@ 2017-10-25 15:58 Richard Sandiford
2017-11-08 22:47 ` Jeff Law
0 siblings, 1 reply; 4+ messages in thread
From: Richard Sandiford @ 2017-10-25 15:58 UTC (permalink / raw)
To: gcc-patches
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.
Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu,
on top of the poly_int series. I think I can approve this under the
gen* maintainership, so if there are no comments in the menatime,
I'll apply it if the prerequisites are approved.
Thanks,
Richard
2017-10-25 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.
Index: gcc/machmode.h
===================================================================
--- gcc/machmode.h 2017-10-25 16:50:35.628184659 +0100
+++ gcc/machmode.h 2017-10-25 16:55:00.469175980 +0100
@@ -23,9 +23,9 @@ #define HAVE_MACHINE_MODES
typedef opt_mode<machine_mode> opt_machine_mode;
extern CONST_MODE_SIZE poly_uint16_pod mode_size[NUM_MACHINE_MODES];
-extern const poly_uint16_pod mode_precision[NUM_MACHINE_MODES];
+extern CONST_MODE_PRECISION poly_uint16_pod mode_precision[NUM_MACHINE_MODES];
extern const unsigned char mode_inner[NUM_MACHINE_MODES];
-extern const poly_uint16_pod mode_nunits[NUM_MACHINE_MODES];
+extern CONST_MODE_NUNITS poly_uint16_pod mode_nunits[NUM_MACHINE_MODES];
extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];
extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];
extern const unsigned char mode_wider[NUM_MACHINE_MODES];
Index: gcc/machmode.def
===================================================================
--- gcc/machmode.def 2017-10-25 16:50:35.628184659 +0100
+++ gcc/machmode.def 2017-10-25 16:55:00.468176022 +0100
@@ -169,6 +169,12 @@ along with GCC; see the file COPYING3.
Unlike a FORMAT argument, if you are adjusting a float format
you must put an & in front of the name of each format structure.
+ ADJUST_NUNITS (MODE, EXPR);
+ Like the above, but set the number of nunits of MODE to EXPR.
+ This changes the size and precision of the mode in proportion
+ to the change in the number of units; for example, doubling
+ the number of units doubles the size and precision as well.
+
Note: If a mode is ever made which is more than 255 bytes wide,
machmode.h and genmodes.c will have to be changed to allocate
more space for the mode_size and mode_alignment arrays. */
Index: gcc/genmodes.c
===================================================================
--- gcc/genmodes.c 2017-10-25 16:50:35.627184698 +0100
+++ gcc/genmodes.c 2017-10-25 16:55:00.468176022 +0100
@@ -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;
@@ -786,6 +789,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)
@@ -955,9 +959,9 @@ #define tagged_printf(FMT, ARG, TAG) do
#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 ("};")
@@ -1015,6 +1019,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\
@@ -1027,7 +1036,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)
@@ -1046,7 +1055,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\
@@ -1055,12 +1067,13 @@ extern __inline__ __attribute__((__alway
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\
@@ -1277,7 +1290,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 */
@@ -1392,7 +1408,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)
@@ -1411,7 +1428,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);
@@ -1425,7 +1442,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);
@@ -1563,7 +1581,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",
@@ -1604,7 +1622,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);
@@ -1685,6 +1703,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)
@@ -1825,7 +1860,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);
@@ -1843,7 +1878,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);
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Add support for adjusting the number of units in a mode
2017-10-25 15:58 Add support for adjusting the number of units in a mode Richard Sandiford
@ 2017-11-08 22:47 ` Jeff Law
2017-11-09 11:14 ` Richard Sandiford
0 siblings, 1 reply; 4+ messages in thread
From: Jeff Law @ 2017-11-08 22:47 UTC (permalink / raw)
To: gcc-patches, richard.sandiford
On 10/25/2017 09:57 AM, Richard Sandiford wrote:
> 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.
>
> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu,
> on top of the poly_int series. I think I can approve this under the
> gen* maintainership, so if there are no comments in the menatime,
> I'll apply it if the prerequisites are approved.
>
> Thanks,
> Richard
>
>
> 2017-10-25 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.
Were all the prereqs here approved? Or does this depend on the poly_int
stuff?
jeff
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Add support for adjusting the number of units in a mode
2017-11-08 22:47 ` Jeff Law
@ 2017-11-09 11:14 ` Richard Sandiford
2017-11-19 23:54 ` Jeff Law
0 siblings, 1 reply; 4+ messages in thread
From: Richard Sandiford @ 2017-11-09 11:14 UTC (permalink / raw)
To: Jeff Law; +Cc: gcc-patches
Jeff Law <law@redhat.com> writes:
> On 10/25/2017 09:57 AM, Richard Sandiford wrote:
>> 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.
>>
>> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu,
>> on top of the poly_int series. I think I can approve this under the
>> gen* maintainership, so if there are no comments in the menatime,
>> I'll apply it if the prerequisites are approved.
>>
>> Thanks,
>> Richard
>>
>>
>> 2017-10-25 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.
> Were all the prereqs here approved? Or does this depend on the poly_int
> stuff?
Yeah, it depends on the poly_int stuff. Not in a major way though --
I could reorder it if necessary.
Thanks,
Richard
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: Add support for adjusting the number of units in a mode
2017-11-09 11:14 ` Richard Sandiford
@ 2017-11-19 23:54 ` Jeff Law
0 siblings, 0 replies; 4+ messages in thread
From: Jeff Law @ 2017-11-19 23:54 UTC (permalink / raw)
To: gcc-patches, richard.sandiford
On 11/09/2017 04:08 AM, Richard Sandiford wrote:
> Jeff Law <law@redhat.com> writes:
>> On 10/25/2017 09:57 AM, Richard Sandiford wrote:
>>> 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.
>>>
>>> Tested on aarch64-linux-gnu, x86_64-linux-gnu and powerpc64le-linux-gnu,
>>> on top of the poly_int series. I think I can approve this under the
>>> gen* maintainership, so if there are no comments in the menatime,
>>> I'll apply it if the prerequisites are approved.
>>>
>>> Thanks,
>>> Richard
>>>
>>>
>>> 2017-10-25 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.
>> Were all the prereqs here approved? Or does this depend on the poly_int
>> stuff?
>
> Yeah, it depends on the poly_int stuff. Not in a major way though --
> I could reorder it if necessary.
Your call. I figure it's going to be at least a week working my way
through the rest of poly_int. I keep hoping to see groups of patches
within that kit that I can trivially look at and say, yea, of course
this is good. But it hasn't really happened yet.
jeff
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2017-11-19 23:47 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-25 15:58 Add support for adjusting the number of units in a mode Richard Sandiford
2017-11-08 22:47 ` Jeff Law
2017-11-09 11:14 ` Richard Sandiford
2017-11-19 23:54 ` Jeff Law
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).