On Fri, Mar 11, 2011 at 5:23 AM, Nathan Froyd <[email protected]> wrote:
> The first step in removing TREE_CHAIN (and even TREE_TYPE) from a select
> few nodes is to create separate substructures for trees-with-type and
> trees-with-chain. Since trees-with-type but no chain are expected to be
> more common that vice versa, make the hierarchy reflect that. Modify a
> few macros to reflect the new inheritance structure, and add a new tree
> structure enum for the new structure. Make note that we support the new
> tree structure in the LTO streamer, even though we don't need to do
> anything about it yet.
Ok for 4.7 (I assume you have tested each patch separately for _all_
languages, or if not, will do so before applying).
Thanks,
Richard.
> -Nathan
>
> gcc/
> * tree.h (struct typed_tree): New.
> (struct tree_common): Include it instead of tree_base.
> (TREE_TYPE): Update for new location of type field.
> (TYPE_USER_ALIGN, TYPE_PACKED): Refer to base field directly.
> (DECL_USER_ALIGN, DECL_PACKED): Likewise.
> (union tree_node): Add typed field.
> * treestruct.def (TS_TYPED): New.
> * lto-streamer.c (check_handled_ts_structures): Handle it.
> * tree.c (MARK_TS_TYPED): New macro.
> (MARK_TS_COMMON): Call it instead of MARK_TS_BASE.
>
> diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
> index dba9d2d..546228c 100644
> --- a/gcc/lto-streamer.c
> +++ b/gcc/lto-streamer.c
> @@ -270,6 +270,7 @@ check_handled_ts_structures (void)
> /* These are the TS_* structures that are either handled or
> explicitly ignored by the streamer routines. */
> handled_p[TS_BASE] = true;
> + handled_p[TS_TYPED] = true;
> handled_p[TS_COMMON] = true;
> handled_p[TS_INT_CST] = true;
> handled_p[TS_REAL_CST] = true;
> diff --git a/gcc/tree.c b/gcc/tree.c
> index c947072..798bc08 100644
> --- a/gcc/tree.c
> +++ b/gcc/tree.c
> @@ -356,9 +356,15 @@ initialize_tree_contains_struct (void)
> tree_contains_struct[C][TS_BASE] = 1; \
> } while (0)
>
> -#define MARK_TS_COMMON(C) \
> +#define MARK_TS_TYPED(C) \
> do { \
> MARK_TS_BASE (C); \
> + tree_contains_struct[C][TS_TYPED] = 1; \
> + } while (0)
> +
> +#define MARK_TS_COMMON(C) \
> + do { \
> + MARK_TS_TYPED (C); \
> tree_contains_struct[C][TS_COMMON] = 1; \
> } while (0)
>
> diff --git a/gcc/tree.h b/gcc/tree.h
> index a49e335..2f772e1 100644
> --- a/gcc/tree.h
> +++ b/gcc/tree.h
> @@ -407,12 +407,16 @@ struct GTY(()) tree_base {
> unsigned address_space : 8;
> };
>
> -struct GTY(()) tree_common {
> +struct GTY(()) typed_tree {
> struct tree_base base;
> - tree chain;
> tree type;
> };
>
> +struct GTY(()) tree_common {
> + struct typed_tree typed;
> + tree chain;
> +};
> +
> /* The following table lists the uses of each of the above flags and
> for which types of nodes they are defined.
>
> @@ -869,7 +873,7 @@ enum tree_node_structure_enum {
> In VECTOR_TYPE nodes, this is the type of the elements. */
> #define TREE_TYPE(NODE) __extension__ \
> (*({__typeof (NODE) const __t = (NODE);
> \
> - &__t->common.type; }))
> + &__t->typed.type; }))
>
> extern void tree_contains_struct_check_failed (const_tree,
> const enum
> tree_node_structure_enum,
> @@ -2151,7 +2155,7 @@ extern enum machine_mode vector_type_mode (const_tree);
>
> /* 1 if the alignment for this type was requested by "aligned" attribute,
> 0 if it is the default for this type. */
> -#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->common.base.user_align)
> +#define TYPE_USER_ALIGN(NODE) (TYPE_CHECK (NODE)->base.user_align)
>
> /* The alignment for NODE, in bytes. */
> #define TYPE_ALIGN_UNIT(NODE) (TYPE_ALIGN (NODE) / BITS_PER_UNIT)
> @@ -2289,7 +2293,7 @@ extern enum machine_mode vector_type_mode (const_tree);
>
> /* Indicated that objects of this type should be laid out in as
> compact a way as possible. */
> -#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->common.base.packed_flag)
> +#define TYPE_PACKED(NODE) (TYPE_CHECK (NODE)->base.packed_flag)
>
> /* Used by type_contains_placeholder_p to avoid recomputation.
> Values are: 0 (unknown), 1 (false), 2 (true). Never access
> @@ -2632,7 +2636,7 @@ struct GTY(()) tree_decl_minimal {
> /* Set if the alignment of this DECL has been set by the user, for
> example with an 'aligned' attribute. */
> #define DECL_USER_ALIGN(NODE) \
> - (DECL_COMMON_CHECK (NODE)->common.base.user_align)
> + (DECL_COMMON_CHECK (NODE)->base.user_align)
> /* Holds the machine mode corresponding to the declaration of a variable or
> field. Always equal to TYPE_MODE (TREE_TYPE (decl)) except for a
> FIELD_DECL. */
> @@ -2900,7 +2904,7 @@ struct GTY(()) tree_decl_with_rtl {
> #define DECL_FCONTEXT(NODE) (FIELD_DECL_CHECK (NODE)->field_decl.fcontext)
>
> /* In a FIELD_DECL, indicates this field should be bit-packed. */
> -#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->common.base.packed_flag)
> +#define DECL_PACKED(NODE) (FIELD_DECL_CHECK (NODE)->base.packed_flag)
>
> /* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed
> specially. */
> @@ -3505,6 +3509,7 @@ extern tree build_target_option_node (void);
> union GTY ((ptr_alias (union lang_tree_node),
> desc ("tree_node_structure (&%h)"), variable_size)) tree_node {
> struct tree_base GTY ((tag ("TS_BASE"))) base;
> + struct typed_tree GTY ((tag ("TS_TYPED"))) typed;
> struct tree_common GTY ((tag ("TS_COMMON"))) common;
> struct tree_int_cst GTY ((tag ("TS_INT_CST"))) int_cst;
> struct tree_real_cst GTY ((tag ("TS_REAL_CST"))) real_cst;
> diff --git a/gcc/treestruct.def b/gcc/treestruct.def
> index baea46a..b65bdc2 100644
> --- a/gcc/treestruct.def
> +++ b/gcc/treestruct.def
> @@ -31,6 +31,7 @@ along with GCC; see the file COPYING3. If not see
> specifying what structures contain what other structures in the
> tree_contains_struct array. */
> DEFTREESTRUCT(TS_BASE, "base")
> +DEFTREESTRUCT(TS_TYPED, "typed")
> DEFTREESTRUCT(TS_COMMON, "common")
> DEFTREESTRUCT(TS_INT_CST, "integer cst")
> DEFTREESTRUCT(TS_REAL_CST, "real cst")
> --
> 1.7.0.4
>
>