From 15f8d3ab4a4f0e893b9080477091425fda92d187 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 18 Aug 2014 20:02:17 +0000 Subject: [PATCH] Introduce rtx_insn subclass of rtx_def gcc/ 2014-08-18 David Malcolm * coretypes.h (class rtx_insn): Add forward declaration. * rtl.h: Include is-a.h. (struct rtx_def): Add dummy "desc" and "tag" GTY options as a workaround to ensure gengtype knows inheritance is occurring, whilst continuing to use the pre-existing special-casing for rtx_def. (class rtx_insn): New subclass of rtx_def, adding the invariant that we're dealing with something we can sanely use INSN_UID, NEXT_INSN, PREV_INSN on. (is_a_helper ::test): New. (is_a_helper ::test): New. From-SVN: r214118 --- gcc/ChangeLog | 15 +++++++++++++ gcc/coretypes.h | 7 ++++++ gcc/rtl.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 81 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bc5c327b931..f6454dbad74 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2014-08-18 David Malcolm + + * coretypes.h (class rtx_insn): Add forward declaration. + + * rtl.h: Include is-a.h. + (struct rtx_def): Add dummy "desc" and "tag" GTY options as a + workaround to ensure gengtype knows inheritance is occurring, + whilst continuing to use the pre-existing special-casing for + rtx_def. + (class rtx_insn): New subclass of rtx_def, adding the + invariant that we're dealing with something we can sanely use + INSN_UID, NEXT_INSN, PREV_INSN on. + (is_a_helper ::test): New. + (is_a_helper ::test): New. + 2014-08-18 David Malcolm * is-a.h (template safe_as_a ) New function. diff --git a/gcc/coretypes.h b/gcc/coretypes.h index bbb515092bb..f22b9808b3f 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -55,6 +55,13 @@ typedef const struct simple_bitmap_def *const_sbitmap; struct rtx_def; typedef struct rtx_def *rtx; typedef const struct rtx_def *const_rtx; + +/* Subclasses of rtx_def, using indentation to show the class + hierarchy. + Where possible, keep this list in the same order as in rtl.def. */ +class rtx_def; + class rtx_insn; + struct rtvec_def; typedef struct rtvec_def *rtvec; typedef const struct rtvec_def *const_rtvec; diff --git a/gcc/rtl.h b/gcc/rtl.h index b6555ea97aa..28f598e03f0 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see #include "hashtab.h" #include "wide-int.h" #include "flags.h" +#include "is-a.h" /* Value used by some passes to "recognize" noop moves as valid instructions. */ @@ -266,7 +267,21 @@ struct GTY((variable_size)) hwivec_def { /* RTL expression ("rtx"). */ -struct GTY((chain_next ("RTX_NEXT (&%h)"), +/* The GTY "desc" and "tag" options below are a kludge: we need a desc + field for for gengtype to recognize that inheritance is occurring, + so that all subclasses are redirected to the traversal hook for the + base class. + However, all of the fields are in the base class, and special-casing + is at work. Hence we use desc and tag of 0, generating a switch + statement of the form: + switch (0) + { + case 0: // all the work happens here + } + in order to work with the existing special-casing in gengtype. */ + +struct GTY((desc("0"), tag("0"), + chain_next ("RTX_NEXT (&%h)"), chain_prev ("RTX_PREV (&%h)"))) rtx_def { /* The kind of expression this is. */ ENUM_BITFIELD(rtx_code) code: 16; @@ -387,6 +402,25 @@ struct GTY((chain_next ("RTX_NEXT (&%h)"), } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u; }; +class GTY(()) rtx_insn : public rtx_def +{ + /* No extra fields, but adds the invariant: + + (INSN_P (X) + || NOTE_P (X) + || JUMP_TABLE_DATA_P (X) + || BARRIER_P (X) + || LABEL_P (X)) + + i.e. that we must be able to use the following: + INSN_UID () + NEXT_INSN () + PREV_INSN () + i.e. we have an rtx that has an INSN_UID field and can be part of + a linked list of insns. + */ +}; + /* The size in bytes of an rtx header (code, mode and flags). */ #define RTX_HDR_SIZE offsetof (struct rtx_def, u) @@ -548,6 +582,30 @@ struct GTY(()) rtvec_def { /* Predicate yielding nonzero iff X is a data for a jump table. */ #define JUMP_TABLE_DATA_P(INSN) (GET_CODE (INSN) == JUMP_TABLE_DATA) +template <> +template <> +inline bool +is_a_helper ::test (rtx rt) +{ + return (INSN_P (rt) + || NOTE_P (rt) + || JUMP_TABLE_DATA_P (rt) + || BARRIER_P (rt) + || LABEL_P (rt)); +} + +template <> +template <> +inline bool +is_a_helper ::test (const_rtx rt) +{ + return (INSN_P (rt) + || NOTE_P (rt) + || JUMP_TABLE_DATA_P (rt) + || BARRIER_P (rt) + || LABEL_P (rt)); +} + /* Predicate yielding nonzero iff X is a return or simple_return. */ #define ANY_RETURN_P(X) \ (GET_CODE (X) == RETURN || GET_CODE (X) == SIMPLE_RETURN)