Add MODE_OPAQUE
authorAaron Sawdey <acsawdey@linux.ibm.com>
Wed, 4 Nov 2020 19:54:25 +0000 (13:54 -0600)
committerAaron Sawdey <acsawdey@linux.ibm.com>
Tue, 17 Nov 2020 16:10:11 +0000 (11:10 -0500)
After discussion with Richard Sandiford on IRC, he suggested adding a
new mode class MODE_OPAQUE to deal with the problems (PR 96791) we had
been having with POImode/PXImode in powerpc target. This patch is the
accumulation of changes I needed to make to add this and make it useable
for the purposes of what power10 MMA needed.

MODE_OPAQUE modes allow you to have modes for which you can just
define loads and stores. By design, optimization does not expect to
know how to do arithmetic or subregs on these modes. This allows us to
have modes for multi-register vector operations where we don't want to
open Pandora's Box and define general arithmetic operations.

This patch will be followed by a target specific patch to change the
powerpc power10 MMA builtins to use opaque modes, and will also let use
use the vector pair loads/stores defined with that in the inline expansion
of memcpy/memmove, allowing me to fix PR 96791.

gcc/ChangeLog
PR target/96791
* mode-classes.def: Add MODE_OPAQUE.
* machmode.def: Add OPAQUE_MODE.
* tree.def: Add OPAQUE_TYPE for types that will use
MODE_OPAQUE.
* doc/generic.texi: Document OPAQUE_TYPE.
* doc/rtl.texi: Document MODE_OPAQUE.
* machmode.h: Add OPAQUE_MODE_P().
* genmodes.c (complete_mode): Add MODE_OPAQUE.
(opaque_mode): New function.
* tree.c (tree_code_size): Add OPAQUE_TYPE.
* tree.h: Add OPAQUE_TYPE_P().
* stor-layout.c (int_mode_for_mode): Treat MODE_OPAQUE modes
like BLKmode.
* ira.c (find_moveable_pseudos): Treat MODE_OPAQUE modes more
like integer/float modes here.
* dbxout.c (dbxout_type): Treat OPAQUE_TYPE like VOID_TYPE.
* tree-pretty-print.c (dump_generic_node): Treat OPAQUE_TYPE
like like other types.

13 files changed:
gcc/dbxout.c
gcc/doc/generic.texi
gcc/doc/rtl.texi
gcc/genmodes.c
gcc/ira.c
gcc/machmode.def
gcc/machmode.h
gcc/mode-classes.def
gcc/stor-layout.c
gcc/tree-pretty-print.c
gcc/tree.c
gcc/tree.def
gcc/tree.h

index 5a20fdecdcc4055e1d70c92eb685562f99a97ac3..eaee2f19ce0cb59d9f50215c875f0e4c30200137 100644 (file)
@@ -1963,6 +1963,7 @@ dbxout_type (tree type, int full)
     case VOID_TYPE:
     case NULLPTR_TYPE:
     case LANG_TYPE:
+    case OPAQUE_TYPE:
       /* For a void type, just define it as itself; i.e., "5=5".
         This makes us consider it defined
         without saying what it is.  The debugger will make it
index 7373266c69f393139dabe21437aa8b3c2b5b0b4a..5c1d3cda48c0376ab851a560c5bb419d73603ff2 100644 (file)
@@ -302,6 +302,7 @@ The elements are indexed from zero.
 @tindex ARRAY_TYPE
 @tindex RECORD_TYPE
 @tindex UNION_TYPE
+@tindex OPAQUE_TYPE
 @tindex UNKNOWN_TYPE
 @tindex OFFSET_TYPE
 @findex TYPE_UNQUALIFIED
@@ -487,6 +488,13 @@ assigned to that constant.  These constants will appear in the order in
 which they were declared.  The @code{TREE_TYPE} of each of these
 constants will be the type of enumeration type itself.
 
+@item OPAQUE_TYPE
+Used for things that have a @code{MODE_OPAQUE} mode class in the
+backend. Opaque types have a size and precision, and can be held in
+memory or registers. They are used when we do not want the compiler to
+make assumptions about the availability of other operations as would
+happen with integer types.
+
 @item BOOLEAN_TYPE
 Used to represent the @code{bool} type.
 
index 22af5731bb61ae54b464ed8d3012fe3e17e44d7b..4f9b99047ad09d6ef74d782b9c988650086ea4de 100644 (file)
@@ -1406,6 +1406,12 @@ Pointer bounds modes.  Used to represent values of pointer bounds type.
 Operations in these modes may be executed as NOPs depending on hardware
 features and environment setup.
 
+@findex MODE_OPAQUE
+@item MODE_OPAQUE
+This is a mode class for modes that don't want to provide operations
+other than register moves, memory moves, loads, stores, and
+@code{unspec}s. They have a size and precision and that's all.
+
 @findex MODE_RANDOM
 @item MODE_RANDOM
 This is a catchall mode class for modes which don't fit into the above
index bd78310ea24ed814508c6e40c411d93b65e08fdc..34b52fe41d6bf441a8487abc17d6fea3137c4829 100644 (file)
@@ -358,6 +358,14 @@ complete_mode (struct mode_data *m)
       m->component = 0;
       break;
 
+    case MODE_OPAQUE:
+      /* Opaque modes have size and precision.  */
+      validate_mode (m, OPTIONAL, SET, UNSET, UNSET, UNSET);
+
+      m->ncomponents = 1;
+      m->component = 0;
+      break;
+
     case MODE_PARTIAL_INT:
       /* A partial integer mode uses ->component to say what the
         corresponding full-size integer mode is, and may also
@@ -588,6 +596,20 @@ make_int_mode (const char *name,
   m->precision = precision;
 }
 
+#define OPAQUE_MODE(N, B)                      \
+  make_opaque_mode (#N, -1U, B, __FILE__, __LINE__)
+
+static void ATTRIBUTE_UNUSED
+make_opaque_mode (const char *name,
+                 unsigned int precision,
+                 unsigned int bytesize,
+                 const char *file, unsigned int line)
+{
+  struct mode_data *m = new_mode (MODE_OPAQUE, name, file, line);
+  m->bytesize = bytesize;
+  m->precision = precision;
+}
+
 #define FRACT_MODE(N, Y, F) \
        make_fixed_point_mode (MODE_FRACT, #N, Y, 0, F, __FILE__, __LINE__)
 
index 3c824e9be392a45bd23da1222682284501549894..89b5df4003d5c443e2a014f60c54e5cdb2ccea1a 100644 (file)
--- a/gcc/ira.c
+++ b/gcc/ira.c
@@ -4666,7 +4666,9 @@ find_moveable_pseudos (void)
                || !DF_REF_INSN_INFO (def)
                || HARD_REGISTER_NUM_P (regno)
                || DF_REG_EQ_USE_COUNT (regno) > 0
-               || (!INTEGRAL_MODE_P (mode) && !FLOAT_MODE_P (mode)))
+               || (!INTEGRAL_MODE_P (mode)
+                   && !FLOAT_MODE_P (mode)
+                   && !OPAQUE_MODE_P (mode)))
              continue;
            def_insn = DF_REF_INSN (def);
 
index e4c9b4b5d981bf4f749d436831dfcd4fc0b6bc5c..6f8c6855acaa21862ad0a20a75a8749c8480cd11 100644 (file)
@@ -153,6 +153,9 @@ along with GCC; see the file COPYING3.  If not see
         the element at index 0 occupying the lsb of the first byte in
         memory.  Only the lowest bit of each element is significant.
 
+     OPAQUE_MODE (NAME, BYTESIZE)
+        Create an opaque mode called NAME that is BYTESIZE bytes wide.
+
      COMPLEX_MODES (CLASS);
         For all modes presently declared in class CLASS, construct
        corresponding complex modes.  Modes smaller than one byte
index fbeefc24804d0d2b7accde34ebc0df59bfc7948c..bb3a5c6c27e56679d41b5aa44283b07dada454a2 100644 (file)
@@ -225,6 +225,10 @@ extern const unsigned char mode_class[NUM_MACHINE_MODES];
   (SIGNED_FIXED_POINT_MODE_P (MODE)            \
    || UNSIGNED_FIXED_POINT_MODE_P (MODE))
 
+/* Nonzero if MODE is opaque.  */
+#define OPAQUE_MODE_P(MODE)                     \
+    (GET_MODE_CLASS (MODE) == MODE_OPAQUE)
+
 /* Nonzero if CLASS modes can be widened.  */
 #define CLASS_HAS_WIDER_MODES_P(CLASS)         \
   (CLASS == MODE_INT                           \
index f181def05aef711049b8ac64584a4a17329b6e3d..b78a715ba59198ddca049e5c3de9142d195a8c92 100644 (file)
@@ -36,4 +36,5 @@ along with GCC; see the file COPYING3.  If not see
   DEF_MODE_CLASS (MODE_VECTOR_UFRACT), /* SIMD vectors */                 \
   DEF_MODE_CLASS (MODE_VECTOR_ACCUM),  /* SIMD vectors */                 \
   DEF_MODE_CLASS (MODE_VECTOR_UACCUM), /* SIMD vectors */                 \
-  DEF_MODE_CLASS (MODE_VECTOR_FLOAT)
+  DEF_MODE_CLASS (MODE_VECTOR_FLOAT),                                      \
+  DEF_MODE_CLASS (MODE_OPAQUE)          /* opaque modes */
index dff81d1c24f51435d717a42234dddfebbeed1d07..ee1cf55df90e2948df52f6d90b7e3d6741a4d399 100644 (file)
@@ -393,6 +393,9 @@ int_mode_for_mode (machine_mode mode)
     case MODE_VECTOR_UACCUM:
       return int_mode_for_size (GET_MODE_BITSIZE (mode), 0);
 
+    case MODE_OPAQUE:
+       return opt_scalar_int_mode ();
+
     case MODE_RANDOM:
       if (mode == BLKmode)
        return opt_scalar_int_mode ();
index 318f048bcff4a48df44573aa098ee6a7f51db115..5a93c4d8b9e3df117f515347ec7eaaf53f06240c 100644 (file)
@@ -1708,6 +1708,7 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
     case VECTOR_TYPE:
     case ENUMERAL_TYPE:
     case BOOLEAN_TYPE:
+    case OPAQUE_TYPE:
       {
        unsigned int quals = TYPE_QUALS (node);
        enum tree_code_class tclass;
index 0fe9097bbbcbc220f2bf371002092dc897b3385b..569a9b9317bee17f0dacfda0eee2bdba63b3aae1 100644 (file)
@@ -864,6 +864,7 @@ tree_code_size (enum tree_code code)
        case BOOLEAN_TYPE:
        case INTEGER_TYPE:
        case REAL_TYPE:
+       case OPAQUE_TYPE:
        case POINTER_TYPE:
        case REFERENCE_TYPE:
        case NULLPTR_TYPE:
index 6c53fe1bf67cd8eee7084de0b20b8d217d70710a..462672f2c69fc988a314799e7342a29298674e8f 100644 (file)
@@ -250,6 +250,12 @@ DEFTREECODE (METHOD_TYPE, "method_type", tcc_type, 0)
    layout_type does not know how to lay this out,
    so the front-end must do so manually.  */
 DEFTREECODE (LANG_TYPE, "lang_type", tcc_type, 0)
+
+/* This is for types that will use MODE_OPAQUE in the back end.  They are meant
+   to be able to go in a register of some sort but are explicitly not to be
+   converted or operated on like INTEGER_TYPE.  They will have size and
+   alignment information only.  */
+DEFTREECODE (OPAQUE_TYPE, "opaque_type", tcc_type, 0)
 \f
 /* Expressions */
 
index 5c0e3cc2e5a80d2aeca916f40ac830421d31a48f..bea3e16c0916dc121e215ab8b18d179d6cc69898 100644 (file)
@@ -625,6 +625,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int,
 #define FUNC_OR_METHOD_TYPE_P(NODE) \
   (TREE_CODE (NODE) == FUNCTION_TYPE || TREE_CODE (NODE) == METHOD_TYPE)
 
+#define OPAQUE_TYPE_P(NODE) \
+    (TREE_CODE (NODE) == OPAQUE_TYPE)
+
 /* Define many boolean fields that all tree nodes have.  */
 
 /* In VAR_DECL, PARM_DECL and RESULT_DECL nodes, nonzero means address