aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/ada/ChangeLog15
-rw-r--r--gcc/ada/gcc-interface/decl.c12
-rw-r--r--gcc/ada/gcc-interface/gigi.h3
-rw-r--r--gcc/ada/gcc-interface/misc.c21
-rw-r--r--gcc/ada/gcc-interface/utils.c52
-rw-r--r--gcc/langhooks-def.h4
-rw-r--r--gcc/langhooks.h5
-rw-r--r--gcc/system.h2
-rw-r--r--gcc/tree.c86
-rw-r--r--gcc/tree.h2
11 files changed, 146 insertions, 73 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4e6b97c..faf3d0b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+2010-09-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * langhooks.h (struct lang_hooks_for_types): Remove hash_types field.
+ * langhooks-def.h (LANG_HOOKS_HASH_TYPES): Delete.
+ (LANG_HOOKS_FOR_TYPES_INITIALIZER): Remove LANG_HOOKS_HASH_TYPES.
+ * system.h (LANG_HOOKS_HASH_TYPES): Poison.
+ * tree.c (type_hash_canon): Do not test lang_hooks.types.hash_types.
+ (build_nonstandard_integer_type): Likewise.
+ (build_range_type_1): New function, built from...
+ (build_range_type): ...this. Call build_range_type_1.
+ (build_nonshared_range_type): New function.
+ (build_array_type_1): New function, built from...
+ (build_array_type: ...this. Call build_array_type_1.
+ (build_nonshared_array_type): New function.
+ * tree.h (build_nonshared_range_type): Declare.
+ (build_nonshared_array_type): Likewise.
+
2010-09-20 Anatoly Sokolov <aesok@post.ru>
* config/arm/arm.h (CLASS_LIKELY_SPILLED_P): Remove.
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 4db1391..15100f6 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,18 @@
+2010-09-20 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gcc-interface/decl.c (gnat_to_gnu_entity): Replace calls to
+ build_array_type with calls to build_nonshared_array_type.
+ (substitute_in_type): Likewise.
+ * gcc-interface/misc.c (LANG_HOOKS_HASH_TYPES): Delete.
+ (LANG_HOOKS_TYPE_HASH_EQ): Define.
+ (gnat_post_options): Add 'static' keyword.
+ (gnat_type_hash_eq): New static function.
+ * gcc-interface/utils.c (fntype_same_flags_p): New function.
+ (create_subprog_type): Call it.
+ (create_index_type): Call build_nonshared_range_type and tidy up.
+ (create_range_type): Likewise.
+ * gcc-interface/gigi.h (fntype_same_flags_p): Declare.
+
2010-09-19 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/trans.c (gnat_pushdecl): Do not do anything special
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index c9ca2a6..0669875 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -2070,7 +2070,7 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Now build the array type. */
for (index = ndim - 1; index >= 0; index--)
{
- tem = build_array_type (tem, gnu_index_types[index]);
+ tem = build_nonshared_array_type (tem, gnu_index_types[index]);
TYPE_MULTI_ARRAY_P (tem) = (index > 0);
if (array_type_has_nonaliased_component (tem, gnat_entity))
TYPE_NONALIASED_COMPONENT (tem) = 1;
@@ -2403,7 +2403,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
/* Now build the array type. */
for (index = ndim - 1; index >= 0; index --)
{
- gnu_type = build_array_type (gnu_type, gnu_index_types[index]);
+ gnu_type = build_nonshared_array_type (gnu_type,
+ gnu_index_types[index]);
TYPE_MULTI_ARRAY_P (gnu_type) = (index > 0);
if (array_type_has_nonaliased_component (gnu_type, gnat_entity))
TYPE_NONALIASED_COMPONENT (gnu_type) = 1;
@@ -2649,8 +2650,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entity, tree gnu_expr, int definition)
gnat_entity);
gnu_type
- = build_array_type (gnat_to_gnu_type (Component_Type (gnat_entity)),
- gnu_index_type);
+ = build_nonshared_array_type (gnat_to_gnu_type
+ (Component_Type (gnat_entity)),
+ gnu_index_type);
if (array_type_has_nonaliased_component (gnu_type, gnat_entity))
TYPE_NONALIASED_COMPONENT (gnu_type) = 1;
relate_alias_sets (gnu_type, gnu_string_type, ALIAS_SET_COPY);
@@ -8610,7 +8612,7 @@ substitute_in_type (tree t, tree f, tree r)
if (component == TREE_TYPE (t) && domain == TYPE_DOMAIN (t))
return t;
- nt = build_array_type (component, domain);
+ nt = build_nonshared_array_type (component, domain);
TYPE_ALIGN (nt) = TYPE_ALIGN (t);
TYPE_USER_ALIGN (nt) = TYPE_USER_ALIGN (t);
SET_TYPE_MODE (nt, TYPE_MODE (t));
diff --git a/gcc/ada/gcc-interface/gigi.h b/gcc/ada/gcc-interface/gigi.h
index b464cac..dd30b24 100644
--- a/gcc/ada/gcc-interface/gigi.h
+++ b/gcc/ada/gcc-interface/gigi.h
@@ -447,6 +447,9 @@ extern tree gnat_signed_type (tree type_node);
transparently converted to each other. */
extern int gnat_types_compatible_p (tree t1, tree t2);
+/* Return true if T, a FUNCTION_TYPE, has the specified list of flags. */
+extern bool fntype_same_flags_p (const_tree, tree, bool, bool, bool);
+
/* Create an expression whose value is that of EXPR,
converted to type TYPE. The TREE_TYPE of the value
is always TYPE. This function implements all reasonable
diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c
index 080e988..1167f03 100644
--- a/gcc/ada/gcc-interface/misc.c
+++ b/gcc/ada/gcc-interface/misc.c
@@ -72,6 +72,7 @@ static void gnat_print_decl (FILE *, tree, int);
static void gnat_print_type (FILE *, tree, int);
static const char *gnat_printable_name (tree, int);
static const char *gnat_dwarf_name (tree, int);
+static bool gnat_type_hash_eq (const_tree, const_tree);
static tree gnat_return_tree (tree);
static void gnat_parse_file (int);
static void internal_error_function (diagnostic_context *,
@@ -98,8 +99,8 @@ static tree gnat_eh_personality (void);
#define LANG_HOOKS_POST_OPTIONS gnat_post_options
#undef LANG_HOOKS_PARSE_FILE
#define LANG_HOOKS_PARSE_FILE gnat_parse_file
-#undef LANG_HOOKS_HASH_TYPES
-#define LANG_HOOKS_HASH_TYPES false
+#undef LANG_HOOKS_TYPE_HASH_EQ
+#define LANG_HOOKS_TYPE_HASH_EQ gnat_type_hash_eq
#undef LANG_HOOKS_GETDECLS
#define LANG_HOOKS_GETDECLS lhd_return_null_tree_v
#undef LANG_HOOKS_PUSHDECL
@@ -304,7 +305,7 @@ gnat_init_options (unsigned int decoded_options_count,
/* Post-switch processing. */
-bool
+static bool
gnat_post_options (const char **pfilename ATTRIBUTE_UNUSED)
{
/* Excess precision other than "fast" requires front-end
@@ -595,6 +596,20 @@ gnat_dwarf_name (tree decl, int verbosity ATTRIBUTE_UNUSED)
return (const char *) IDENTIFIER_POINTER (DECL_NAME (decl));
}
+/* Return true if types T1 and T2 are identical for type hashing purposes.
+ Called only after doing all language independent checks. At present,
+ this function is only called when both types are FUNCTION_TYPE. */
+
+static bool
+gnat_type_hash_eq (const_tree t1, const_tree t2)
+{
+ gcc_assert (TREE_CODE (t1) == FUNCTION_TYPE);
+ return fntype_same_flags_p (t1, TYPE_CI_CO_LIST (t2),
+ TYPE_RETURN_UNCONSTRAINED_P (t2),
+ TYPE_RETURN_BY_DIRECT_REF_P (t2),
+ TREE_ADDRESSABLE (t2));
+}
+
/* Do nothing (return the tree node passed). */
static tree
diff --git a/gcc/ada/gcc-interface/utils.c b/gcc/ada/gcc-interface/utils.c
index e1f7aab..3fab92b 100644
--- a/gcc/ada/gcc-interface/utils.c
+++ b/gcc/ada/gcc-interface/utils.c
@@ -1106,10 +1106,8 @@ create_subprog_type (tree return_type, tree param_decl_list, tree cico_list,
/* TYPE may have been shared since GCC hashes types. If it has a different
CICO_LIST, make a copy. Likewise for the various flags. */
- if (TYPE_CI_CO_LIST (type) != cico_list
- || TYPE_RETURN_UNCONSTRAINED_P (type) != return_unconstrained_p
- || TYPE_RETURN_BY_DIRECT_REF_P (type) != return_by_direct_ref_p
- || TREE_ADDRESSABLE (type) != return_by_invisi_ref_p)
+ if (!fntype_same_flags_p (type, cico_list, return_unconstrained_p,
+ return_by_direct_ref_p, return_by_invisi_ref_p))
{
type = copy_type (type);
TYPE_CI_CO_LIST (type) = cico_list;
@@ -1165,17 +1163,9 @@ tree
create_index_type (tree min, tree max, tree index, Node_Id gnat_node)
{
/* First build a type for the desired range. */
- tree type = build_range_type (sizetype, min, max);
-
- /* If this type has the TYPE_INDEX_TYPE we want, return it. */
- if (TYPE_INDEX_TYPE (type) == index)
- return type;
-
- /* Otherwise, if TYPE_INDEX_TYPE is set, make a copy. Note that we have
- no way of sharing these types, but that's only a small hole. */
- if (TYPE_INDEX_TYPE (type))
- type = copy_type (type);
+ tree type = build_nonshared_range_type (sizetype, min, max);
+ /* Then set the index type. */
SET_TYPE_INDEX_TYPE (type, index);
create_type_decl (NULL_TREE, type, NULL, true, false, gnat_node);
@@ -1194,26 +1184,12 @@ create_range_type (tree type, tree min, tree max)
type = sizetype;
/* First build a type with the base range. */
- range_type
- = build_range_type (type, TYPE_MIN_VALUE (type), TYPE_MAX_VALUE (type));
-
- min = convert (type, min);
- max = convert (type, max);
-
- /* If this type has the TYPE_RM_{MIN,MAX}_VALUE we want, return it. */
- if (TYPE_RM_MIN_VALUE (range_type)
- && TYPE_RM_MAX_VALUE (range_type)
- && operand_equal_p (TYPE_RM_MIN_VALUE (range_type), min, 0)
- && operand_equal_p (TYPE_RM_MAX_VALUE (range_type), max, 0))
- return range_type;
-
- /* Otherwise, if TYPE_RM_{MIN,MAX}_VALUE is set, make a copy. */
- if (TYPE_RM_MIN_VALUE (range_type) || TYPE_RM_MAX_VALUE (range_type))
- range_type = copy_type (range_type);
+ range_type = build_nonshared_range_type (type, TYPE_MIN_VALUE (type),
+ TYPE_MAX_VALUE (type));
/* Then set the actual range. */
- SET_TYPE_RM_MIN_VALUE (range_type, min);
- SET_TYPE_RM_MAX_VALUE (range_type, max);
+ SET_TYPE_RM_MIN_VALUE (range_type, convert (type, min));
+ SET_TYPE_RM_MAX_VALUE (range_type, convert (type, max));
return range_type;
}
@@ -2121,6 +2097,18 @@ gnat_types_compatible_p (tree t1, tree t2)
return 0;
}
+
+/* Return true if T, a FUNCTION_TYPE, has the specified list of flags. */
+
+bool
+fntype_same_flags_p (const_tree t, tree cico_list, bool return_unconstrained_p,
+ bool return_by_direct_ref_p, bool return_by_invisi_ref_p)
+{
+ return TYPE_CI_CO_LIST (t) == cico_list
+ && TYPE_RETURN_UNCONSTRAINED_P (t) == return_unconstrained_p
+ && TYPE_RETURN_BY_DIRECT_REF_P (t) == return_by_direct_ref_p
+ && TREE_ADDRESSABLE (t) == return_by_invisi_ref_p;
+}
/* EXP is an expression for the size of an object. If this size contains
discriminant references, replace them with the maximum (if MAX_P) or
diff --git a/gcc/langhooks-def.h b/gcc/langhooks-def.h
index c89763b..a4dda6b 100644
--- a/gcc/langhooks-def.h
+++ b/gcc/langhooks-def.h
@@ -178,7 +178,6 @@ extern tree lhd_make_node (enum tree_code);
#define LANG_HOOKS_GET_ARRAY_DESCR_INFO NULL
#define LANG_HOOKS_GET_SUBRANGE_BOUNDS NULL
#define LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE reconstruct_complex_type
-#define LANG_HOOKS_HASH_TYPES true
#define LANG_HOOKS_FOR_TYPES_INITIALIZER { \
LANG_HOOKS_MAKE_TYPE, \
@@ -195,8 +194,7 @@ extern tree lhd_make_node (enum tree_code);
LANG_HOOKS_TYPE_HASH_EQ, \
LANG_HOOKS_GET_ARRAY_DESCR_INFO, \
LANG_HOOKS_GET_SUBRANGE_BOUNDS, \
- LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE, \
- LANG_HOOKS_HASH_TYPES \
+ LANG_HOOKS_RECONSTRUCT_COMPLEX_TYPE \
}
/* Declaration hooks. */
diff --git a/gcc/langhooks.h b/gcc/langhooks.h
index 87bac28..eb8b8fc 100644
--- a/gcc/langhooks.h
+++ b/gcc/langhooks.h
@@ -138,11 +138,6 @@ struct lang_hooks_for_types
return values from functions. The argument TYPE is the top of the
chain, and BOTTOM is the new type which we will point to. */
tree (*reconstruct_complex_type) (tree, tree);
-
- /* Nonzero if types that are identical are to be hashed so that only
- one copy is kept. If a language requires unique types for each
- user-specified type, such as Ada, this should be set to TRUE. */
- bool hash_types;
};
/* Language hooks related to decls and the symbol table. */
diff --git a/gcc/system.h b/gcc/system.h
index 8928ce6..178eec0 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -781,7 +781,7 @@ extern void fancy_abort (const char *, int, const char *) ATTRIBUTE_NORETURN;
LANG_HOOKS_MAYBE_BUILD_CLEANUP LANG_HOOKS_UPDATE_DECL_AFTER_SAVING \
LANG_HOOKS_POPLEVEL LANG_HOOKS_TRUTHVALUE_CONVERSION \
TARGET_PROMOTE_FUNCTION_ARGS TARGET_PROMOTE_FUNCTION_RETURN \
- LANG_HOOKS_MISSING_ARGUMENT
+ LANG_HOOKS_MISSING_ARGUMENT LANG_HOOKS_HASH_TYPES
/* Miscellaneous macros that are no longer used. */
#pragma GCC poison USE_MAPPED_LOCATION
diff --git a/gcc/tree.c b/gcc/tree.c
index 7746628..8423416 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -6123,9 +6123,6 @@ type_hash_canon (unsigned int hashcode, tree type)
being passed. */
gcc_assert (TYPE_MAIN_VARIANT (type) == type);
- if (!lang_hooks.types.hash_types)
- return type;
-
/* See if the type is in the hash table already. If so, return it.
Otherwise, add the type. */
t1 = type_hash_lookup (hashcode, type);
@@ -7093,21 +7090,20 @@ build_nonstandard_integer_type (unsigned HOST_WIDE_INT precision,
ret = itype;
if (host_integerp (TYPE_MAX_VALUE (itype), 1))
ret = type_hash_canon (tree_low_cst (TYPE_MAX_VALUE (itype), 1), itype);
- if (precision <= MAX_INT_CACHED_PREC && lang_hooks.types.hash_types)
+ if (precision <= MAX_INT_CACHED_PREC)
nonstandard_integer_type_cache[precision + unsignedp] = ret;
return ret;
}
-/* Create a range of some discrete type TYPE (an INTEGER_TYPE,
- ENUMERAL_TYPE or BOOLEAN_TYPE), with low bound LOWVAL and
- high bound HIGHVAL. */
+/* Create a range of some discrete type TYPE (an INTEGER_TYPE, ENUMERAL_TYPE
+ or BOOLEAN_TYPE) with low bound LOWVAL and high bound HIGHVAL. If SHARED
+ is true, reuse such a type that has already been constructed. */
-tree
-build_range_type (tree type, tree lowval, tree highval)
+static tree
+build_range_type_1 (tree type, tree lowval, tree highval, bool shared)
{
tree itype = make_node (INTEGER_TYPE);
- hashval_t hash;
TREE_TYPE (itype) = type;
@@ -7131,10 +7127,32 @@ build_range_type (tree type, tree lowval, tree highval)
SET_TYPE_STRUCTURAL_EQUALITY (itype);
return itype;
}
- hash = iterative_hash_expr (TYPE_MIN_VALUE (itype), 0);
- hash = iterative_hash_expr (TYPE_MAX_VALUE (itype), hash);
- hash = iterative_hash_hashval_t (TYPE_HASH (type), hash);
- return type_hash_canon (hash, itype);
+
+ if (shared)
+ {
+ hashval_t hash = iterative_hash_expr (TYPE_MIN_VALUE (itype), 0);
+ hash = iterative_hash_expr (TYPE_MAX_VALUE (itype), hash);
+ hash = iterative_hash_hashval_t (TYPE_HASH (type), hash);
+ itype = type_hash_canon (hash, itype);
+ }
+
+ return itype;
+}
+
+/* Wrapper around build_range_type_1 with SHARED set to true. */
+
+tree
+build_range_type (tree type, tree lowval, tree highval)
+{
+ return build_range_type_1 (type, lowval, highval, true);
+}
+
+/* Wrapper around build_range_type_1 with SHARED set to false. */
+
+tree
+build_nonshared_range_type (tree type, tree lowval, tree highval)
+{
+ return build_range_type_1 (type, lowval, highval, false);
}
/* Create a type of integers to be the TYPE_DOMAIN of an ARRAY_TYPE.
@@ -7205,13 +7223,12 @@ subrange_type_for_debug_p (const_tree type, tree *lowval, tree *highval)
/* Construct, lay out and return the type of arrays of elements with ELT_TYPE
and number of elements specified by the range of values of INDEX_TYPE.
- If such a type has already been constructed, reuse it. */
+ If SHARED is true, reuse such a type that has already been constructed. */
-tree
-build_array_type (tree elt_type, tree index_type)
+static tree
+build_array_type_1 (tree elt_type, tree index_type, bool shared)
{
tree t;
- hashval_t hashcode = 0;
if (TREE_CODE (elt_type) == FUNCTION_TYPE)
{
@@ -7231,10 +7248,13 @@ build_array_type (tree elt_type, tree index_type)
if (TYPE_STRUCTURAL_EQUALITY_P (t))
return t;
- hashcode = iterative_hash_object (TYPE_HASH (elt_type), hashcode);
- if (index_type)
- hashcode = iterative_hash_object (TYPE_HASH (index_type), hashcode);
- t = type_hash_canon (hashcode, t);
+ if (shared)
+ {
+ hashval_t hashcode = iterative_hash_object (TYPE_HASH (elt_type), 0);
+ if (index_type)
+ hashcode = iterative_hash_object (TYPE_HASH (index_type), hashcode);
+ t = type_hash_canon (hashcode, t);
+ }
if (TYPE_CANONICAL (t) == t)
{
@@ -7244,13 +7264,31 @@ build_array_type (tree elt_type, tree index_type)
else if (TYPE_CANONICAL (elt_type) != elt_type
|| (index_type && TYPE_CANONICAL (index_type) != index_type))
TYPE_CANONICAL (t)
- = build_array_type (TYPE_CANONICAL (elt_type),
- index_type ? TYPE_CANONICAL (index_type) : NULL);
+ = build_array_type_1 (TYPE_CANONICAL (elt_type),
+ index_type
+ ? TYPE_CANONICAL (index_type) : NULL_TREE,
+ shared);
}
return t;
}
+/* Wrapper around build_array_type_1 with SHARED set to true. */
+
+tree
+build_array_type (tree elt_type, tree index_type)
+{
+ return build_array_type_1 (elt_type, index_type, true);
+}
+
+/* Wrapper around build_array_type_1 with SHARED set to false. */
+
+tree
+build_nonshared_array_type (tree elt_type, tree index_type)
+{
+ return build_array_type_1 (elt_type, index_type, false);
+}
+
/* Recursively examines the array elements of TYPE, until a non-array
element type is found. */
diff --git a/gcc/tree.h b/gcc/tree.h
index 1ff9d35..e7d0c53 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -4102,6 +4102,7 @@ extern tree build_opaque_vector_type (tree innertype, int nunits);
extern tree build_type_no_quals (tree);
extern tree build_index_type (tree);
extern tree build_array_type (tree, tree);
+extern tree build_nonshared_array_type (tree, tree);
extern tree build_function_type (tree, tree);
extern tree build_function_type_list (tree, ...);
extern tree build_function_type_skip_args (tree, bitmap);
@@ -5127,6 +5128,7 @@ extern void build_common_tree_nodes_2 (int);
extern void build_common_builtin_nodes (void);
extern tree build_nonstandard_integer_type (unsigned HOST_WIDE_INT, int);
extern tree build_range_type (tree, tree, tree);
+extern tree build_nonshared_range_type (tree, tree, tree);
extern bool subrange_type_for_debug_p (const_tree, tree *, tree *);
extern HOST_WIDE_INT int_cst_value (const_tree);
extern HOST_WIDEST_INT widest_int_cst_value (const_tree);