acsaw...@linux.ibm.com writes: > From: Aaron Sawdey <acsaw...@linux.ibm.com> > > Richard, > Thanks for the review. I think I have resolved everything, as follows: > > * I was able to remove the const_tiny_rtx initialization for > MODE_OPAQUE. If that becomes a problem it's a pretty simple matter to > use an UNSPEC to assign a constant to an opaque mode if necessary. The > whole point of this exercise was not to have this thing treated as an > integral type so I think it's best to leave this out if at all > possible.
OK, sounds good. > * I ended up adding a precision to opaque after I had put in that hack > in get_nonzero_bits(). Now that it has a precision (equal to bitsize > as you say) this is no longer needed. The underlying problem there was > that without a precision, you ended up returning wi::shwi(-1,0) which > did not get treated as -1. OK. > * I have documented OPAQUE_TYPE in generic.texi and MODE_OPAQUE in > rtl.texi. > > OK for trunk if bootstrap/regtest passes on x86_64 and ppc64le? > > Thanks, > Aaron > > 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. > --- > gcc/dbxout.c | 1 + > gcc/doc/generic.texi | 8 ++++++++ > gcc/doc/rtl.texi | 6 ++++++ > gcc/genmodes.c | 22 ++++++++++++++++++++++ > gcc/ira.c | 4 +++- > gcc/machmode.def | 3 +++ > gcc/machmode.h | 4 ++++ > gcc/mode-classes.def | 3 ++- > gcc/stor-layout.c | 3 +++ > gcc/tree-pretty-print.c | 1 + > gcc/tree.c | 1 + > gcc/tree.def | 6 ++++++ > gcc/tree.h | 3 +++ > 13 files changed, 63 insertions(+), 2 deletions(-) > > diff --git a/gcc/dbxout.c b/gcc/dbxout.c > index 5a20fdecdcc..eaee2f19ce0 100644 > --- a/gcc/dbxout.c > +++ b/gcc/dbxout.c > @@ -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 > diff --git a/gcc/doc/generic.texi b/gcc/doc/generic.texi > index 7373266c69f..7e7b74c6c8b 100644 > --- a/gcc/doc/generic.texi > +++ b/gcc/doc/generic.texi > @@ -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 use a @code{MODE_OPAQUE} mode class in the Maybe s/use/have/? Just a suggestion though -- it's ok either way. > +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. > > diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi > index 22af5731bb6..cf892d425a2 100644 > --- a/gcc/doc/rtl.texi > +++ b/gcc/doc/rtl.texi > @@ -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 moves between registers/memory. They have a size and How about “other than register moves, memory moves, loads, stores and @code{unspec}s?”. I don't think there's anything stopping us using unspecs for these modes, and it wasn't clear to me which combinations were included in “moves between registers/memory”. OK with those changes if you agree. Thanks, Richard > +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 > diff --git a/gcc/genmodes.c b/gcc/genmodes.c > index bd78310ea24..34b52fe41d6 100644 > --- a/gcc/genmodes.c > +++ b/gcc/genmodes.c > @@ -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__) > > diff --git a/gcc/ira.c b/gcc/ira.c > index 050405f1833..e5f9a080e4d 100644 > --- 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); > > diff --git a/gcc/machmode.def b/gcc/machmode.def > index e4c9b4b5d98..6f8c6855aca 100644 > --- a/gcc/machmode.def > +++ b/gcc/machmode.def > @@ -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 > diff --git a/gcc/machmode.h b/gcc/machmode.h > index fbeefc24804..bb3a5c6c27e 100644 > --- a/gcc/machmode.h > +++ b/gcc/machmode.h > @@ -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 \ > diff --git a/gcc/mode-classes.def b/gcc/mode-classes.def > index f181def05ae..b78a715ba59 100644 > --- a/gcc/mode-classes.def > +++ b/gcc/mode-classes.def > @@ -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 */ > diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c > index dff81d1c24f..ee1cf55df90 100644 > --- a/gcc/stor-layout.c > +++ b/gcc/stor-layout.c > @@ -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 (); > diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c > index bd60d74d1af..c19e485e75a 100644 > --- a/gcc/tree-pretty-print.c > +++ b/gcc/tree-pretty-print.c > @@ -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; > diff --git a/gcc/tree.c b/gcc/tree.c > index 9260772b846..45b5a64c74c 100644 > --- a/gcc/tree.c > +++ b/gcc/tree.c > @@ -837,6 +837,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: > diff --git a/gcc/tree.def b/gcc/tree.def > index 6c53fe1bf67..462672f2c69 100644 > --- a/gcc/tree.def > +++ b/gcc/tree.def > @@ -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) > > /* Expressions */ > > diff --git a/gcc/tree.h b/gcc/tree.h > index caf6287f909..70570522330 100644 > --- a/gcc/tree.h > +++ b/gcc/tree.h > @@ -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