Re: [03/77] Allow machine modes to be classes

2017-08-11 Thread Jeff Law
On 07/13/2017 02:38 AM, Richard Sandiford wrote:
> This patch makes various changes that allow modes like SImode to be
> classes rather than enums.
> 
> Firstly, it adds inline functions for all mode size properties,
> with the macros being simple wrappers around them.  This is necessary
> for the __builtin_constant_p trick to continue working effectively when
> the mode arguments are slightly more complex (but still foldable at
> compile time).
> 
> These inline functions are trivial and heavily used.  There's not much
> point keeping them out-of-line at -O0: if anything it would make
> debugging harder rather than easier, and it would also slow things down.
> The patch therefore marks them as "always_inline", if that's available.
> Later patches use this approach too.
> 
> Using inline functions means that it's no longer possible to pass
> an int to GET_MODE_PRECISION etc.  The Fortran and powerpcspe-c.c
> parts are needed to avoid instances of that.
> 
> The patch continues to use enums for gencondmd.c, so that more
> mode comparisons are integer constant expressions when checking
> for always-true or always-false conditions.  This is the only
> intended use of USE_ENUM_MODES.
> 
> The patch also enforces the previous replacement of case statements
> by defining modes as:
> 
>   #define FOOmode ((void) 0, E_FOOmode)
> 
> This adds no overhead but makes sure that new uses of "case FOOmode:"
> don't accidentally creep in when FOOmode has no specific class associated
> with it.
> 
> 2017-07-13  Richard Sandiford  
>   Alan Hayward  
>   David Sherwood  
> 
> gcc/
>   * genconditions.c (write_header): Add a "#define USE_ENUM_MODES".
>   * genmodes.c (emit_insn_modes_h): Define FOOmode to E_FOOmode if
>   USE_ENUM_MODES is defined and to ((void) 0, E_FOOmode) otherwise.
>   * machmode.h (mode_size): Move earlier in file.
>   (mode_precision): Likewise.
>   (mode_inner): Likewise.
>   (mode_nunits): Likewise.
>   (mode_unit_size): Likewise.
>   (unit_unit_precision): Likewise.
>   (mode_wider): Likewise.
>   (mode_2xwider): Likewise.
>   (machine_mode): New class.
>   (mode_to_bytes): New function.
>   (mode_to_bits): Likewise.
>   (mode_to_precision): Likewise.
>   (mode_to_inner): Likewise.
>   (mode_to_unit_size): Likewise.
>   (mode_to_unit_precision): Likewise.
>   (mode_to_nunits): Likewise.
>   (GET_MODE_SIZE): Use mode_to_bytes.
>   (GET_MODE_BITSIZE): Use mode_to_bits.
>   (GET_MODE_PRECISION): Use mode_to_precision.
>   (GET_MODE_INNER): Use mode_to_inner.
>   (GET_MODE_UNIT_SIZE): Use mode_to_unit_size.
>   (GET_MODE_UNIT_PRECISION): Use mode_to_unit_precision.
>   (GET_MODE_NUNITS): Use mode_to_nunits.
>   * system.h (ALWAYS_INLINE): New macro.
>   * config/powerpcspe/powerpcspe-c.c
>   (altivec_resolve_overloaded_builtin): Use machine_mode instead of
>   int for arg1_mode and arg2_mode.
> 
> gcc/fortran/
>   * trans-types.c (gfc_init_kinds): Use machine_mode instead of int
>   for "mode".
OK.
Jeff


[03/77] Allow machine modes to be classes

2017-07-13 Thread Richard Sandiford
This patch makes various changes that allow modes like SImode to be
classes rather than enums.

Firstly, it adds inline functions for all mode size properties,
with the macros being simple wrappers around them.  This is necessary
for the __builtin_constant_p trick to continue working effectively when
the mode arguments are slightly more complex (but still foldable at
compile time).

These inline functions are trivial and heavily used.  There's not much
point keeping them out-of-line at -O0: if anything it would make
debugging harder rather than easier, and it would also slow things down.
The patch therefore marks them as "always_inline", if that's available.
Later patches use this approach too.

Using inline functions means that it's no longer possible to pass
an int to GET_MODE_PRECISION etc.  The Fortran and powerpcspe-c.c
parts are needed to avoid instances of that.

The patch continues to use enums for gencondmd.c, so that more
mode comparisons are integer constant expressions when checking
for always-true or always-false conditions.  This is the only
intended use of USE_ENUM_MODES.

The patch also enforces the previous replacement of case statements
by defining modes as:

  #define FOOmode ((void) 0, E_FOOmode)

This adds no overhead but makes sure that new uses of "case FOOmode:"
don't accidentally creep in when FOOmode has no specific class associated
with it.

2017-07-13  Richard Sandiford  
Alan Hayward  
David Sherwood  

gcc/
* genconditions.c (write_header): Add a "#define USE_ENUM_MODES".
* genmodes.c (emit_insn_modes_h): Define FOOmode to E_FOOmode if
USE_ENUM_MODES is defined and to ((void) 0, E_FOOmode) otherwise.
* machmode.h (mode_size): Move earlier in file.
(mode_precision): Likewise.
(mode_inner): Likewise.
(mode_nunits): Likewise.
(mode_unit_size): Likewise.
(unit_unit_precision): Likewise.
(mode_wider): Likewise.
(mode_2xwider): Likewise.
(machine_mode): New class.
(mode_to_bytes): New function.
(mode_to_bits): Likewise.
(mode_to_precision): Likewise.
(mode_to_inner): Likewise.
(mode_to_unit_size): Likewise.
(mode_to_unit_precision): Likewise.
(mode_to_nunits): Likewise.
(GET_MODE_SIZE): Use mode_to_bytes.
(GET_MODE_BITSIZE): Use mode_to_bits.
(GET_MODE_PRECISION): Use mode_to_precision.
(GET_MODE_INNER): Use mode_to_inner.
(GET_MODE_UNIT_SIZE): Use mode_to_unit_size.
(GET_MODE_UNIT_PRECISION): Use mode_to_unit_precision.
(GET_MODE_NUNITS): Use mode_to_nunits.
* system.h (ALWAYS_INLINE): New macro.
* config/powerpcspe/powerpcspe-c.c
(altivec_resolve_overloaded_builtin): Use machine_mode instead of
int for arg1_mode and arg2_mode.

gcc/fortran/
* trans-types.c (gfc_init_kinds): Use machine_mode instead of int
for "mode".

Index: gcc/genconditions.c
===
--- gcc/genconditions.c 2017-02-23 19:54:12.0 +
+++ gcc/genconditions.c 2017-07-13 09:18:20.866501621 +0100
@@ -67,6 +67,7 @@ #define CHECKING_P 0\n\
 #undef ENABLE_RTL_FLAG_CHECKING\n\
 #undef ENABLE_GC_CHECKING\n\
 #undef ENABLE_GC_ALWAYS_COLLECT\n\
+#define USE_ENUM_MODES\n\
 \n\
 #include \"coretypes.h\"\n\
 #include \"tm.h\"\n\
Index: gcc/genmodes.c
===
--- gcc/genmodes.c  2017-07-13 09:18:17.576867543 +0100
+++ gcc/genmodes.c  2017-07-13 09:18:20.866501621 +0100
@@ -1155,8 +1155,12 @@ enum machine_mode\n{");
printf ("%*s/* %s:%d */\n", 27 - count_, "",
 trim_filename (m->file), m->line);
printf ("#define HAVE_%smode\n", m->name);
-   printf ("#define %smode E_%smode\n",
+   printf ("#ifdef USE_ENUM_MODES\n");
+   printf ("#define %smode E_%smode\n", m->name, m->name);
+   printf ("#else\n");
+   printf ("#define %smode ((void) 0, E_%smode)\n",
m->name, m->name);
+   printf ("#endif\n");
   }
 
   puts ("  MAX_MACHINE_MODE,\n");
Index: gcc/machmode.h
===
--- gcc/machmode.h  2017-07-02 10:05:20.996539436 +0100
+++ gcc/machmode.h  2017-07-13 09:18:20.866501621 +0100
@@ -20,6 +20,15 @@ Software Foundation; either version 3, o
 #ifndef HAVE_MACHINE_MODES
 #define HAVE_MACHINE_MODES
 
+extern CONST_MODE_SIZE unsigned short mode_size[NUM_MACHINE_MODES];
+extern const unsigned short mode_precision[NUM_MACHINE_MODES];
+extern const unsigned char mode_inner[NUM_MACHINE_MODES];
+extern const unsigned char 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