Commit aea50b45 by Jan Hubicka Committed by Jan Hubicka

lto-streamer-in.c (lto_read_body_or_constructor): Set TYPE_CANONICAL only for…

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
parent 73c92330
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> 2015-11-24 Michael Meissner <meissner@linux.vnet.ibm.com>
* config/rs6000/rs6000.md (lround<mode>di2): Remove constraints. * config/rs6000/rs6000.md (lround<mode>di2): Remove constraints.
...@@ -869,11 +869,11 @@ get_alias_set (tree t) ...@@ -869,11 +869,11 @@ get_alias_set (tree t)
set = lang_hooks.get_alias_set (t); set = lang_hooks.get_alias_set (t);
if (set != -1) if (set != -1)
return set; return set;
/* Handle structure type equality for pointer types. This is easy /* Handle structure type equality for pointer types, arrays and vectors.
to do, because the code bellow ignore canonical types on these anyway. This is easy to do, because the code bellow ignore canonical types on
This is important for LTO, where TYPE_CANONICAL for pointers can not these anyway. This is important for LTO, where TYPE_CANONICAL for
be meaningfuly computed by the frotnend. */ pointers can not be meaningfuly computed by the frotnend. */
if (!POINTER_TYPE_P (t)) if (canonical_type_used_p (t))
{ {
/* In LTO we set canonical types for all types where it makes /* In LTO we set canonical types for all types where it makes
sense to do so. Double check we did not miss some type. */ sense to do so. Double check we did not miss some type. */
...@@ -929,7 +929,9 @@ get_alias_set (tree t) ...@@ -929,7 +929,9 @@ get_alias_set (tree t)
integer(kind=4)[4] the same alias set or not. integer(kind=4)[4] the same alias set or not.
Just be pragmatic here and make sure the array and its element Just be pragmatic here and make sure the array and its element
type get the same alias set assigned. */ 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)); set = get_alias_set (TREE_TYPE (t));
/* From the former common C and C++ langhook implementation: /* From the former common C and C++ langhook implementation:
...@@ -971,7 +973,10 @@ get_alias_set (tree t) ...@@ -971,7 +973,10 @@ get_alias_set (tree t)
We also want to make pointer to array/vector equivalent to pointer to We also want to make pointer to array/vector equivalent to pointer to
its element (see the reasoning above). Skip all those types, too. */ its element (see the reasoning above). Skip all those types, too. */
for (p = t; POINTER_TYPE_P (p) 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; || TREE_CODE (p) == VECTOR_TYPE;
p = TREE_TYPE (p)) p = TREE_TYPE (p))
{ {
...@@ -1200,15 +1205,18 @@ record_component_aliases (tree type) ...@@ -1200,15 +1205,18 @@ record_component_aliases (tree type)
/* VECTOR_TYPE and ARRAY_TYPE share the alias set with their /* VECTOR_TYPE and ARRAY_TYPE share the alias set with their
element type and that type has to be normalized to void *, element type and that type has to be normalized to void *,
too, in the case it is a pointer. */ too, in the case it is a pointer. */
while ((TREE_CODE (t) == ARRAY_TYPE while (!canonical_type_used_p (t) && !POINTER_TYPE_P (t))
&& (!COMPLETE_TYPE_P (t) {
|| TYPE_NONALIASED_COMPONENT (t))) gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
|| TREE_CODE (t) == VECTOR_TYPE) t = TREE_TYPE (t);
t = TREE_TYPE (t); }
if (POINTER_TYPE_P (t)) if (POINTER_TYPE_P (t))
t = ptr_type_node; 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)); record_alias_subset (superset, get_alias_set (t));
} }
break; break;
......
...@@ -1231,7 +1231,9 @@ lto_read_body_or_constructor (struct lto_file_decl_data *file_data, struct symta ...@@ -1231,7 +1231,9 @@ lto_read_body_or_constructor (struct lto_file_decl_data *file_data, struct symta
if (TYPE_P (t)) if (TYPE_P (t))
{ {
gcc_assert (TYPE_CANONICAL (t) == NULL_TREE); 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) if (TYPE_MAIN_VARIANT (t) != t)
{ {
gcc_assert (TYPE_NEXT_VARIANT (t) == NULL_TREE); gcc_assert (TYPE_NEXT_VARIANT (t) == NULL_TREE);
......
2015-11-24 Jan Hubicka <hubicka@ucw.cz> 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. * lto.c (unify_scc): Use free_node.
2015-11-21 Jan Hubicka <hubicka@ucw.cz> 2015-11-21 Jan Hubicka <hubicka@ucw.cz>
......
...@@ -389,9 +389,7 @@ iterative_hash_canonical_type (tree type, inchash::hash &hstate) ...@@ -389,9 +389,7 @@ iterative_hash_canonical_type (tree type, inchash::hash &hstate)
/* All type variants have same TYPE_CANONICAL. */ /* All type variants have same TYPE_CANONICAL. */
type = TYPE_MAIN_VARIANT (type); type = TYPE_MAIN_VARIANT (type);
/* We do not compute TYPE_CANONICAl of POINTER_TYPE because the aliasing if (!canonical_type_used_p (type))
code never use it anyway. */
if (POINTER_TYPE_P (type))
v = hash_canonical_type (type); v = hash_canonical_type (type);
/* An already processed type. */ /* An already processed type. */
else if (TYPE_CANONICAL (type)) else if (TYPE_CANONICAL (type))
...@@ -444,7 +442,7 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash) ...@@ -444,7 +442,7 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
gcc_checking_assert (TYPE_P (t) && !TYPE_CANONICAL (t) gcc_checking_assert (TYPE_P (t) && !TYPE_CANONICAL (t)
&& type_with_alias_set_p (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); slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash, INSERT);
if (*slot) if (*slot)
...@@ -477,7 +475,8 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash) ...@@ -477,7 +475,8 @@ gimple_register_canonical_type_1 (tree t, hashval_t hash)
static void static void
gimple_register_canonical_type (tree t) 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; return;
/* Canonical types are same among all complete variants. */ /* Canonical types are same among all complete variants. */
......
...@@ -8252,7 +8252,8 @@ build_array_type_1 (tree elt_type, tree index_type, bool shared) ...@@ -8252,7 +8252,8 @@ build_array_type_1 (tree elt_type, tree index_type, bool shared)
if (TYPE_CANONICAL (t) == t) if (TYPE_CANONICAL (t) == t)
{ {
if (TYPE_STRUCTURAL_EQUALITY_P (elt_type) 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); SET_TYPE_STRUCTURAL_EQUALITY (t);
else if (TYPE_CANONICAL (elt_type) != elt_type else if (TYPE_CANONICAL (elt_type) != elt_type
|| (index_type && TYPE_CANONICAL (index_type) != index_type)) || (index_type && TYPE_CANONICAL (index_type) != index_type))
...@@ -9865,7 +9866,7 @@ make_vector_type (tree innertype, int nunits, machine_mode mode) ...@@ -9865,7 +9866,7 @@ make_vector_type (tree innertype, int nunits, machine_mode mode)
SET_TYPE_VECTOR_SUBPARTS (t, nunits); SET_TYPE_VECTOR_SUBPARTS (t, nunits);
SET_TYPE_MODE (t, mode); 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); SET_TYPE_STRUCTURAL_EQUALITY (t);
else if ((TYPE_CANONICAL (innertype) != innertype else if ((TYPE_CANONICAL (innertype) != innertype
|| mode != VOIDmode) || mode != VOIDmode)
...@@ -13295,7 +13296,8 @@ gimple_canonical_types_compatible_p (const_tree t1, const_tree t2, ...@@ -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 TYPE_CANONICAL is more fine grained than the equivalnce we test (where
all pointers are considered equal. Be sure to not return false all pointers are considered equal. Be sure to not return false
negatives. */ 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); return TYPE_CANONICAL (t1) == TYPE_CANONICAL (t2);
} }
......
...@@ -4811,7 +4811,9 @@ extern void DEBUG_FUNCTION verify_type (const_tree t); ...@@ -4811,7 +4811,9 @@ extern void DEBUG_FUNCTION verify_type (const_tree t);
extern bool gimple_canonical_types_compatible_p (const_tree, const_tree, extern bool gimple_canonical_types_compatible_p (const_tree, const_tree,
bool trust_type_canonical = true); bool trust_type_canonical = true);
extern bool type_with_interoperable_signedness (const_tree); 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 inline enum tree_code
tree_code_for_canonical_type_merging (enum tree_code 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) ...@@ -4833,6 +4835,23 @@ tree_code_for_canonical_type_merging (enum tree_code code)
return 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 #define tree_map_eq tree_map_base_eq
extern unsigned int tree_map_hash (const void *); extern unsigned int tree_map_hash (const void *);
#define tree_map_marked_p tree_map_base_marked_p #define tree_map_marked_p tree_map_base_marked_p
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment