alias.c (struct alias_set_entry): New field has_zero_child.
* alias.c (struct alias_set_entry): New field has_zero_child. (mem_in_disjoint_alias_sets_p): Return 0 if set in either ase. (get_alias_set): If language-dependent routine set TYPE_ALIAS_SET, do nothing. Call record_component_aliases for aggregate types. (record_alias_subset): Set has_zero_child. (record_component_aliases, case ARRAY_TYPE): Do nothing if TYPE_NONALIASES_COMPONENT. (record_component_aliases, case RECORD_TYPE): Test DECL_NONADDRESSABLE_P. * c-decl.c (grokdeclarator): Set DECL_NONADDRESSABLE_P instead of TREE_ADDRESSABLE. * calls.c (initialize_argument_information): Only test TYPE_TRANSPARENT_UNION for UNION_TYPE. * function.c (assign_parms): Likewise. * integrate.c (function_cannot_inline_p): Likewise. * stor-layout.c (finish_record_layout): Don't call record_component_aliases. * tree.h (struct tree_int_cst): Use struct tree_common. (struct tree_real_cst, struct tree_string): Likewise. (struct tree_complex, struct tree_identifier): Likewise. (struct tree_list, struct tree_vec, struct tree_exp): Likewise. (struct tree_block, struct tree_type, struct tree_decl): Likewise. (TYPE_TRANSPARENT_UNION): Use UNION_TYPE_CHECK. (TYPE_NONALIASES_COMPONENT): New macro. (TYPE_AMBIENT_BOUNDEDNESS): Use FUNCTION_TYPE_CHECK. (DECL_NONADDRESSABLE_P): New macro. (struct tree_decl): Reorder bits for clarity of how many left; add non_adressable. * cp/cp-tree.h: Use struct tree_common instead of a char array. * cp/decl.c (grokdeclarator): Set DECL_NONADDRESSABLE_P instead of TREE_ADDRESSABLE. From-SVN: r34373
This commit is contained in:
parent
0e13506e49
commit
2bf105ab5b
|
@ -1,3 +1,35 @@
|
|||
Fri Jun 2 19:31:03 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
* alias.c (struct alias_set_entry): New field has_zero_child.
|
||||
(mem_in_disjoint_alias_sets_p): Return 0 if set in either ase.
|
||||
(get_alias_set): If language-dependent routine set TYPE_ALIAS_SET,
|
||||
do nothing.
|
||||
Call record_component_aliases for aggregate types.
|
||||
(record_alias_subset): Set has_zero_child.
|
||||
(record_component_aliases, case ARRAY_TYPE): Do nothing if
|
||||
TYPE_NONALIASES_COMPONENT.
|
||||
(record_component_aliases, case RECORD_TYPE): Test
|
||||
DECL_NONADDRESSABLE_P.
|
||||
* c-decl.c (grokdeclarator): Set DECL_NONADDRESSABLE_P instead
|
||||
of TREE_ADDRESSABLE.
|
||||
* calls.c (initialize_argument_information): Only test
|
||||
TYPE_TRANSPARENT_UNION for UNION_TYPE.
|
||||
* function.c (assign_parms): Likewise.
|
||||
* integrate.c (function_cannot_inline_p): Likewise.
|
||||
* stor-layout.c (finish_record_layout): Don't call
|
||||
record_component_aliases.
|
||||
* tree.h (struct tree_int_cst): Use struct tree_common.
|
||||
(struct tree_real_cst, struct tree_string): Likewise.
|
||||
(struct tree_complex, struct tree_identifier): Likewise.
|
||||
(struct tree_list, struct tree_vec, struct tree_exp): Likewise.
|
||||
(struct tree_block, struct tree_type, struct tree_decl): Likewise.
|
||||
(TYPE_TRANSPARENT_UNION): Use UNION_TYPE_CHECK.
|
||||
(TYPE_NONALIASES_COMPONENT): New macro.
|
||||
(TYPE_AMBIENT_BOUNDEDNESS): Use FUNCTION_TYPE_CHECK.
|
||||
(DECL_NONADDRESSABLE_P): New macro.
|
||||
(struct tree_decl): Reorder bits for clarity of how many left;
|
||||
add non_adressable.
|
||||
|
||||
2000-06-02 Jason Merrill <jason@casey.soma.redhat.com>
|
||||
|
||||
* Makefile.in (libgcc.a): Also depend on $(LIB2ADD).
|
||||
|
|
70
gcc/alias.c
70
gcc/alias.c
|
@ -79,6 +79,10 @@ typedef struct alias_set_entry
|
|||
continuing our example above, the children here will be all of
|
||||
`int', `double', `float', and `struct S'. */
|
||||
splay_tree children;
|
||||
|
||||
/* Nonzero if would have a child of zero: this effectively makes this
|
||||
alias set the same as alias set zero. */
|
||||
int has_zero_child;
|
||||
} *alias_set_entry;
|
||||
|
||||
static int rtx_equal_for_memref_p PARAMS ((rtx, rtx));
|
||||
|
@ -239,14 +243,18 @@ mems_in_disjoint_alias_sets_p (mem1, mem2)
|
|||
|
||||
/* See if the first alias set is a subset of the second. */
|
||||
ase = get_alias_set_entry (MEM_ALIAS_SET (mem1));
|
||||
if (ase != 0 && splay_tree_lookup (ase->children,
|
||||
(splay_tree_key) MEM_ALIAS_SET (mem2)))
|
||||
if (ase != 0
|
||||
&& (ase->has_zero_child
|
||||
|| splay_tree_lookup (ase->children,
|
||||
(splay_tree_key) MEM_ALIAS_SET (mem2))))
|
||||
return 0;
|
||||
|
||||
/* Now do the same, but with the alias sets reversed. */
|
||||
ase = get_alias_set_entry (MEM_ALIAS_SET (mem2));
|
||||
if (ase != 0 && splay_tree_lookup (ase->children,
|
||||
(splay_tree_key) MEM_ALIAS_SET (mem1)))
|
||||
if (ase != 0
|
||||
&& (ase->has_zero_child
|
||||
|| splay_tree_lookup (ase->children,
|
||||
(splay_tree_key) MEM_ALIAS_SET (mem1))))
|
||||
return 0;
|
||||
|
||||
/* The two MEMs are in distinct alias sets, and neither one is the
|
||||
|
@ -406,7 +414,12 @@ get_alias_set (t)
|
|||
|
||||
/* See if the language has special handling for this type. */
|
||||
if ((set = lang_get_alias_set (t)) != -1)
|
||||
;
|
||||
{
|
||||
/* If the alias set is now known, we are done. */
|
||||
if (TYPE_ALIAS_SET_KNOWN_P (t))
|
||||
return TYPE_ALIAS_SET (t);
|
||||
}
|
||||
|
||||
/* There are no objects of FUNCTION_TYPE, so there's no point in
|
||||
using up an alias set for them. (There are, of course, pointers
|
||||
and references to functions, but that's different.) */
|
||||
|
@ -417,6 +430,12 @@ get_alias_set (t)
|
|||
set = new_alias_set ();
|
||||
|
||||
TYPE_ALIAS_SET (t) = set;
|
||||
|
||||
/* If this is an aggregate type, we must record any component aliasing
|
||||
information. */
|
||||
if (AGGREGATE_TYPE_P (t))
|
||||
record_component_aliases (t);
|
||||
|
||||
return set;
|
||||
}
|
||||
|
||||
|
@ -468,18 +487,26 @@ record_alias_subset (superset, subset)
|
|||
|
||||
}
|
||||
|
||||
subset_entry = get_alias_set_entry (subset);
|
||||
if (subset == 0)
|
||||
superset_entry->has_zero_child = 1;
|
||||
else
|
||||
{
|
||||
subset_entry = get_alias_set_entry (subset);
|
||||
/* If there is an entry for the subset, enter all of its children
|
||||
(if they are not already present) as children of the SUPERSET. */
|
||||
if (subset_entry)
|
||||
{
|
||||
if (subset_entry->has_zero_child)
|
||||
superset_entry->has_zero_child = 1;
|
||||
|
||||
/* If there is an entry for the subset, enter all of its children
|
||||
(if they are not already present) as children of the SUPERSET. */
|
||||
if (subset_entry)
|
||||
splay_tree_foreach (subset_entry->children,
|
||||
insert_subset_children,
|
||||
superset_entry->children);
|
||||
splay_tree_foreach (subset_entry->children, insert_subset_children,
|
||||
superset_entry->children);
|
||||
}
|
||||
|
||||
/* Enter the SUBSET itself as a child of the SUPERSET. */
|
||||
splay_tree_insert (superset_entry->children,
|
||||
(splay_tree_key) subset, 0);
|
||||
/* Enter the SUBSET itself as a child of the SUPERSET. */
|
||||
splay_tree_insert (superset_entry->children,
|
||||
(splay_tree_key) subset, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* Record that component types of TYPE, if any, are part of that type for
|
||||
|
@ -493,7 +520,6 @@ record_component_aliases (type)
|
|||
tree type;
|
||||
{
|
||||
HOST_WIDE_INT superset = get_alias_set (type);
|
||||
HOST_WIDE_INT subset;
|
||||
tree field;
|
||||
|
||||
if (superset == 0)
|
||||
|
@ -502,20 +528,16 @@ record_component_aliases (type)
|
|||
switch (TREE_CODE (type))
|
||||
{
|
||||
case ARRAY_TYPE:
|
||||
subset = get_alias_set (TREE_TYPE (type));
|
||||
if (subset != 0)
|
||||
record_alias_subset (superset, subset);
|
||||
if (! TYPE_NONALIASED_COMPONENT (type))
|
||||
record_alias_subset (superset, get_alias_set (TREE_TYPE (type)));
|
||||
break;
|
||||
|
||||
case RECORD_TYPE:
|
||||
case UNION_TYPE:
|
||||
case QUAL_UNION_TYPE:
|
||||
for (field = TYPE_FIELDS (type); field != 0; field = TREE_CHAIN (field))
|
||||
{
|
||||
subset = get_alias_set (TREE_TYPE (field));
|
||||
if (TREE_ADDRESSABLE (field) && subset != 0 && subset != superset)
|
||||
record_alias_subset (superset, subset);
|
||||
}
|
||||
if (! DECL_NONADDRESSABLE_P (field))
|
||||
record_alias_subset (superset, get_alias_set (TREE_TYPE (field)));
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -4697,7 +4697,8 @@ grokdeclarator (declarator, declspecs, decl_context, initialized)
|
|||
#endif
|
||||
}
|
||||
decl = build_decl (FIELD_DECL, declarator, type);
|
||||
TREE_ADDRESSABLE (decl) = ! bitfield;
|
||||
DECL_NONADDRESSABLE_P (decl) = bitfield;
|
||||
|
||||
if (size_varies)
|
||||
C_DECL_VARIABLE_SIZE (decl) = 1;
|
||||
}
|
||||
|
|
|
@ -1109,7 +1109,7 @@ initialize_argument_information (num_actuals, args, args_size, n_named_args,
|
|||
/* If TYPE is a transparent union, pass things the way we would
|
||||
pass the first field of the union. We have already verified that
|
||||
the modes are the same. */
|
||||
if (TYPE_TRANSPARENT_UNION (type))
|
||||
if (TREE_CODE (type) == UNION_TYPE && TYPE_TRANSPARENT_UNION (type))
|
||||
type = TREE_TYPE (TYPE_FIELDS (type));
|
||||
|
||||
/* Decide where to pass this arg.
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
Fri Jun 2 19:38:57 2000 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
|
||||
|
||||
* cp-tree.h: Use struct tree_common instead of a char array.
|
||||
* decl.c (grokdeclarator): Set DECL_NONADDRESSABLE_P instead
|
||||
of TREE_ADDRESSABLE.
|
||||
|
||||
2000-06-02 Richard Henderson <rth@cygnus.com>
|
||||
|
||||
* decl.c (init_decl_processing): Don't set lang_get_alias_set.
|
||||
|
|
|
@ -299,7 +299,7 @@ typedef struct
|
|||
|
||||
typedef struct
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
HOST_WIDE_INT index;
|
||||
HOST_WIDE_INT level;
|
||||
HOST_WIDE_INT orig_level;
|
||||
|
@ -308,7 +308,7 @@ typedef struct
|
|||
|
||||
typedef struct ptrmem_cst
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
/* This isn't used, but the middle-end expects all constants to have
|
||||
this field. */
|
||||
struct rtx_def *rtl;
|
||||
|
@ -351,7 +351,7 @@ typedef struct ptrmem_cst
|
|||
|
||||
struct tree_binding
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
union {
|
||||
tree scope;
|
||||
struct binding_level *level;
|
||||
|
@ -374,7 +374,7 @@ struct tree_binding
|
|||
|
||||
struct tree_overload
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
tree function;
|
||||
};
|
||||
|
||||
|
@ -391,7 +391,7 @@ struct tree_overload
|
|||
|
||||
struct tree_wrapper
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
union {
|
||||
void *ptr;
|
||||
int i;
|
||||
|
@ -402,7 +402,7 @@ struct tree_wrapper
|
|||
#define SRCLOC_LINE(NODE) (((struct tree_srcloc*)SRCLOC_CHECK (NODE))->linenum)
|
||||
struct tree_srcloc
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
const char *filename;
|
||||
int linenum;
|
||||
};
|
||||
|
|
|
@ -11594,7 +11594,7 @@ grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist)
|
|||
else
|
||||
{
|
||||
decl = build_decl (FIELD_DECL, declarator, type);
|
||||
TREE_ADDRESSABLE (decl) = ! bitfield;
|
||||
DECL_NONADDRESSABLE_P (decl) = bitfield;
|
||||
if (RIDBIT_SETP (RID_MUTABLE, specbits))
|
||||
{
|
||||
DECL_MUTABLE_P (decl) = 1;
|
||||
|
|
|
@ -4231,7 +4231,8 @@ assign_parms (fndecl)
|
|||
type of the first field for the tests below. We have already
|
||||
verified that the modes are the same. */
|
||||
if (DECL_TRANSPARENT_UNION (parm)
|
||||
|| TYPE_TRANSPARENT_UNION (passed_type))
|
||||
|| (TREE_CODE (passed_type) == UNION_TYPE
|
||||
&& TYPE_TRANSPARENT_UNION (passed_type)))
|
||||
passed_type = TREE_TYPE (TYPE_FIELDS (passed_type));
|
||||
|
||||
/* See if this arg was passed by invisible reference. It is if
|
||||
|
|
|
@ -201,7 +201,8 @@ function_cannot_inline_p (fndecl)
|
|||
{
|
||||
if (int_size_in_bytes (TREE_TYPE (parms)) < 0)
|
||||
return N_("function with varying-size parameter cannot be inline");
|
||||
else if (TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
|
||||
else if (TREE_CODE (TREE_TYPE (parms)) == UNION_TYPE
|
||||
&& TYPE_TRANSPARENT_UNION (TREE_TYPE (parms)))
|
||||
return N_("function with transparent unit parameter cannot be inline");
|
||||
}
|
||||
|
||||
|
|
|
@ -1173,9 +1173,6 @@ finish_record_layout (rli)
|
|||
rli->pending_statics = TREE_CHAIN (rli->pending_statics);
|
||||
}
|
||||
|
||||
/* Show any alias subsetting we need. */
|
||||
record_component_aliases (rli->t);
|
||||
|
||||
/* Clean up. */
|
||||
free (rli);
|
||||
}
|
||||
|
|
47
gcc/tree.h
47
gcc/tree.h
|
@ -671,7 +671,7 @@ extern void tree_class_check_failed PARAMS ((const tree, char,
|
|||
|
||||
struct tree_int_cst
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
struct rtx_def *rtl; /* acts as link to register transfer language
|
||||
(rtl) info */
|
||||
unsigned HOST_WIDE_INT int_cst_low;
|
||||
|
@ -695,7 +695,7 @@ struct tree_int_cst
|
|||
|
||||
struct tree_real_cst
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
struct rtx_def *rtl; /* acts as link to register transfer language
|
||||
(rtl) info */
|
||||
REAL_VALUE_TYPE real_cst;
|
||||
|
@ -707,7 +707,7 @@ struct tree_real_cst
|
|||
|
||||
struct tree_string
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
struct rtx_def *rtl; /* acts as link to register transfer language
|
||||
(rtl) info */
|
||||
int length;
|
||||
|
@ -720,7 +720,7 @@ struct tree_string
|
|||
|
||||
struct tree_complex
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
struct rtx_def *rtl; /* acts as link to register transfer language
|
||||
(rtl) info */
|
||||
union tree_node *real;
|
||||
|
@ -734,7 +734,7 @@ struct tree_complex
|
|||
|
||||
struct tree_identifier
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
int length;
|
||||
char *pointer;
|
||||
};
|
||||
|
@ -745,7 +745,7 @@ struct tree_identifier
|
|||
|
||||
struct tree_list
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
union tree_node *purpose;
|
||||
union tree_node *value;
|
||||
};
|
||||
|
@ -757,7 +757,7 @@ struct tree_list
|
|||
|
||||
struct tree_vec
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
int length;
|
||||
union tree_node *a[1];
|
||||
};
|
||||
|
@ -813,7 +813,7 @@ struct tree_vec
|
|||
|
||||
struct tree_exp
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
int complexity;
|
||||
union tree_node *operands[1];
|
||||
};
|
||||
|
@ -839,7 +839,7 @@ struct tree_exp
|
|||
|
||||
struct tree_block
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
|
||||
unsigned handler_block_flag : 1;
|
||||
unsigned abstract_flag : 1;
|
||||
|
@ -1007,11 +1007,18 @@ struct tree_block
|
|||
|
||||
/* Indicates that objects of this type must be initialized by calling a
|
||||
function when they are created. */
|
||||
#define TYPE_NEEDS_CONSTRUCTING(NODE) (TYPE_CHECK (NODE)->type.needs_constructing_flag)
|
||||
#define TYPE_NEEDS_CONSTRUCTING(NODE) \
|
||||
(TYPE_CHECK (NODE)->type.needs_constructing_flag)
|
||||
|
||||
/* Indicates that objects of this type (a UNION_TYPE), should be passed
|
||||
the same way that the first union alternative would be passed. */
|
||||
#define TYPE_TRANSPARENT_UNION(NODE) (TYPE_CHECK (NODE)->type.transparent_union_flag)
|
||||
#define TYPE_TRANSPARENT_UNION(NODE) \
|
||||
(UNION_TYPE_CHECK (NODE)->type.transparent_union_flag)
|
||||
|
||||
/* For an ARRAY_TYPE, indicates that it is not permitted to
|
||||
take the address of a component of the type. */
|
||||
#define TYPE_NONALIASED_COMPONENT(NODE) \
|
||||
(ARRAY_TYPE_CHECK (NODE)->type.transparent_union_flag)
|
||||
|
||||
/* Indicated that objects of this type should be laid out in as
|
||||
compact a way as possible. */
|
||||
|
@ -1070,15 +1077,15 @@ struct tree_block
|
|||
default_pointer_boundedness at the time TYPE was created. It is
|
||||
useful for choosing default boundedness of function arguments for
|
||||
non-prototype function decls and for varargs/stdarg lists. */
|
||||
|
||||
#define TYPE_AMBIENT_BOUNDEDNESS(TYPE) (TYPE_CHECK (TYPE)->type.transparent_union_flag)
|
||||
#define TYPE_AMBIENT_BOUNDEDNESS(TYPE) \
|
||||
(FUNCTION_TYPE_CHECK (TYPE)->type.transparent_union_flag)
|
||||
|
||||
#define MAX_POINTER_DEPTH 2
|
||||
#define VA_LIST_POINTER_DEPTH 3
|
||||
|
||||
struct tree_type
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
union tree_node *values;
|
||||
union tree_node *size;
|
||||
union tree_node *size_unit;
|
||||
|
@ -1522,6 +1529,11 @@ struct tree_type
|
|||
an address constant. */
|
||||
#define DECL_NON_ADDR_CONST_P(NODE) (DECL_CHECK (NODE)->decl.non_addr_const_p)
|
||||
|
||||
/* Used in a FIELD_DECL to indicate that we cannot form the address of
|
||||
this component. */
|
||||
#define DECL_NONADDRESSABLE_P(NODE) \
|
||||
(FIELD_DECL_CHECK (NODE)->decl.non_addressable)
|
||||
|
||||
/* Used to indicate an alias set for the memory pointed to by this
|
||||
particular FIELD_DECL, PARM_DECL, or VAR_DECL, which must have
|
||||
pointer (or reference) type. */
|
||||
|
@ -1544,7 +1556,7 @@ struct tree_type
|
|||
|
||||
struct tree_decl
|
||||
{
|
||||
char common[sizeof (struct tree_common)];
|
||||
struct tree_common common;
|
||||
const char *filename;
|
||||
int linenum;
|
||||
unsigned int uid;
|
||||
|
@ -1575,9 +1587,12 @@ struct tree_decl
|
|||
unsigned comdat_flag : 1;
|
||||
unsigned malloc_flag : 1;
|
||||
unsigned no_limit_stack : 1;
|
||||
unsigned pure_flag : 1;
|
||||
ENUM_BITFIELD(built_in_class) built_in_class : 2;
|
||||
|
||||
unsigned pure_flag : 1;
|
||||
unsigned pointer_depth : 2;
|
||||
unsigned non_addressable : 1;
|
||||
/* Four unused bits. */
|
||||
|
||||
unsigned lang_flag_0 : 1;
|
||||
unsigned lang_flag_1 : 1;
|
||||
|
|
Loading…
Reference in New Issue