2
0
mirror of git://gcc.gnu.org/git/gcc.git synced 2025-03-24 12:31:25 +08:00

langhooks.h (struct lang_hooks_for_types): Remove hash_types field.

* 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.
ada/
	* 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.

From-SVN: r164452
This commit is contained in:
Eric Botcazou 2010-09-20 20:11:35 +00:00 committed by Eric Botcazou
parent 8d03ad011a
commit 523e82a7a3
11 changed files with 146 additions and 73 deletions

@ -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.

@ -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

@ -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));

@ -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

@ -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

@ -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

@ -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. */

@ -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. */

@ -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

@ -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. */

@ -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);