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. * 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. * 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 +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 +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 -- 2.18.4