(TYPE_HASH): Move definition to top of file.

(make_node): Add support for SET_DEFAULT_TYPE_ATTRIBUTES.
(build_type_attribute_variant): New function.
(type_hash_lookup): Check if the attributes match.
(attribute_list_{equal,contained}): New functions.

From-SVN: r7253
This commit is contained in:
Richard Kenner 1994-05-06 18:29:26 -04:00
parent 660b43c865
commit 91e97eb8cb
1 changed files with 109 additions and 4 deletions

View File

@ -257,6 +257,10 @@ static int next_decl_uid;
/* Unique id for next type created. */
static int next_type_uid = 1;
/* Here is how primitive or already-canonicalized types' hash
codes are made. */
#define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777)
extern char *mode_name[];
void gcc_obstack_init ();
@ -999,6 +1003,10 @@ make_node (code)
TYPE_ALIGN (t) = 1;
TYPE_MAIN_VARIANT (t) = t;
TYPE_OBSTACK (t) = obstack;
TYPE_ATTRIBUTES (t) = NULL_TREE;
#ifdef SET_DEFAULT_TYPE_ATTRIBUTES
SET_DEFAULT_TYPE_ATTRIBUTES (t);
#endif
break;
case 'c':
@ -2696,6 +2704,65 @@ build_block (vars, tags, subblocks, supercontext, chain)
return block;
}
/* Return a type like TTYPE except that its TYPE_ATTRIBUTE
is ATTRIBUTE.
Such modified types already made are recorded so that duplicates
are not made. */
tree
build_type_attribute_variant (ttype, attribute)
tree ttype, attribute;
{
if ( ! attribute_list_equal (TYPE_ATTRIBUTES (ttype), attribute))
{
register int hashcode;
register struct obstack *ambient_obstack = current_obstack;
tree ntype;
if (ambient_obstack != &permanent_obstack)
current_obstack = TYPE_OBSTACK (ttype);
ntype = copy_node (ttype);
current_obstack = ambient_obstack;
TYPE_POINTER_TO (ntype) = 0;
TYPE_REFERENCE_TO (ntype) = 0;
TYPE_ATTRIBUTES (ntype) = attribute;
/* Create a new main variant of TYPE. */
TYPE_MAIN_VARIANT (ntype) = ntype;
TYPE_NEXT_VARIANT (ntype) = 0;
TYPE_READONLY (ntype) = TYPE_VOLATILE (ntype) = 0;
hashcode = TYPE_HASH (TREE_CODE (ntype))
+ TYPE_HASH (TREE_TYPE (ntype))
+ type_hash_list (attribute);
switch (TREE_CODE (ntype))
{
case FUNCTION_TYPE:
hashcode += TYPE_HASH (TYPE_ARG_TYPES (ntype));
break;
case ARRAY_TYPE:
hashcode += TYPE_HASH (TYPE_DOMAIN (ntype));
break;
case INTEGER_TYPE:
hashcode += TYPE_HASH (TYPE_MAX_VALUE (ntype));
break;
case REAL_TYPE:
hashcode += TYPE_HASH (TYPE_PRECISION (ntype));
break;
}
ntype = type_hash_canon (hashcode, ntype);
ttype = build_type_variant (ntype, TYPE_READONLY (ttype),
TYPE_VOLATILE (ttype));
}
return ttype;
}
/* Return a type like TYPE except that its TYPE_READONLY is CONSTP
and its TYPE_VOLATILE is VOLATILEP.
@ -2818,10 +2885,6 @@ struct type_hash
#define TYPE_HASH_SIZE 59
struct type_hash *type_hash_table[TYPE_HASH_SIZE];
/* Here is how primitive or already-canonicalized types' hash
codes are made. */
#define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777)
/* Compute a hash code for a list of types (chain of TREE_LIST nodes
with types in the TREE_VALUE slots), by adding the hash codes
of the individual types. */
@ -2850,6 +2913,8 @@ type_hash_lookup (hashcode, type)
if (h->hashcode == hashcode
&& TREE_CODE (h->type) == TREE_CODE (type)
&& TREE_TYPE (h->type) == TREE_TYPE (type)
&& attribute_list_equal (TYPE_ATTRIBUTES (h->type),
TYPE_ATTRIBUTES (type))
&& (TYPE_MAX_VALUE (h->type) == TYPE_MAX_VALUE (type)
|| tree_int_cst_equal (TYPE_MAX_VALUE (h->type),
TYPE_MAX_VALUE (type)))
@ -2925,6 +2990,46 @@ type_hash_canon (hashcode, type)
return type;
}
/* Given two lists of attributes, return true if list l2 is
equivalent to l1. */
int
attribute_list_equal (l1, l2)
tree l1, l2;
{
return attribute_list_contained (l1, l2)
&& attribute_list_contained (l2, l1);
}
/* Given two lists of attributes, return true if list l2 is
completely contained within l1. */
int
attribute_list_contained (l1, l2)
tree l1, l2;
{
register tree t1, t2;
/* First check the obvious, maybe the lists are identical. */
if (l1 == l2)
return 1;
/* Then check the obvious, maybe the lists are similar. */
for (t1 = l1, t2 = l2;
t1 && t2
&& TREE_VALUE (t1) == TREE_VALUE (t2);
t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2));
/* Maybe the lists are equal. */
if (t1 == 0 && t2 == 0)
return 1;
for (; t2; t2 = TREE_CHAIN (t2))
if (!value_member (l1, t2))
return 0;
return 1;
}
/* Given two lists of types
(chains of TREE_LIST nodes with types in the TREE_VALUE slots)
return 1 if the lists contain the same types in the same order.