On Mon, 29 Oct 2018, Jan Hubicka wrote:

> Hi,
> this is cleaner version of the patch.  During weekend I did some tests with
> firefox, libreoffice and gcc builds and it seems to work well. For firefox
> it reaches almost linear scalability of the ltrans files (they are 1.9GB,
> after increasing number of partitions to 128 they grow to 2GB that looks
> quite acceptable. Resulting .s and libxul binary are actually bigger than
> that when debug info is enabled).
> 
> So if that works in other cases, I will increas lto-partitions and probably
> declare it good enough for this stage1 and will try to move to other things.
> 
> Concerning two things we have discussed, I am keeping recursion to
> free_lang_data_in_type for now as reordering seems just temporary solution
> until we do more freeing from both types and decl (eventually I want to free
> subtypes of function types that also brings a lot of context. On Firefox that
> acount another 5% of stream data volume).
> 
> One option would be to change the walking order for this stage1 and worry
> about it next stage1.  Other option would be to simply push the newly created
> types to the fld queues.

If that works this sounds best.

> I also did not share fld_type_variant_equal_p with check_base_type since
> that one checks also context that we do not want to do. Probably could be
> cleaned up incrementally - I wonder why Objective-C needs it.
> 
> I looked into enabling free_lang_data by default.  My main problem there is
> what to do with late langhooks, say one for variably_modified_type_p.
> I suppose we could just declare middle-end self contained wrt analyzing
> IL and try to disable them one by one after free lang data was run?

Yes, that was the original idea.  IIRC enabling free-lang-data 
unconditionally mostly works fine apart from some testcases issues
with late diagnostics and dump scanning.

> What we however want to do about late warnings? Do we have some idea how
> many are those and what kind of % modifiers needs to be printed correctly?
> Say late warning wants to print a type, how we are going to do that?

Well, we print the type in the middle-end way - basically 
install the LTO variant of the langhooks.

You fail to free fld_incomplete_types btw.  The patch looks sensible
with that change - possibly with removing the recursion and pushing
to the worklist instead.

Thanks,
Richard.

> Boostrapped/regtested x86_64-linux.
> 
> Honza
>       * tree.c (free_lang_data_in_type): Forward declare.
>       (fld_type_variant_equal_p): New function.
>       (fld_type_variant): New function
>       (fld_incomplete_types): New hash.
>       (fld_incomplete_type_of): New function
>       (fld_simplfied-type): New function.
>       (free_lang_data_in_decl): New.
> Index: tree.c
> ===================================================================
> --- tree.c    (revision 265573)
> +++ tree.c    (working copy)
> @@ -265,6 +265,8 @@
>  static void print_debug_expr_statistics (void);
>  static void print_value_expr_statistics (void);
>  
> +static void free_lang_data_in_type (tree type);
> +
>  tree global_trees[TI_MAX];
>  tree integer_types[itk_none];
>  
> @@ -5038,6 +5041,115 @@
>      SET_EXPR_LOCATION (t, loc);
>  }
>  
> +/* Do same comparsion as check_qualified_type skipping lang part of type
> +   and be more permissive about type names: we only care that names are
> +   same (for diagnostics) and that ODR names are the same.  */
> +
> +static bool
> +fld_type_variant_equal_p (tree t, tree v)
> +{
> +  if (TYPE_QUALS (t) != TYPE_QUALS (v)
> +      || TYPE_NAME (t) != TYPE_NAME (v)
> +      || TYPE_ALIGN (t) != TYPE_ALIGN (v)
> +      || !attribute_list_equal (TYPE_ATTRIBUTES (t),
> +                             TYPE_ATTRIBUTES (v)))
> +    return false;
> +
> +  return true;
> +}
> +
> +/* Find variant of FIRST that match T and create new one if necessary.  */
> +
> +static tree
> +fld_type_variant (tree first, tree t)
> +{
> +  if (first == TYPE_MAIN_VARIANT (t))
> +    return t;
> +  for (tree v = first; v; v = TYPE_NEXT_VARIANT (v))
> +    if (fld_type_variant_equal_p (t, v))
> +      return v;
> +  tree v = build_variant_type_copy (first);
> +  TYPE_READONLY (v) = TYPE_READONLY (t);
> +  TYPE_VOLATILE (v) = TYPE_VOLATILE (t);
> +  TYPE_ATOMIC (v) = TYPE_ATOMIC (t);
> +  TYPE_RESTRICT (v) = TYPE_RESTRICT (t);
> +  TYPE_ADDR_SPACE (v) = TYPE_ADDR_SPACE (t);
> +  TYPE_NAME (v) = TYPE_NAME (t);
> +  TYPE_ATTRIBUTES (v) = TYPE_ATTRIBUTES (t);
> +  return v;
> +}
> +
> +/* Map complete types to incomplete types.  */
> +
> +static hash_map<tree, tree> *fld_incomplete_types;
> +
> +/* For T being aggregate type try to turn it into a incomplete variant.
> +   Return T if no simplification is possible.  */
> +
> +static tree
> +fld_incomplete_type_of (tree t)
> +{
> +  if (!t)
> +    return NULL;
> +  if (POINTER_TYPE_P (t))
> +    {
> +      tree t2 = fld_incomplete_type_of (TREE_TYPE (t));
> +      if (t2 != TREE_TYPE (t))
> +     {
> +       tree first;
> +       if (TREE_CODE (t) == POINTER_TYPE)
> +         first = build_pointer_type_for_mode (t2, TYPE_MODE (t),
> +                                             TYPE_REF_CAN_ALIAS_ALL (t));
> +       else
> +         first = build_reference_type_for_mode (t2, TYPE_MODE (t),
> +                                             TYPE_REF_CAN_ALIAS_ALL (t));
> +       return fld_type_variant (first, t);
> +     }
> +      return t;
> +    }
> +  if (!RECORD_OR_UNION_TYPE_P (t) || !COMPLETE_TYPE_P (t))
> +    return t;
> +  if (TYPE_MAIN_VARIANT (t) == t)
> +    {
> +      bool existed;
> +      tree &copy
> +      = fld_incomplete_types->get_or_insert (t, &existed);
> +
> +      if (!existed)
> +     {
> +       copy = build_distinct_type_copy (t);
> +
> +       /* It is possible type was not seen by free_lang_data yet.  */
> +       free_lang_data_in_type (copy);
> +       TYPE_SIZE (copy) = NULL;
> +       SET_TYPE_MODE (copy, VOIDmode);
> +       SET_TYPE_ALIGN (copy, BITS_PER_UNIT);
> +       TYPE_SIZE_UNIT (copy) = NULL;
> +       if (AGGREGATE_TYPE_P (t))
> +         {
> +           TYPE_FIELDS (copy) = NULL;
> +           TYPE_BINFO (copy) = NULL;
> +         }
> +       else
> +         TYPE_VALUES (copy) = NULL;
> +     }
> +      return copy;
> +   }
> +  return (fld_type_variant
> +         (fld_incomplete_type_of (TYPE_MAIN_VARIANT (t)), t));
> +}
> +
> +/* Simplify type T for scenarios where we do not need complete pointer
> +   types.  */
> +
> +static tree
> +fld_simplified_type (tree t)
> +{
> +  if (t && POINTER_TYPE_P (t))
> +    return fld_incomplete_type_of (t);
> +  return t;
> +}
> +
>  /* Reset the expression *EXPR_P, a size or position.
>  
>     ??? We could reset all non-constant sizes or positions.  But it's cheap
> @@ -5354,9 +5470,12 @@
>        DECL_VISIBILITY_SPECIFIED (decl) = 0;
>        DECL_INITIAL (decl) = NULL_TREE;
>        DECL_ORIGINAL_TYPE (decl) = NULL_TREE;
>      }
>    else if (TREE_CODE (decl) == FIELD_DECL)
> -    DECL_INITIAL (decl) = NULL_TREE;
> +    {
> +      TREE_TYPE (decl) = fld_simplified_type (TREE_TYPE (decl));
> +      DECL_INITIAL (decl) = NULL_TREE;
> +    }
>    else if (TREE_CODE (decl) == TRANSLATION_UNIT_DECL
>             && DECL_INITIAL (decl)
>             && TREE_CODE (DECL_INITIAL (decl)) == BLOCK)
> @@ -5866,6 +5989,8 @@
>        || (!flag_generate_lto && !flag_generate_offload))
>      return 0;
>  
> +  fld_incomplete_types = new hash_map<tree, tree>;
> +
>    /* Provide a dummy TRANSLATION_UNIT_DECL if the FE failed to provide one.  
> */
>    if (vec_safe_is_empty (all_translation_units))
>      build_translation_unit_decl (NULL_TREE);
> 
> 

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

Reply via email to