aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1994-05-06 18:29:26 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1994-05-06 18:29:26 -0400
commit91e97eb8cb646cd6e29794945ee27cd1fd10658b (patch)
tree5db5b77f8edc181f58dcf075e29cef02ad4e0d6e
parent660b43c8658a5a87bceb90721115b30381affd22 (diff)
downloadgcc-91e97eb8cb646cd6e29794945ee27cd1fd10658b.zip
gcc-91e97eb8cb646cd6e29794945ee27cd1fd10658b.tar.gz
gcc-91e97eb8cb646cd6e29794945ee27cd1fd10658b.tar.bz2
(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
-rw-r--r--gcc/tree.c113
1 files changed, 109 insertions, 4 deletions
diff --git a/gcc/tree.c b/gcc/tree.c
index 0c6e686..6e15640 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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.