ipa-devirt.c (odr_types_equivalent_p): Expect constants than const decls in TREE_VALU...
authorJan Hubicka <jh@suse.cz>
Wed, 7 Nov 2018 14:12:20 +0000 (15:12 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 7 Nov 2018 14:12:20 +0000 (14:12 +0000)
* ipa-devirt.c (odr_types_equivalent_p): Expect constants
than const decls in TREE_VALUE of enum.
(dump_type_inheritance_graph): Improve duplicate dumping.
(free_enum_values): New.
(build_type_inheritance_graph): Use it.
* tree.c (free_lang_data_in_type): Free TYPE_VALUES of enums
which are not main variants or not ODR types.
(verify_type_variant): Expect variants to have no TYPE_VALUES.

From-SVN: r265875

gcc/ChangeLog
gcc/ipa-devirt.c
gcc/tree.c

index 899e3fa..c893ee2 100644 (file)
@@ -1,3 +1,14 @@
+2018-11-07  Jan Hubicka  <jh@suse.cz>
+
+       * ipa-devirt.c (odr_types_equivalent_p): Expect constants
+       than const decls in TREE_VALUE of enum.
+       (dump_type_inheritance_graph): Improve duplicate dumping.
+       (free_enum_values): New.
+       (build_type_inheritance_graph): Use it.
+       * tree.c (free_lang_data_in_type): Free TYPE_VALUES of enums
+       which are not main variants or not ODR types.
+       (verify_type_variant): Expect variants to have no TYPE_VALUES.
+
 2018-11-07  Richard Biener  <rguenther@suse.de>
 
        * ipa-inline.c (want_inline_small_function_p): Compute
index d92e6f4..4676bdb 100644 (file)
@@ -1328,9 +1328,7 @@ odr_types_equivalent_p (tree t1, tree t2, bool warn, bool *warned,
                           " is defined in another translation unit"));
              return false;
            }
-         if (TREE_VALUE (v1) != TREE_VALUE (v2)
-             && !operand_equal_p (DECL_INITIAL (TREE_VALUE (v1)),
-                                  DECL_INITIAL (TREE_VALUE (v2)), 0))
+         if (TREE_VALUE (v1) != TREE_VALUE (v2))
            {
              warn_odr (t1, t2, NULL, NULL, warn, warned,
                        G_("an enum with different values is defined"
@@ -2191,6 +2189,7 @@ static void
 dump_type_inheritance_graph (FILE *f)
 {
   unsigned int i;
+  unsigned int num_all_types = 0, num_types = 0, num_duplicates = 0;
   if (!odr_types_ptr)
     return;
   fprintf (f, "\n\nType inheritance graph:\n");
@@ -2201,26 +2200,70 @@ dump_type_inheritance_graph (FILE *f)
     }
   for (i = 0; i < odr_types.length (); i++)
     {
-      if (odr_types[i] && odr_types[i]->types && odr_types[i]->types->length ())
+      if (!odr_types[i])
+       continue;
+
+      num_all_types++;
+      if (!odr_types[i]->types || !odr_types[i]->types->length ())
+       continue;
+
+      /* To aid ODR warnings we also mangle integer constants but do
+        not consinder duplicates there.  */
+      if (TREE_CODE (odr_types[i]->type) == INTEGER_TYPE)
+       continue;
+
+      /* It is normal to have one duplicate and one normal variant.  */
+      if (odr_types[i]->types->length () == 1
+         && COMPLETE_TYPE_P (odr_types[i]->type)
+         && !COMPLETE_TYPE_P ((*odr_types[i]->types)[0]))
+       continue;
+
+      num_types ++;
+
+      unsigned int j;
+      fprintf (f, "Duplicate tree types for odr type %i\n", i);
+      print_node (f, "", odr_types[i]->type, 0);
+      print_node (f, "", TYPE_NAME (odr_types[i]->type), 0);
+      putc ('\n',f);
+      for (j = 0; j < odr_types[i]->types->length (); j++)
        {
-         unsigned int j;
-         fprintf (f, "Duplicate tree types for odr type %i\n", i);
-         print_node (f, "", odr_types[i]->type, 0);
-         for (j = 0; j < odr_types[i]->types->length (); j++)
+         tree t;
+         num_duplicates ++;
+         fprintf (f, "duplicate #%i\n", j);
+         print_node (f, "", (*odr_types[i]->types)[j], 0);
+         t = (*odr_types[i]->types)[j];
+         while (TYPE_P (t) && TYPE_CONTEXT (t))
            {
-             tree t;
-             fprintf (f, "duplicate #%i\n", j);
-             print_node (f, "", (*odr_types[i]->types)[j], 0);
-             t = (*odr_types[i]->types)[j];
-             while (TYPE_P (t) && TYPE_CONTEXT (t))
-               {
-                 t = TYPE_CONTEXT (t);
-                 print_node (f, "", t, 0);
-               }
-             putc ('\n',f);
+             t = TYPE_CONTEXT (t);
+             print_node (f, "", t, 0);
            }
+         print_node (f, "", TYPE_NAME ((*odr_types[i]->types)[j]), 0);
+         putc ('\n',f);
        }
     }
+  fprintf (f, "Out of %i types there are %i types with duplicates; "
+          "%i duplicates overall\n", num_all_types, num_types, num_duplicates);
+}
+
+/* Save some WPA->ltrans streaming by freeing enum values.  */
+
+static void
+free_enum_values ()
+{
+  static bool enum_values_freed = false;
+  if (enum_values_freed || !flag_wpa || !odr_types_ptr)
+    return;
+  enum_values_freed = true;
+  unsigned int i;
+  for (i = 0; i < odr_types.length (); i++)
+    if (odr_types[i] && TREE_CODE (odr_types[i]->type) == ENUMERAL_TYPE)
+      {
+       TYPE_VALUES (odr_types[i]->type) = NULL;
+       if (odr_types[i]->types)
+          for (unsigned int j = 0; j < odr_types[i]->types->length (); j++)
+           TYPE_VALUES ((*odr_types[i]->types)[j]) = NULL;
+      }
+  enum_values_freed = true;
 }
 
 /* Initialize IPA devirt and build inheritance tree graph.  */
@@ -2233,7 +2276,10 @@ build_type_inheritance_graph (void)
   dump_flags_t flags;
 
   if (odr_hash)
-    return;
+    {
+      free_enum_values ();
+      return;
+    }
   timevar_push (TV_IPA_INHERITANCE);
   inheritance_dump_file = dump_begin (TDI_inheritance, &flags);
   odr_hash = new odr_hash_type (23);
@@ -2278,6 +2324,7 @@ build_type_inheritance_graph (void)
       dump_type_inheritance_graph (inheritance_dump_file);
       dump_end (TDI_inheritance, inheritance_dump_file);
     }
+  free_enum_values ();
   timevar_pop (TV_IPA_INHERITANCE);
 }
 
index b1f4ecf..11c0535 100644 (file)
@@ -5345,6 +5345,20 @@ free_lang_data_in_type (tree type, struct free_lang_data_d *fld)
           || SCALAR_FLOAT_TYPE_P (type)
           || FIXED_POINT_TYPE_P (type))
     {
+      if (TREE_CODE (type) == ENUMERAL_TYPE)
+       {
+         /* Type values are used only for C++ ODR checking.  Drop them
+            for all type variants and non-ODR types.  */
+         if (TYPE_MAIN_VARIANT (type) != type
+             || !type_with_linkage_p (type))
+           TYPE_VALUES (type) = NULL;
+         else
+         /* Simplify representation by recording only values rather
+            than const decls.  */
+           for (tree e = TYPE_VALUES (type); e; e = TREE_CHAIN (e))
+             if (TREE_CODE (TREE_VALUE (e)) == CONST_DECL)
+               TREE_VALUE (e) = DECL_INITIAL (TREE_VALUE (e));
+       }
       free_lang_data_in_one_sizepos (&TYPE_MIN_VALUE (type));
       free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type));
     }
@@ -13525,7 +13539,8 @@ verify_type_variant (const_tree t, tree tv)
     }
 
   /* Check various uses of TYPE_VALUES_RAW.  */
-  if (TREE_CODE (t) == ENUMERAL_TYPE)
+  if (TREE_CODE (t) == ENUMERAL_TYPE
+      && TYPE_VALUES (t))
     verify_variant_match (TYPE_VALUES);
   else if (TREE_CODE (t) == ARRAY_TYPE)
     verify_variant_match (TYPE_DOMAIN);