public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Turn complete to incomplete types in free_lang_data
@ 2018-10-26 12:49 Jan Hubicka
  2018-10-26 14:06 ` Richard Biener
  0 siblings, 1 reply; 8+ messages in thread
From: Jan Hubicka @ 2018-10-26 12:49 UTC (permalink / raw)
  To: gcc-patches, rguenther

Hi,
this is minimal variant of the patch turning complete to incomplete pointers in
fields.  We can do more - in particular it would be very function to do same
for functions types and decls (because they often end up being streamed to
symtab) and we should also turn pointers to arrays and enums to incomplete
variants.

I do that in my local tree but i would like to get it into mainline one by
one and check benefits of each change independently. 

Patch bootstraped&regtests x86-64 and I am now re-testing it on firefox.  I
checked on small testcases that types indeed do get merged.

OK if it survives more testing on firefox and lto bootstrap?

Honza

	* tree.c (free_lang_data_in_type): Declare.
	(types_equal_p): New function.
	(free_lang_data_type_variant): New function.
	(incomplete_type_of): New function.
	(simplified_type): New function.
Index: tree.c
===================================================================
--- tree.c	(revision 265522)
+++ tree.c	(working copy)
@@ -265,6 +265,8 @@ static void print_type_hash_statistics (
 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,140 @@ protected_set_expr_location (tree t, loc
     SET_EXPR_LOCATION (t, loc);
 }
 \f
+/* 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
+types_equal_p (tree t, tree v)
+{
+  if (t==v)
+    return true;
+
+  if (TYPE_QUALS (t) != TYPE_QUALS (v))
+    return false;
+
+  if (TYPE_NAME (t) != TYPE_NAME (v)
+      && (!TYPE_NAME (t) || !TYPE_NAME (v)
+	  || TREE_CODE (TYPE_NAME (t)) != TYPE_DECL
+	  || TREE_CODE (TYPE_NAME (v)) != TYPE_DECL
+	  || DECL_ASSEMBLER_NAME_RAW (TYPE_NAME (t))
+	     != DECL_ASSEMBLER_NAME_RAW (TYPE_NAME (v))
+	  || DECL_NAME (TYPE_NAME (t)) != DECL_NAME (TYPE_NAME (v))))
+     return false;
+
+  if (TYPE_ALIGN (t) != TYPE_ALIGN (v))
+    return false;
+
+  if (!attribute_list_equal (TYPE_ATTRIBUTES (t),
+			     TYPE_ATTRIBUTES (v)))
+     return false;
+
+  /* Do not replace complete type by incomplete.  */
+  if ((TREE_CODE (t) == QUAL_UNION_TYPE
+       || TREE_CODE (t) == UNION_TYPE || TREE_CODE (t) == RECORD_TYPE)
+      && COMPLETE_TYPE_P (t) != COMPLETE_TYPE_P (v))
+    return false;
+
+  gcc_assert (TREE_CODE (t) == TREE_CODE (v));
+
+  /* For pointer types and array types we also care about the type they
+     reffer to.  */
+  if (TREE_TYPE (t))
+    return types_equal_p (TREE_TYPE (t), TREE_TYPE (v));
+
+  return true;
+}
+
+/* Find variant of FIRST that match T and create new one if necessary.  */
+
+static tree
+free_lang_data_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 (types_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> *incomplete_types;
+
+/* See if type T can be turned into incopmlete variant.  */
+
+static tree
+incomplete_type_of (tree t)
+{
+  if (!RECORD_OR_UNION_TYPE_P (t))
+    return t;
+  if (!COMPLETE_TYPE_P (t))
+    return t;
+  if (TYPE_MAIN_VARIANT (t) == t)
+    {
+      bool existed;
+      tree &copy
+	 = incomplete_types->get_or_insert (TYPE_MAIN_VARIANT (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 (free_lang_data_type_variant
+	    (incomplete_type_of (TYPE_MAIN_VARIANT (t)), t));
+}
+
+/* Simplify type T for scenarios where we do not need complete pointer
+   types.  */
+
+static tree
+simplified_type (tree t)
+{
+  if (POINTER_TYPE_P (t))
+    {
+      tree t2 = POINTER_TYPE_P (TREE_TYPE (t))
+		? simplified_type (TREE_TYPE (t))
+		: 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 free_lang_data_type_variant (first, 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 +5492,11 @@ free_lang_data_in_decl (tree decl)
       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) = 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 +6011,8 @@ free_lang_data (void)
       || (!flag_generate_lto && !flag_generate_offload))
     return 0;
 
+  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);

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2018-10-30 19:16 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-26 12:49 Turn complete to incomplete types in free_lang_data Jan Hubicka
2018-10-26 14:06 ` Richard Biener
2018-10-26 14:52   ` Jan Hubicka
2018-10-30  9:42     ` Richard Biener
2018-10-30 10:11       ` Jan Hubicka
2018-10-29 11:04   ` Jan Hubicka
2018-10-30 15:20     ` Richard Biener
2018-10-30 19:49       ` Jan Hubicka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).