lto-streamer-in.c (lto_read_body_or_constructor): Set TYPE_CANONICAL only for types...
authorJan Hubicka <hubicka@ucw.cz>
Tue, 24 Nov 2015 19:35:38 +0000 (20:35 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 24 Nov 2015 19:35:38 +0000 (19:35 +0000)
* 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

gcc/ChangeLog
gcc/alias.c
gcc/lto-streamer-in.c
gcc/lto/ChangeLog
gcc/lto/lto.c
gcc/tree.c
gcc/tree.h

index ac7b7bde0b51aea14c13adca3886baf0663f1f78..a3e259bb15c5bed2ac370eb3fd06266191e1daae 100644 (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.
index f3f79869a8bbeec48ccb37d642de046517e3b199..e8e3f6c34acd55a11278e9b1605cfad1bc5c9a39 100644 (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;
index 4c4a39be627afc1a83c4bc403409d396624d097f..53298519b058b489c470b5fb35a8a6bc6e94fe52 100644 (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);
index 9d6b12640c6e4c899e3ae2c2ed39af902083cfff..be0eb7f4e92db22777e0563a8e690d45a2480fda 100644 (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.
index c4c51588adcb6ea86737c5f051a7b8066b4482d1..b1e2d6e8090cdd3b7819c1e4cd40de74f6ac58b5 100644 (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.  */
index 2888657fe044d6f6554363e6db06c2a3d703053d..4176d614a51d308eb7238e02820923db9ac79275 100644 (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);
     }
 
index 6c733aa5e4c952d670053cc967e54ebaf70c6e72..121c88bb5e581989fbbd161087881c1df1b8b249 100644 (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