From: Jan Hubicka Date: Tue, 24 Nov 2015 19:35:38 +0000 (+0100) Subject: lto-streamer-in.c (lto_read_body_or_constructor): Set TYPE_CANONICAL only for types... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=aea50b45f5db36d77d4cf8488dd98d8a06c073a8;p=gcc.git 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 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ac7b7bde0b5..a3e259bb15c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2015-11-24 Jan Hubicka + + * 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 * config/rs6000/rs6000.md (lrounddi2): Remove constraints. diff --git a/gcc/alias.c b/gcc/alias.c index f3f79869a8b..e8e3f6c34ac 100644 --- a/gcc/alias.c +++ b/gcc/alias.c @@ -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; diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 4c4a39be627..53298519b05 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -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); diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog index 9d6b12640c6..be0eb7f4e92 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,12 @@ +2015-11-24 Jan Hubicka + + * 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 * lto.c (unify_scc): Use free_node. diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index c4c51588adc..b1e2d6e8090 100644 --- a/gcc/lto/lto.c +++ b/gcc/lto/lto.c @@ -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. */ diff --git a/gcc/tree.c b/gcc/tree.c index 2888657fe04..4176d614a51 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -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); } diff --git a/gcc/tree.h b/gcc/tree.h index 6c733aa5e4c..121c88bb5e5 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -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