lto-streamer-in.c (lto_read_body_or_constructor): Set TYPE_CANONICAL only for types where LTO sets them.

* lto-streamer-in.c (lto_read_body_or_constructor): Set TYPE_CANONICAL
	only for types where LTO sets them.
	* tree.c (build_array_type_1): Do ont set TYPE_CANONICAL for LTO.
	(make_vector_type): Likewise.
	(gimple_canonical_types_compatible_p): Use canonical_type_used_p.
	* tree.h (canonical_type_used_p): New inline.
	* alias.c (get_alias_set): Handle structural equality for all
	types that pass canonical_type_used_p.
	(record_component_aliases): Look through all types with
	record_component_aliases for possible pointers; sanity check that
	the alias sets match.

	* lto.c (iterative_hash_canonical_type): Recruse for all types
	which pass !canonical_type_used_p.
	(gimple_register_canonical_type_1): Sanity check we do not compute
	canonical type of anything with !canonical_type_used_p.
	(gimple_register_canonical_type): Skip all types that are
	!canonical_type_used_p

From-SVN: r230835
This commit is contained in:
Jan Hubicka 2015-11-24 20:35:38 +01:00 committed by Jan Hubicka
parent 73c923307b
commit aea50b45f5
7 changed files with 76 additions and 23 deletions

View File

@ -1,3 +1,17 @@
2015-11-24 Jan Hubicka <hubicka@ucw.cz>
* lto-streamer-in.c (lto_read_body_or_constructor): Set TYPE_CANONICAL
only for types where LTO sets them.
* tree.c (build_array_type_1): Do ont set TYPE_CANONICAL for LTO.
(make_vector_type): Likewise.
(gimple_canonical_types_compatible_p): Use canonical_type_used_p.
* tree.h (canonical_type_used_p): New inline.
* alias.c (get_alias_set): Handle structural equality for all
types that pass canonical_type_used_p.
(record_component_aliases): Look through all types with
record_component_aliases for possible pointers; sanity check that
the alias sets match.
2015-11-24 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.md (lround<mode>di2): Remove constraints.

View File

@ -869,11 +869,11 @@ get_alias_set (tree t)
set = lang_hooks.get_alias_set (t);
if (set != -1)
return set;
/* Handle structure type equality for pointer types. This is easy
to do, because the code bellow ignore canonical types on these anyway.
This is important for LTO, where TYPE_CANONICAL for pointers can not
be meaningfuly computed by the frotnend. */
if (!POINTER_TYPE_P (t))
/* Handle structure type equality for pointer types, arrays and vectors.
This is easy to do, because the code bellow ignore canonical types on
these anyway. This is important for LTO, where TYPE_CANONICAL for
pointers can not be meaningfuly computed by the frotnend. */
if (canonical_type_used_p (t))
{
/* In LTO we set canonical types for all types where it makes
sense to do so. Double check we did not miss some type. */
@ -929,7 +929,9 @@ get_alias_set (tree t)
integer(kind=4)[4] the same alias set or not.
Just be pragmatic here and make sure the array and its element
type get the same alias set assigned. */
else if (TREE_CODE (t) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (t))
else if (TREE_CODE (t) == ARRAY_TYPE
&& (!TYPE_NONALIASED_COMPONENT (t)
|| TYPE_STRUCTURAL_EQUALITY_P (t)))
set = get_alias_set (TREE_TYPE (t));
/* From the former common C and C++ langhook implementation:
@ -971,7 +973,10 @@ get_alias_set (tree t)
We also want to make pointer to array/vector equivalent to pointer to
its element (see the reasoning above). Skip all those types, too. */
for (p = t; POINTER_TYPE_P (p)
|| (TREE_CODE (p) == ARRAY_TYPE && !TYPE_NONALIASED_COMPONENT (p))
|| (TREE_CODE (p) == ARRAY_TYPE
&& (!TYPE_NONALIASED_COMPONENT (p)
|| !COMPLETE_TYPE_P (p)
|| TYPE_STRUCTURAL_EQUALITY_P (p)))
|| TREE_CODE (p) == VECTOR_TYPE;
p = TREE_TYPE (p))
{
@ -1200,15 +1205,18 @@ record_component_aliases (tree type)
/* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
element type and that type has to be normalized to void *,
too, in the case it is a pointer. */
while ((TREE_CODE (t) == ARRAY_TYPE
&& (!COMPLETE_TYPE_P (t)
|| TYPE_NONALIASED_COMPONENT (t)))
|| TREE_CODE (t) == VECTOR_TYPE)
t = TREE_TYPE (t);
while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
{
gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
t = TREE_TYPE (t);
}
if (POINTER_TYPE_P (t))
t = ptr_type_node;
else if (flag_checking)
gcc_checking_assert (get_alias_set (t)
== get_alias_set (TREE_TYPE (field)));
}
record_alias_subset (superset, get_alias_set (t));
}
break;

View File

@ -1231,7 +1231,9 @@ lto_read_body_or_constructor (struct lto_file_decl_data *file_data, struct symta
if (TYPE_P (t))
{
gcc_assert (TYPE_CANONICAL (t) == NULL_TREE);
TYPE_CANONICAL (t) = TYPE_MAIN_VARIANT (t);
if (type_with_alias_set_p (t)
&& canonical_type_used_p (t))
TYPE_CANONICAL (t) = TYPE_MAIN_VARIANT (t);
if (TYPE_MAIN_VARIANT (t) != t)
{
gcc_assert (TYPE_NEXT_VARIANT (t) == NULL_TREE);

View File

@ -1,3 +1,12 @@
2015-11-24 Jan Hubicka <hubicka@ucw.cz>
* lto.c (iterative_hash_canonical_type): Recruse for all types
which pass !canonical_type_used_p.
(gimple_register_canonical_type_1): Sanity check we do not compute
canonical type of anything with !canonical_type_used_p.
(gimple_register_canonical_type): Skip all types that are
!canonical_type_used_p
2015-11-24 Jan Hubicka <hubicka@ucw.cz>
* lto.c (unify_scc): Use free_node.

View File

@ -389,9 +389,7 @@ iterative_hash_canonical_type (tree type, inchash::hash &hstate)
/* All type variants have same TYPE_CANONICAL. */
type = TYPE_MAIN_VARIANT (type);
/* We do not compute TYPE_CANONICAl of POINTER_TYPE because the aliasing
code never use it anyway. */
if (POINTER_TYPE_P (type))
if (!canonical_type_used_p (type))
v = hash_canonical_type (type);
/* An already processed type. */
else if (TYPE_CANONICAL (type))
@ -444,7 +442,7 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
gcc_checking_assert (TYPE_P (t) && !TYPE_CANONICAL (t)
&& type_with_alias_set_p (t)
&& !POINTER_TYPE_P (t));
&& canonical_type_used_p (t));
slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash, INSERT);
if (*slot)
@ -477,7 +475,8 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
static void
gimple_register_canonical_type (tree t)
{
if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t) || POINTER_TYPE_P (t))
if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t)
|| !canonical_type_used_p (t))
return;
/* Canonical types are same among all complete variants. */

View File

@ -8252,7 +8252,8 @@ build_array_type_1 (tree elt_type, tree index_type, bool shared)
if (TYPE_CANONICAL (t) == t)
{
if (TYPE_STRUCTURAL_EQUALITY_P (elt_type)
|| (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type)))
|| (index_type && TYPE_STRUCTURAL_EQUALITY_P (index_type))
|| in_lto_p)
SET_TYPE_STRUCTURAL_EQUALITY (t);
else if (TYPE_CANONICAL (elt_type) != elt_type
|| (index_type && TYPE_CANONICAL (index_type) != index_type))
@ -9865,7 +9866,7 @@ make_vector_type (tree innertype, int nunits, machine_mode mode)
SET_TYPE_VECTOR_SUBPARTS (t, nunits);
SET_TYPE_MODE (t, mode);
if (TYPE_STRUCTURAL_EQUALITY_P (innertype))
if (TYPE_STRUCTURAL_EQUALITY_P (innertype) || in_lto_p)
SET_TYPE_STRUCTURAL_EQUALITY (t);
else if ((TYPE_CANONICAL (innertype) != innertype
|| mode != VOIDmode)
@ -13295,7 +13296,8 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2,
TYPE_CANONICAL is more fine grained than the equivalnce we test (where
all pointers are considered equal. Be sure to not return false
negatives. */
gcc_checking_assert (!POINTER_TYPE_P (t1) && !POINTER_TYPE_P (t2));
gcc_checking_assert (canonical_type_used_p (t1)
&& canonical_type_used_p (t2));
return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
}

View File

@ -4811,7 +4811,9 @@ extern void DEBUG_FUNCTION verify_type (const_tree t);
extern bool gimple_canonical_types_compatible_p (const_tree, const_tree,
bool trust_type_canonical = true);
extern bool type_with_interoperable_signedness (const_tree);
/* Return simplified tree code of type that is used for canonical type merging. */
/* Return simplified tree code of type that is used for canonical type
merging. */
inline enum tree_code
tree_code_for_canonical_type_merging (enum tree_code code)
{
@ -4833,6 +4835,23 @@ tree_code_for_canonical_type_merging (enum tree_code code)
return code;
}
/* Return ture if get_alias_set care about TYPE_CANONICAL of given type.
We don't define the types for pointers, arrays and vectors. The reason is
that pointers are handled specially: ptr_type_node accesses conflict with
accesses to all other pointers. This is done by alias.c.
Because alias sets of arrays and vectors are the same as types of their
elements, we can't compute canonical type either. Otherwise we could go
form void *[10] to int *[10] (because they are equivalent for canonical type
machinery) and get wrong TBAA. */
inline bool
canonical_type_used_p (const_tree t)
{
return !(POINTER_TYPE_P (t)
|| TREE_CODE (t) == ARRAY_TYPE
|| TREE_CODE (t) == VECTOR_TYPE);
}
#define tree_map_eq tree_map_base_eq
extern unsigned int tree_map_hash (const void *);
#define tree_map_marked_p tree_map_base_marked_p