Segher Boessenkool <seg...@kernel.crashing.org> writes:
> Hi Richard,
>
> On Thu, Jul 13, 2017 at 09:35:44AM +0100, Richard Sandiford wrote:
>> This series is an update of:
>> 
>>     https://gcc.gnu.org/ml/gcc-patches/2016-12/msg00766.html
>> 
>> It adds a group of wrapper classes around machine_mode for modes that
>> are known to belong to, or need to belong to, a particular mode_class.
>> For example, it adds a scalar_int_mode wrapper for MODE_INT and
>> MODE_PARTIAL_INT modes, a scalar_float_mode wrapper for MODE_FLOAT and
>> MODE_DECIMAL_FLOAT modes, and so on.
>
> <huge snip>
>
> So what does it change in the interfaces we use?  I couldn't find an
> update of documentation, maybe I missed it (it's a huge series :-) )
> An overview of the new interfaces (and how they are used) would help.

You didn't miss one.  I was hoping the function comments would be enough,
but on reflection, they're not.  I've attached a patch for rtl.texi below.

> From what I can tell so far it makes things much harder to read.
> Perhaps that is just because this is all new.

Which parts specifically?  E.g. is it mostly the is_a <T> (x, &y) changes?
Or the as_a <T> (x) changes too?  Do you think the FOR_EACH_* iterators
also make things harder to read?  Or is machine_mode->scalar_int_mode
itself a problem?

>> I tested this by compiling the testsuite for:
>> 
>>     aarch64-linux-gnu alpha-linux-gnu arc-elf arm-linux-gnueabi
>>     arm-linux-gnueabihf avr-elf bfin-elf c6x-elf cr16-elf cris-elf
>>     epiphany-elf fr30-elf frv-linux-gnu ft32-elf h8300-elf
>>     hppa64-hp-hpux11.23 ia64-linux-gnu i686-pc-linux-gnu
>>     i686-apple-darwin iq2000-elf lm32-elf m32c-elf m32r-elf
>>     m68k-linux-gnu mcore-elf microblaze-elf mips-linux-gnu
>>     mipsisa64-linux-gnu mmix mn10300-elf moxie-rtems msp430-elf
>>     nds32le-elf nios2-linux-gnu nvptx-none pdp11 powerpc-linux-gnuspe
>>     powerpc-eabispe powerpc64-linux-gnu powerpc-ibm-aix7.0 riscv64-elf
>>     rl78-elf rx-elf s390-linux-gnu s390x-linux-gnu sh-linux-gnu
>>     sparc-linux-gnu sparc64-linux-gnu sparc-wrs-vxworks spu-elf
>>     tilegx-elf tilepro-elf xstormy16-elf v850-elf vax-netbsdelf
>>     visium-elf x86_64-darwin x86_64-linux-gnu xtensa-elf
>> 
>> and checking that there were no changes in assembly.  Also tested
>> in the normal way on aarch64-linux-gnu, powerc64-linux-gnu and
>> x86_64-linux-gnu.
>
> Could you also test powerpc64le-linux please?  It is a primary
> platform.  gcc112 is a nice fast machine.

Sorry, I meant powerpc64le-linux-gnu rather than powerpc64-linux-gnu.
It was indeed gcc112 that I used.

Thanks,
Richard


2017-07-24  Richard Sandiford  <richard.sandif...@linaro.org>

gcc/
        * doc/rtl.texi: Document machine_mode wrapper classes.

Index: gcc/doc/rtl.texi
===================================================================
--- gcc/doc/rtl.texi    2017-07-24 10:11:36.155904178 +0100
+++ gcc/doc/rtl.texi    2017-07-24 10:11:40.484732386 +0100
@@ -1402,6 +1402,108 @@ classes.  Currently @code{VOIDmode} and
 @code{MODE_RANDOM}.
 @end table
 
+@cindex machine mode wrapper classes
+@code{machmode.h} also defines various wrapper classes that combine a
+@code{machine_mode} with a static assertion that a particular
+condition holds.  The classes are:
+
+@table @code
+@findex scalar_int_mode
+@item scalar_int_mode
+A mode that has class @code{MODE_INT} or @code{MODE_PARTIAL_INT}.
+
+@findex scalar_float_mode
+@item scalar_float_mode
+A mode that has class @code{MODE_FLOAT} or @code{MODE_DECIMAL_FLOAT}.
+
+@findex scalar_mode
+@item scalar_mode
+A mode that holds a single numerical value.  In practice this means
+that the mode is a @code{scalar_int_mode}, is a @code{scalar_float_mode},
+or has class @code{MODE_FRACT}, @code{MODE_UFRACT}, @code{MODE_ACCUM},
+@code{MODE_UACCUM} or @code{MODE_POINTER_BOUNDS}.
+
+@findex complex_mode
+@item complex_mode
+A mode that has class @code{MODE_COMPLEX_INT} or @code{MODE_COMPLEX_FLOAT}.
+@end table
+
+Named modes use the most constrained of the available wrapper classes,
+if one exists, otherwise they use @code{machine_mode}.  For example,
+@code{QImode} is a @code{scalar_int_mode}, @code{SFmode} is a
+@code{scalar_float_mode} and @code{BLKmode} is a plain
+@code{machine_mode}.  It is possible to refer to any mode as a raw
+@code{machine_mode} by adding the @code{E_} prefix, where @code{E}
+stands for ``enumeration''.  For example, the raw @code{machine_mode}
+names of the modes just mentioned are @code{E_QImode}, @code{E_SFmode}
+and @code{E_BLKmode} respectively.
+
+The wrapper classes implicitly convert to @code{machine_mode} and to any
+wrapper class that represents a more general condition; for example
+@code{scalar_int_mode} and @code{scalar_float_mode} both convert
+to @code{scalar_mode}.  The classes act like @code{machine_mode}s
+that accept only certain named modes.
+
+@findex opt_mode
+@file{machmode.h} also defines a template class @code{opt_mode<@var{T}>}
+that holds a @code{T} or nothing, where @code{T} can be either
+@code{machine_mode} or one of the wrapper classes above.  The main
+operations on an @code{opt_mode<@var{T}>} @var{x} are as follows:
+
+@table @samp
+@item @var{x}.exists ()
+Return true if @var{x} holds a mode rather than nothing.
+
+@item @var{x}.exists (&@var{y})
+Return true if @var{x} holds a mode rather than nothing, storing the
+mode in @var{y} if so.  @var{y} must be assignment-compatible with @var{T}.
+
+@item *@var{x}
+Assert that @var{x} holds a mode rather than nothing and return that mode.
+
+@item @var{x} = @var{y}
+Set @var{x} to @var{y}, where @var{y} is a @var{T} or implicitly converts
+to a @var{T}.
+@end table
+
+The default constructor sets an @code{opt_mode<@var{T}>} to nothing.
+There is also a constructor that takes an initial value of type @var{T}.
+
+It is possible to use the @file{is-a.h} accessors on a @code{machine_mode}
+or machine mode wrapper @var{x}:
+
+@table @samp
+@findex is_a
+@item is_a <@var{T}> (@var{x})
+Return true if @var{x} meets the conditions for wrapper class @var{T}.
+
+@item is_a <@var{T}> (@var{x}, &@var{y})
+Return true if @var{x} meets the conditions for wrapper class @var{T},
+storing it in @var{y} if so.  @var{y} must be assignment-compatible with
+@var{T}.
+
+@item as_a <@var{T}> (@var{x})
+Assert that @var{x} meets the conditions for wrapper class @var{T}
+and return it as a @var{T}.
+
+@item dyn_cast <@var{T}> (@var{x})
+Return an @code{opt_mode<@var{T}>} that holds @var{x} if @var{x} meets
+the conditions for wrapper class @var{T} and that holds nothing otherwise.
+@end table
+
+The purpose of these wrapper classes is to give stronger static type
+checking.  For example, if a function takes a @code{scalar_int_mode},
+a caller that has a general @code{machine_mode} must either check or
+assert that the code is indeed a scalar integer first, using one of
+the functions above.
+
+The wrapper classes are normal C++ classes, with user-defined
+constructors.  Sometimes it is useful to have a POD version of
+the same type, particularly if the type appears in a @code{union}.
+The template class @code{pod_mode<@var{T}>} provides a POD version
+of wrapper class @var{T}.  It is assignment-compatible with @var{T}
+and implicitly converts to both @code{machine_mode} and @var{T}.
+
 Here are some C macros that relate to machine modes:
 
 @table @code

Reply via email to