On Wed, 21 Nov 2018, Jan Hubicka wrote:

> Hi,
> this patch recovers location infomration in the ODR warnings.
> Because location info is not attached to types but corresponding
> TYPE_DECLs, we need to prevent TYPE_DECLs to be merged when
> corresponding types are not merged.
> 
> To achieve this I no longer clear TREE_TYPE of TYPE_DECLs which
> puts them back to the same SCC as the type itself.  While making
> incomplete type variant we need to produce copy of TYPE_DECL. Becuase
> it is possible that TYPE_DECL was not processed by free lang data
> we can not do copy_node but build it from scratch (because 
> the toplevel loops possibly processed all decls). This is not hard
> to do, but made me notice few extra flags that are streamed for
> TYPE_DECLs and free_lang_data is not seeing them.
> 
> I have also extended ipa-devirt to get rid of the duplicated decls
> once ODR warnings are done to save ltrans streaming (it actually
> added about 10% of ltrans data w/o this change)
> 
> I have checked that the patch does not increase number of type
> duplicates for cc1 (24), I will also re-do testing for Firefox
> which may uncover some extra flags/attributes to care about.
> 
> lto-bootstrapped/regtested x86_64-linux OK?

OK if you put a comment ...

> Honza
>       
>       PR lto/87957
>       * tree.c (fld_decl_context): Break out from ...
>       (free_lang_data_in_decl): ... here; free TREE_PUBLIC, TREE_PRIVATE
>       DECL_ARTIFICIAL of TYPE_DECL; do not free TREE_TYPE of TYPE_DECL.
>       (fld_incomplete_type_of): Build copy of TYP_DECL.
>       * ipa-devirt.c (free_enum_values): Rename to ...
>       (free_odr_warning_data): ... this one; free also duplicated TYPE_DECLs
>       and TREE_TYPEs of TYPE_DECLs.
> 
> Index: tree.c
> ===================================================================
> --- tree.c    (revision 266325)
> +++ tree.c    (working copy)
> @@ -5206,6 +5206,24 @@ fld_process_array_type (tree t, tree t2,
>    return array;
>  }
>  
> +/* Return CTX after removal of contexts that are not relevant  */
> +
> +static tree
> +fld_decl_context (tree ctx)
> +{
> +  /* Variably modified types are needed for tree_is_indexable to decide
> +     whether the type needs to go to local or global section.
> +     This code is semi-broken but for now it is easiest to keep contexts
> +     as expected.  */
> +  if (ctx && TYPE_P (ctx)
> +      && !variably_modified_type_p (ctx, NULL_TREE))
> +     {
> +       while (ctx && TYPE_P (ctx))
> +      ctx = TYPE_CONTEXT (ctx);
> +     }
> +  return ctx;
> +}
> +
>  /* For T being aggregate type try to turn it into a incomplete variant.
>     Return T if no simplification is possible.  */
>  
> @@ -5267,6 +5285,27 @@ fld_incomplete_type_of (tree t, struct f
>           }
>         else
>           TYPE_VALUES (copy) = NULL;
> +
> +       /* Build copy of TYPE_DECL in TYPE_NAME if necessary.
> +          This is needed for ODR violation warnings to come out right (we
> +          want duplicate TYPE_DECLs whenever the type is duplicated because
> +          of ODR violation.  Because lang data in the TYPE_DECL may not
> +          have been freed yet, rebuild it from scratch and copy relevant
> +          fields.  */
> +       TYPE_NAME (copy) = fld_simplified_type_name (copy);
> +       tree name = TYPE_NAME (copy);
> +
> +       if (name && TREE_CODE (name) == TYPE_DECL)
> +         {
> +           gcc_checking_assert (TREE_TYPE (name) == t);
> +           tree name2 = build_decl (DECL_SOURCE_LOCATION (name), TYPE_DECL,
> +                                    DECL_NAME (name), copy);
> +           SET_DECL_ASSEMBLER_NAME (name2, DECL_ASSEMBLER_NAME (name));
> +           SET_DECL_ALIGN (name2, 0);
> +           DECL_CONTEXT (name2) = fld_decl_context
> +                                      (DECL_CONTEXT (name));
> +           TYPE_NAME (copy) = name2;
> +         }
>       }
>        return copy;
>     }
> @@ -5649,12 +5688,13 @@ free_lang_data_in_decl (tree decl, struc
>      {
>        DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
>        DECL_VISIBILITY_SPECIFIED (decl) = 0;
> -      /* TREE_PUBLIC is used to tell if type is anonymous.  */
> +      TREE_PUBLIC (decl) = 0;
> +      TREE_PRIVATE (decl) = 0;
> +      DECL_ARTIFICIAL (decl) = 0;
>        TYPE_DECL_SUPPRESS_DEBUG (decl) = 0;
>        DECL_INITIAL (decl) = NULL_TREE;
>        DECL_ORIGINAL_TYPE (decl) = NULL_TREE;
>        DECL_MODE (decl) = VOIDmode;
> -      TREE_TYPE (decl) = void_type_node;
>        SET_DECL_ALIGN (decl, 0);
>      }
>    else if (TREE_CODE (decl) == FIELD_DECL)
> @@ -5688,20 +5728,7 @@ free_lang_data_in_decl (tree decl, struc
>    if (TREE_CODE (decl) != FIELD_DECL
>        && ((TREE_CODE (decl) != VAR_DECL && TREE_CODE (decl) != FUNCTION_DECL)
>            || !DECL_VIRTUAL_P (decl)))
> -    {
> -      tree ctx = DECL_CONTEXT (decl);
> -      /* Variably modified types are needed for tree_is_indexable to decide
> -      whether the type needs to go to local or global section.
> -      This code is semi-broken but for now it is easiest to keep contexts
> -      as expected.  */
> -      if (ctx && TYPE_P (ctx)
> -       && !variably_modified_type_p (ctx, NULL_TREE))
> -      {
> -        while (ctx && TYPE_P (ctx))
> -          ctx = TYPE_CONTEXT (ctx);
> -        DECL_CONTEXT (decl) = ctx;
> -      }
> -    }
> +    DECL_CONTEXT (decl) = fld_decl_context (DECL_CONTEXT (decl));
>  }
>  
>  
> Index: ipa-devirt.c
> ===================================================================
> --- ipa-devirt.c      (revision 266325)
> +++ ipa-devirt.c      (working copy)
> @@ -2289,27 +2289,39 @@ dump_type_inheritance_graph (FILE *f)
>          "%i duplicates overall\n", num_all_types, num_types, num_duplicates);
>  }
>  
> -/* Save some WPA->ltrans streaming by freeing enum values.  */
> +/* Save some WPA->ltrans streaming by freeing stuff needed only for good
> +   ODR warnings.  */
>  
>  static void
> -free_enum_values ()
> +free_odr_warning_data ()
>  {
> -  static bool enum_values_freed = false;
> -  if (enum_values_freed || !flag_wpa || !odr_types_ptr)
> +  static bool odr_data_freed = false;
> +
> +  if (odr_data_freed || !flag_wpa || !odr_types_ptr)
>      return;
> -  enum_values_freed = true;
> -  unsigned int i;
> -  for (i = 0; i < odr_types.length (); i++)
> +
> +  odr_data_freed = true;
> +
> +  for (unsigned int i = 0; i < odr_types.length (); i++)
>      if (odr_types[i])
>        {
> -     if (TREE_CODE (odr_types[i]->type) == ENUMERAL_TYPE)
> -       TYPE_VALUES (odr_types[i]->type) = NULL;
> +     tree t = odr_types[i]->type;
> +
> +     if (TREE_CODE (t) == ENUMERAL_TYPE)
> +       TYPE_VALUES (t) = NULL;
> +     TREE_TYPE (TYPE_NAME (t)) = void_type_node;

... here explaining the late "free-lang-data".

Richard.

> +
>       if (odr_types[i]->types)
>            for (unsigned int j = 0; j < odr_types[i]->types->length (); j++)
> -         if (TREE_CODE ((*odr_types[i]->types)[j]) == ENUMERAL_TYPE)
> -           TYPE_VALUES ((*odr_types[i]->types)[j]) = NULL;
> +         {
> +           tree td = (*odr_types[i]->types)[j];
> +
> +           if (TREE_CODE (td) == ENUMERAL_TYPE)
> +             TYPE_VALUES (td) = NULL;
> +           TYPE_NAME (td) = TYPE_NAME (t);
> +         }
>        }
> -  enum_values_freed = true;
> +  odr_data_freed = true;
>  }
>  
>  /* Initialize IPA devirt and build inheritance tree graph.  */
> @@ -2323,7 +2335,7 @@ build_type_inheritance_graph (void)
>  
>    if (odr_hash)
>      {
> -      free_enum_values ();
> +      free_odr_warning_data ();
>        return;
>      }
>    timevar_push (TV_IPA_INHERITANCE);
> @@ -2370,7 +2382,7 @@ build_type_inheritance_graph (void)
>        dump_type_inheritance_graph (inheritance_dump_file);
>        dump_end (TDI_inheritance, inheritance_dump_file);
>      }
> -  free_enum_values ();
> +  free_odr_warning_data ();
>    timevar_pop (TV_IPA_INHERITANCE);
>  }
>  
> 
> 

-- 
Richard Biener <rguent...@suse.de>
SUSE LINUX GmbH, GF: Felix Imendoerffer, Jane Smithard, Graham Norton, HRB 
21284 (AG Nuernberg)

Reply via email to