public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* Remove hash from remember_with_vars
@ 2013-08-31 16:24 Jan Hubicka
  2013-08-31 17:26 ` Richard Biener
  0 siblings, 1 reply; 4+ messages in thread
From: Jan Hubicka @ 2013-08-31 16:24 UTC (permalink / raw)
  To: gcc-patches, rguenther

Hi,
remember_with_vars walks trees that are read from file (now unique)
and looks for fields that can contain pointers to vars or functions and
if so, it records them to global hashtable for later fixup.
This is quite wasteful, because the hash is querried many times.
We can simply walk all fields in a tree and record the tree once afterwards,
moreover since streaming knows when tree is newly constructed, we don't need
hash.

Vectors do not allow deletable elements, but I think it makes no difference:
the trees are all used from decl states.
	* lot.c (tree_with_vars): Turn into vector.
	(MAYBE_REMEMBER_WITH_VARS): Change to...
	(CHECK_VAR): ... this one.
	(CHECK_NO_VAR): New macro.
	(maybe_remember_with_vars_typed): Trun to ...
	(mentions_vars_p_typed): ... this one.
	(maybe_remember_with_vars_common): Trun to ...
	(mentions_vars_p_comon): ... this one.
	(maybe_remember_with_vars_decl_minimal): Trun to ...
	(mentions_vars_p_decl_minmal): ... this one.
	(maybe_remember_with_vars_decl_common): Trun to ...
	(mentions_vars_p_decl_common): ... this one.
	(maybe_remember_with_vars_decl_with_vis): Trun to ...
	(mentions_vars_p_decl_with_vis): ... this one.
	(maybe_remember_with_vars_decl_non_common): Trun to ...
	(mentions_vars_p_decl_non_common): ... this one.
	(maybe_remember_with_vars_function): Trun to ...
	(mentions_vars_p_function): ... this one.
	(maybe_remember_with_vars_field_decl): Trun to ...
	(mentions_vars_p_field_decl): ... this one.
	(maybe_remember_with_vars_type): Trun to ...
	(mentions_vars_p_type): ... this one.
	(maybe_remember_with_vars_binfo): Trun to ...
	(mentions_vars_p_binfo): ... this one.
	(maybe_remember_with_vars_constructor): Trun to ...
	(mentions_vars_p_constructor): ... this one.
	(maybe_remember_with_vars_expr): Trun to ...
	(mentions_vars_p_expr): ... this one.
	(maybe_remember_with_vars): Trun to ...
	(mentions_vars_p): ... this one.
	(lto_read_decls): Update.
	(LTO_SET_PREVAIL): Do not call function for internal decls.
	(lto_fixup_prevailing_decls): Update to match mentions_vars_p;
	check that something was updated.
	(lto_fixup_state): Do not care about internal decls.
	(lto_fixup_decls): Update.
	(read_cgraph_and_symbols): Update.
Index: lto/lto.c
===================================================================
--- lto/lto.c	(revision 202099)
+++ lto/lto.c	(working copy)
@@ -1283,196 +1286,206 @@ gimple_register_type (tree t)
 
 /* End of old merging code.  */
 
+/* Remember trees that contains references to declarations.  */
+static GTY(()) vec <tree, va_gc> *tree_with_vars;
 
-
-/* A hashtable of trees that potentially refer to variables or functions
-   that must be replaced with their prevailing variant.  */
-static GTY((if_marked ("ggc_marked_p"), param_is (union tree_node))) htab_t
-  tree_with_vars;
-
-/* Remember that T is a tree that (potentially) refers to a variable
-   or function decl that may be replaced with its prevailing variant.  */
-static void
-remember_with_vars (tree t)
-{
-  *(tree *) htab_find_slot (tree_with_vars, t, INSERT) = t;
-}
-
-#define MAYBE_REMEMBER_WITH_VARS(tt) \
+#define CHECK_VAR(tt) \
   do \
     { \
-      if (tt) \
-	{ \
-	  if (VAR_OR_FUNCTION_DECL_P (tt) && TREE_PUBLIC (tt)) \
-	    remember_with_vars (t); \
-	} \
+      if ((tt) && VAR_OR_FUNCTION_DECL_P (tt) \
+	  && (TREE_PUBLIC (tt) || DECL_EXTERNAL (tt))) \
+	return true; \
     } while (0)
 
-/* Fix up fields of a tree_typed T.  */
+#define CHECK_NO_VAR(tt) \
+  gcc_checking_assert (!(tt) || !VAR_OR_FUNCTION_DECL_P (tt))
 
-static void
-maybe_remember_with_vars_typed (tree t)
+/* Check presence of pointers to decls in fields of a tree_typed T.  */
+
+static inline bool
+mentions_vars_p_typed (tree t)
 {
-  MAYBE_REMEMBER_WITH_VARS (TREE_TYPE (t));
+  CHECK_NO_VAR (TREE_TYPE (t));
+  return false;
 }
 
-/* Fix up fields of a tree_common T.  */
+/* Check presence of pointers to decls in fields of a tree_common T.  */
 
-static void
-maybe_remember_with_vars_common (tree t)
+static inline bool
+mentions_vars_p_common (tree t)
 {
-  maybe_remember_with_vars_typed (t);
-  MAYBE_REMEMBER_WITH_VARS (TREE_CHAIN (t));
+  if (mentions_vars_p_typed (t))
+    return true;
+  CHECK_NO_VAR (TREE_CHAIN (t));
+  return false;
 }
 
-/* Fix up fields of a decl_minimal T.  */
+/* Check presence of pointers to decls in fields of a decl_minimal T.  */
 
-static void
-maybe_remember_with_vars_decl_minimal (tree t)
+static inline bool
+mentions_vars_p_decl_minimal (tree t)
 {
-  maybe_remember_with_vars_common (t);
-  MAYBE_REMEMBER_WITH_VARS (DECL_NAME (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_CONTEXT (t));
+  if (mentions_vars_p_common (t))
+    return true;
+  CHECK_NO_VAR (DECL_NAME (t));
+  CHECK_VAR (DECL_CONTEXT (t));
+  return false;
 }
 
-/* Fix up fields of a decl_common T.  */
+/* Check presence of pointers to decls in fields of a decl_common T.  */
 
-static void
-maybe_remember_with_vars_decl_common (tree t)
+static inline bool
+mentions_vars_p_decl_common (tree t)
 {
-  maybe_remember_with_vars_decl_minimal (t);
-  MAYBE_REMEMBER_WITH_VARS (DECL_SIZE (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_SIZE_UNIT (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_INITIAL (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_ATTRIBUTES (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_ABSTRACT_ORIGIN (t));
+  if (mentions_vars_p_decl_minimal (t))
+    return true;
+  CHECK_VAR (DECL_SIZE (t));
+  CHECK_VAR (DECL_SIZE_UNIT (t));
+  CHECK_VAR (DECL_INITIAL (t));
+  CHECK_NO_VAR (DECL_ATTRIBUTES (t));
+  CHECK_VAR (DECL_ABSTRACT_ORIGIN (t));
+  return false;
 }
 
-/* Fix up fields of a decl_with_vis T.  */
+/* Check presence of pointers to decls in fields of a decl_with_vis T.  */
 
-static void
-maybe_remember_with_vars_decl_with_vis (tree t)
+static inline bool
+mentions_vars_p_decl_with_vis (tree t)
 {
-  maybe_remember_with_vars_decl_common (t);
+  if (mentions_vars_p_decl_common (t))
+    return true;
 
   /* Accessor macro has side-effects, use field-name here. */
-  MAYBE_REMEMBER_WITH_VARS (t->decl_with_vis.assembler_name);
-  MAYBE_REMEMBER_WITH_VARS (DECL_SECTION_NAME (t));
+  CHECK_NO_VAR (t->decl_with_vis.assembler_name);
+  CHECK_NO_VAR (DECL_SECTION_NAME (t));
+  return false;
 }
 
-/* Fix up fields of a decl_non_common T.  */
+/* Check presence of pointers to decls in fields of a decl_non_common T.  */
 
-static void
-maybe_remember_with_vars_decl_non_common (tree t)
+static inline bool
+mentions_vars_p_decl_non_common (tree t)
 {
-  maybe_remember_with_vars_decl_with_vis (t);
-  MAYBE_REMEMBER_WITH_VARS (DECL_ARGUMENT_FLD (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_RESULT_FLD (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_VINDEX (t));
+  if (mentions_vars_p_decl_with_vis (t))
+    return true;
+  CHECK_NO_VAR (DECL_ARGUMENT_FLD (t));
+  CHECK_NO_VAR (DECL_RESULT_FLD (t));
+  CHECK_NO_VAR (DECL_VINDEX (t));
+  return false;
 }
 
-/* Fix up fields of a decl_non_common T.  */
+/* Check presence of pointers to decls in fields of a decl_non_common T.  */
 
-static void
-maybe_remember_with_vars_function (tree t)
+static bool
+mentions_vars_p_function (tree t)
 {
-  maybe_remember_with_vars_decl_non_common (t);
-  MAYBE_REMEMBER_WITH_VARS (DECL_FUNCTION_PERSONALITY (t));
+  if (mentions_vars_p_decl_non_common (t))
+    return true;
+  CHECK_VAR (DECL_FUNCTION_PERSONALITY (t));
+  return false;
 }
 
-/* Fix up fields of a field_decl T.  */
+/* Check presence of pointers to decls in fields of a field_decl T.  */
 
-static void
-maybe_remember_with_vars_field_decl (tree t)
+static bool
+mentions_vars_p_field_decl (tree t)
 {
-  maybe_remember_with_vars_decl_common (t);
-  MAYBE_REMEMBER_WITH_VARS (DECL_FIELD_OFFSET (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_BIT_FIELD_TYPE (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_QUALIFIER (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_FIELD_BIT_OFFSET (t));
-  MAYBE_REMEMBER_WITH_VARS (DECL_FCONTEXT (t));
+  if (mentions_vars_p_decl_common (t))
+    return true;
+  CHECK_NO_VAR (DECL_FIELD_OFFSET (t));
+  CHECK_NO_VAR (DECL_BIT_FIELD_TYPE (t));
+  CHECK_NO_VAR (DECL_QUALIFIER (t));
+  CHECK_NO_VAR (DECL_FIELD_BIT_OFFSET (t));
+  CHECK_NO_VAR (DECL_FCONTEXT (t));
+  return false;
 }
 
-/* Fix up fields of a type T.  */
+/* Check presence of pointers to decls in fields of a type T.  */
 
-static void
-maybe_remember_with_vars_type (tree t)
+static bool
+mentions_vars_p_type (tree t)
 {
-  maybe_remember_with_vars_common (t);
-  MAYBE_REMEMBER_WITH_VARS (TYPE_CACHED_VALUES (t));
-  MAYBE_REMEMBER_WITH_VARS (TYPE_SIZE (t));
-  MAYBE_REMEMBER_WITH_VARS (TYPE_SIZE_UNIT (t));
-  MAYBE_REMEMBER_WITH_VARS (TYPE_ATTRIBUTES (t));
-  MAYBE_REMEMBER_WITH_VARS (TYPE_NAME (t));
-
-  /* Accessors are for derived node types only. */
-  if (!POINTER_TYPE_P (t))
-    MAYBE_REMEMBER_WITH_VARS (TYPE_MINVAL (t));
-  MAYBE_REMEMBER_WITH_VARS (TYPE_MAXVAL (t));
+  if (mentions_vars_p_common (t))
+    return true;
+  CHECK_NO_VAR (TYPE_CACHED_VALUES (t));
+  CHECK_VAR (TYPE_SIZE (t));
+  CHECK_VAR (TYPE_SIZE_UNIT (t));
+  CHECK_NO_VAR (TYPE_ATTRIBUTES (t));
+  CHECK_NO_VAR (TYPE_NAME (t));
+
+  CHECK_VAR (TYPE_MINVAL (t));
+  CHECK_VAR (TYPE_MAXVAL (t));
 
   /* Accessor is for derived node types only. */
-  MAYBE_REMEMBER_WITH_VARS (t->type_non_common.binfo);
+  CHECK_NO_VAR (t->type_non_common.binfo);
 
-  MAYBE_REMEMBER_WITH_VARS (TYPE_CONTEXT (t));
+  CHECK_VAR (TYPE_CONTEXT (t));
+  CHECK_NO_VAR (TYPE_CANONICAL (t));
+  CHECK_NO_VAR (TYPE_MAIN_VARIANT (t));
+  CHECK_NO_VAR (TYPE_NEXT_VARIANT (t));
+  return false;
 }
 
-/* Fix up fields of a BINFO T.  */
+/* Check presence of pointers to decls in fields of a BINFO T.  */
 
-static void
-maybe_remember_with_vars_binfo (tree t)
+static bool
+mentions_vars_p_binfo (tree t)
 {
   unsigned HOST_WIDE_INT i, n;
 
-  maybe_remember_with_vars_common (t);
-  MAYBE_REMEMBER_WITH_VARS (BINFO_VTABLE (t));
-  MAYBE_REMEMBER_WITH_VARS (BINFO_OFFSET (t));
-  MAYBE_REMEMBER_WITH_VARS (BINFO_VIRTUALS (t));
-  MAYBE_REMEMBER_WITH_VARS (BINFO_VPTR_FIELD (t));
+  if (mentions_vars_p_common (t))
+    return true;
+  CHECK_VAR (BINFO_VTABLE (t));
+  CHECK_NO_VAR (BINFO_OFFSET (t));
+  CHECK_NO_VAR (BINFO_VIRTUALS (t));
+  CHECK_NO_VAR (BINFO_VPTR_FIELD (t));
   n = vec_safe_length (BINFO_BASE_ACCESSES (t));
   for (i = 0; i < n; i++)
-    MAYBE_REMEMBER_WITH_VARS (BINFO_BASE_ACCESS (t, i));
+    CHECK_NO_VAR (BINFO_BASE_ACCESS (t, i));
   /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
      and BINFO_VPTR_INDEX; these are used by C++ FE only.  */
   n = BINFO_N_BASE_BINFOS (t);
   for (i = 0; i < n; i++)
-    MAYBE_REMEMBER_WITH_VARS (BINFO_BASE_BINFO (t, i));
+    CHECK_NO_VAR (BINFO_BASE_BINFO (t, i));
+  return false;
 }
 
-/* Fix up fields of a CONSTRUCTOR T.  */
+/* Check presence of pointers to decls in fields of a CONSTRUCTOR T.  */
 
-static void
-maybe_remember_with_vars_constructor (tree t)
+static bool
+mentions_vars_p_constructor (tree t)
 {
   unsigned HOST_WIDE_INT idx;
   constructor_elt *ce;
 
-  maybe_remember_with_vars_typed (t);
+  if (mentions_vars_p_typed (t))
+    return true;
 
   for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce); idx++)
     {
-      MAYBE_REMEMBER_WITH_VARS (ce->index);
-      MAYBE_REMEMBER_WITH_VARS (ce->value);
+      CHECK_NO_VAR (ce->index);
+      CHECK_VAR (ce->value);
     }
+  return false;
 }
 
-/* Fix up fields of an expression tree T.  */
+/* Check presence of pointers to decls in fields of an expression tree T.  */
 
-static void
-maybe_remember_with_vars_expr (tree t)
+static bool
+mentions_vars_p_expr (tree t)
 {
   int i;
-  maybe_remember_with_vars_typed (t);
+  if (mentions_vars_p_typed (t))
+    return true;
   for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
-    MAYBE_REMEMBER_WITH_VARS (TREE_OPERAND (t, i));
+    CHECK_VAR (TREE_OPERAND (t, i));
+  return false;
 }
 
-/* Given a tree T fixup fields of T by replacing types with their merged
-   variant and other entities by an equal entity from an earlier compilation
-   unit, or an entity being canonical in a different way.  This includes
-   for instance integer or string constants.  */
+/* Check presence of pointers to decls that needs later fixup in T.  */
 
-static void
-maybe_remember_with_vars (tree t)
+static bool
+mentions_vars_p (tree t)
 {
   switch (TREE_CODE (t))
     {
@@ -1480,13 +1493,13 @@ maybe_remember_with_vars (tree t)
       break;
 
     case TREE_LIST:
-      MAYBE_REMEMBER_WITH_VARS (TREE_VALUE (t));
-      MAYBE_REMEMBER_WITH_VARS (TREE_PURPOSE (t));
-      MAYBE_REMEMBER_WITH_VARS (TREE_CHAIN (t));
+      CHECK_VAR (TREE_VALUE (t));
+      CHECK_VAR (TREE_PURPOSE (t));
+      CHECK_NO_VAR (TREE_CHAIN (t));
       break;
 
     case FIELD_DECL:
-      maybe_remember_with_vars_field_decl (t);
+      return mentions_vars_p_field_decl (t);
       break;
 
     case LABEL_DECL:
@@ -1494,27 +1507,28 @@ maybe_remember_with_vars (tree t)
     case PARM_DECL:
     case RESULT_DECL:
     case IMPORTED_DECL:
-      maybe_remember_with_vars_decl_common (t);
+    case NAMESPACE_DECL:
+      return mentions_vars_p_decl_common (t);
       break;
 
     case VAR_DECL:
-      maybe_remember_with_vars_decl_with_vis (t);
+      return mentions_vars_p_decl_with_vis (t);
       break;
 
     case TYPE_DECL:
-      maybe_remember_with_vars_decl_non_common (t);
+      return mentions_vars_p_decl_non_common (t);
       break;
 
     case FUNCTION_DECL:
-      maybe_remember_with_vars_function (t);
+      return mentions_vars_p_function (t);
       break;
 
     case TREE_BINFO:
-      maybe_remember_with_vars_binfo (t);
+      return mentions_vars_p_binfo (t);
       break;
 
     case PLACEHOLDER_EXPR:
-      maybe_remember_with_vars_common (t);
+      return mentions_vars_p_common (t);
       break;
 
     case BLOCK:
@@ -1524,19 +1538,26 @@ maybe_remember_with_vars (tree t)
       break;
 
     case CONSTRUCTOR:
-      maybe_remember_with_vars_constructor (t);
+      return mentions_vars_p_constructor (t);
       break;
 
     default:
       if (TYPE_P (t))
-	maybe_remember_with_vars_type (t);
-      else if (CONSTANT_CLASS_P (t))
-	MAYBE_REMEMBER_WITH_VARS (TREE_TYPE (t));
+	{
+	  if (mentions_vars_p_type (t))
+	    return true;
+	}
       else if (EXPR_P (t))
-	maybe_remember_with_vars_expr (t);
+	{
+	  if (mentions_vars_p_expr (t))
+	    return true;
+	}
+      else if (CONSTANT_CLASS_P (t))
+	CHECK_NO_VAR (TREE_TYPE (t));
       else
-	remember_with_vars (t);
+	gcc_unreachable ();
     }
+  return false;
 }
 
 
@@ -2492,7 +2513,8 @@ lto_read_decls (struct lto_file_decl_dat
 		    lto_register_function_decl_in_symtab (data_in, t, from + i);
 		  /* Scan the tree for references to global functions or
 		     variables and record those for later fixup.  */
-		  maybe_remember_with_vars (t);
+		  if (mentions_vars_p (t))
+		    vec_safe_push (tree_with_vars, t);
 		}
 	    }
 	  if (not_merged_type_same_scc)
@@ -3137,8 +3247,12 @@ lto_wpa_write_files (void)
    prevailing variant.  */
 #define LTO_SET_PREVAIL(tt) \
   do {\
-    if ((tt) && VAR_OR_FUNCTION_DECL_P (tt)) \
-      tt = lto_symtab_prevailing_decl (tt); \
+    if ((tt) && VAR_OR_FUNCTION_DECL_P (tt) \
+	&& (TREE_PUBLIC (tt) || DECL_EXTERNAL (tt))) \
+      { \
+        tt = lto_symtab_prevailing_decl (tt); \
+	fixed = true; \
+      } \
   } while (0)
 
 /* Ensure that TT isn't a replacable var of function decl.  */
@@ -3151,6 +3265,9 @@ static void
 lto_fixup_prevailing_decls (tree t)
 {
   enum tree_code code = TREE_CODE (t);
+  bool fixed = false;
+
+  gcc_checking_assert (code != CONSTRUCTOR && code != TREE_BINFO);
   LTO_NO_PREVAIL (TREE_TYPE (t));
   if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
     LTO_NO_PREVAIL (TREE_CHAIN (t));
@@ -3198,7 +3315,7 @@ lto_fixup_prevailing_decls (tree t)
 
       LTO_SET_PREVAIL (TYPE_MINVAL (t));
       LTO_SET_PREVAIL (TYPE_MAXVAL (t));
-      LTO_SET_PREVAIL (t->type_non_common.binfo);
+      LTO_NO_PREVAIL (t->type_non_common.binfo);
 
       LTO_SET_PREVAIL (TYPE_CONTEXT (t));
 
@@ -3219,11 +3336,15 @@ lto_fixup_prevailing_decls (tree t)
 	case TREE_LIST:
 	  LTO_SET_PREVAIL (TREE_VALUE (t));
 	  LTO_SET_PREVAIL (TREE_PURPOSE (t));
+	  LTO_NO_PREVAIL (TREE_PURPOSE (t));
 	  break;
 	default:
 	  gcc_unreachable ();
 	}
     }
+  /* If we fixed nothing, then we missed something seen by
+     mentions_vars_p.  */
+  gcc_checking_assert (fixed);
 }
 #undef LTO_SET_PREVAIL
 #undef LTO_NO_PREVAIL
@@ -3246,7 +3368,8 @@ lto_fixup_state (struct lto_in_decl_stat
       for (i = 0; i < table->size; i++)
 	{
 	  tree *tp = table->trees + i;
-	  if (VAR_OR_FUNCTION_DECL_P (*tp))
+	  if (VAR_OR_FUNCTION_DECL_P (*tp)
+	      && (TREE_PUBLIC (*tp) || DECL_EXTERNAL (*tp)))
 	    *tp = lto_symtab_prevailing_decl (*tp);
 	}
     }
@@ -3270,11 +3393,11 @@ static void
 lto_fixup_decls (struct lto_file_decl_data **files)
 {
   unsigned int i;
-  htab_iterator hi;
   tree t;
 
+  if (tree_with_vars)
+    FOR_EACH_VEC_ELT ((*tree_with_vars), i, t)
+      lto_fixup_prevailing_decls (t);
-  htab_iterator hi;
-  FOR_EACH_HTAB_ELEMENT (tree_with_vars, t, tree, hi)
-    lto_fixup_prevailing_decls (t);
 
   for (i = 0; files[i]; i++)
     {
@@ -3364,8 +3491,6 @@ read_cgraph_and_symbols (unsigned nfiles
     }
   cgraph_state = CGRAPH_LTO_STREAMING;
 
-  tree_with_vars = htab_create_ggc (101, htab_hash_pointer, htab_eq_pointer,
-				    NULL);
   type_hash_cache = htab_create_ggc (512, tree_int_map_hash,
 				     tree_int_map_eq, NULL);
   type_pair_cache = XCNEWVEC (struct type_pair_d, GIMPLE_TYPE_PAIR_SIZE);
@@ -3481,9 +3605,10 @@ read_cgraph_and_symbols (unsigned nfiles
       /* Fixup all decls.  */
       lto_fixup_decls (all_file_decl_data);
     }
-  htab_delete (tree_with_vars);
+  if (tree_with_vars)
+    ggc_free (tree_with_vars);
   tree_with_vars = NULL;
   ggc_collect ();
 
   timevar_pop (TV_IPA_LTO_DECL_MERGE);
   /* Each pass will set the appropriate timer.  */

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

* Re: Remove hash from remember_with_vars
  2013-08-31 16:24 Remove hash from remember_with_vars Jan Hubicka
@ 2013-08-31 17:26 ` Richard Biener
  2013-08-31 20:15   ` Bernhard Reutner-Fischer
  2013-09-02 14:44   ` Jan Hubicka
  0 siblings, 2 replies; 4+ messages in thread
From: Richard Biener @ 2013-08-31 17:26 UTC (permalink / raw)
  To: Jan Hubicka, gcc-patches

Jan Hubicka <hubicka@ucw.cz> wrote:
>Hi,
>remember_with_vars walks trees that are read from file (now unique)
>and looks for fields that can contain pointers to vars or functions and
>if so, it records them to global hashtable for later fixup.
>This is quite wasteful, because the hash is querried many times.
>We can simply walk all fields in a tree and record the tree once
>afterwards,
>moreover since streaming knows when tree is newly constructed, we don't
>need
>hash.
>
>Vectors do not allow deletable elements, but I think it makes no
>difference:
>the trees are all used from decl states.

Heh, indeed a cleanup possibility I missed.

Ok.
Thanks,
Richard.

>	* lot.c (tree_with_vars): Turn into vector.
>	(MAYBE_REMEMBER_WITH_VARS): Change to...
>	(CHECK_VAR): ... this one.
>	(CHECK_NO_VAR): New macro.
>	(maybe_remember_with_vars_typed): Trun to ...
>	(mentions_vars_p_typed): ... this one.
>	(maybe_remember_with_vars_common): Trun to ...
>	(mentions_vars_p_comon): ... this one.
>	(maybe_remember_with_vars_decl_minimal): Trun to ...
>	(mentions_vars_p_decl_minmal): ... this one.
>	(maybe_remember_with_vars_decl_common): Trun to ...
>	(mentions_vars_p_decl_common): ... this one.
>	(maybe_remember_with_vars_decl_with_vis): Trun to ...
>	(mentions_vars_p_decl_with_vis): ... this one.
>	(maybe_remember_with_vars_decl_non_common): Trun to ...
>	(mentions_vars_p_decl_non_common): ... this one.
>	(maybe_remember_with_vars_function): Trun to ...
>	(mentions_vars_p_function): ... this one.
>	(maybe_remember_with_vars_field_decl): Trun to ...
>	(mentions_vars_p_field_decl): ... this one.
>	(maybe_remember_with_vars_type): Trun to ...
>	(mentions_vars_p_type): ... this one.
>	(maybe_remember_with_vars_binfo): Trun to ...
>	(mentions_vars_p_binfo): ... this one.
>	(maybe_remember_with_vars_constructor): Trun to ...
>	(mentions_vars_p_constructor): ... this one.
>	(maybe_remember_with_vars_expr): Trun to ...
>	(mentions_vars_p_expr): ... this one.
>	(maybe_remember_with_vars): Trun to ...
>	(mentions_vars_p): ... this one.
>	(lto_read_decls): Update.
>	(LTO_SET_PREVAIL): Do not call function for internal decls.
>	(lto_fixup_prevailing_decls): Update to match mentions_vars_p;
>	check that something was updated.
>	(lto_fixup_state): Do not care about internal decls.
>	(lto_fixup_decls): Update.
>	(read_cgraph_and_symbols): Update.
>Index: lto/lto.c
>===================================================================
>--- lto/lto.c	(revision 202099)
>+++ lto/lto.c	(working copy)
>@@ -1283,196 +1286,206 @@ gimple_register_type (tree t)
> 
> /* End of old merging code.  */
> 
>+/* Remember trees that contains references to declarations.  */
>+static GTY(()) vec <tree, va_gc> *tree_with_vars;
> 
>-
>-/* A hashtable of trees that potentially refer to variables or
>functions
>-   that must be replaced with their prevailing variant.  */
>-static GTY((if_marked ("ggc_marked_p"), param_is (union tree_node)))
>htab_t
>-  tree_with_vars;
>-
>-/* Remember that T is a tree that (potentially) refers to a variable
>-   or function decl that may be replaced with its prevailing variant. 
>*/
>-static void
>-remember_with_vars (tree t)
>-{
>-  *(tree *) htab_find_slot (tree_with_vars, t, INSERT) = t;
>-}
>-
>-#define MAYBE_REMEMBER_WITH_VARS(tt) \
>+#define CHECK_VAR(tt) \
>   do \
>     { \
>-      if (tt) \
>-	{ \
>-	  if (VAR_OR_FUNCTION_DECL_P (tt) && TREE_PUBLIC (tt)) \
>-	    remember_with_vars (t); \
>-	} \
>+      if ((tt) && VAR_OR_FUNCTION_DECL_P (tt) \
>+	  && (TREE_PUBLIC (tt) || DECL_EXTERNAL (tt))) \
>+	return true; \
>     } while (0)
> 
>-/* Fix up fields of a tree_typed T.  */
>+#define CHECK_NO_VAR(tt) \
>+  gcc_checking_assert (!(tt) || !VAR_OR_FUNCTION_DECL_P (tt))
> 
>-static void
>-maybe_remember_with_vars_typed (tree t)
>+/* Check presence of pointers to decls in fields of a tree_typed T. 
>*/
>+
>+static inline bool
>+mentions_vars_p_typed (tree t)
> {
>-  MAYBE_REMEMBER_WITH_VARS (TREE_TYPE (t));
>+  CHECK_NO_VAR (TREE_TYPE (t));
>+  return false;
> }
> 
>-/* Fix up fields of a tree_common T.  */
>+/* Check presence of pointers to decls in fields of a tree_common T. 
>*/
> 
>-static void
>-maybe_remember_with_vars_common (tree t)
>+static inline bool
>+mentions_vars_p_common (tree t)
> {
>-  maybe_remember_with_vars_typed (t);
>-  MAYBE_REMEMBER_WITH_VARS (TREE_CHAIN (t));
>+  if (mentions_vars_p_typed (t))
>+    return true;
>+  CHECK_NO_VAR (TREE_CHAIN (t));
>+  return false;
> }
> 
>-/* Fix up fields of a decl_minimal T.  */
>+/* Check presence of pointers to decls in fields of a decl_minimal T. 
>*/
> 
>-static void
>-maybe_remember_with_vars_decl_minimal (tree t)
>+static inline bool
>+mentions_vars_p_decl_minimal (tree t)
> {
>-  maybe_remember_with_vars_common (t);
>-  MAYBE_REMEMBER_WITH_VARS (DECL_NAME (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_CONTEXT (t));
>+  if (mentions_vars_p_common (t))
>+    return true;
>+  CHECK_NO_VAR (DECL_NAME (t));
>+  CHECK_VAR (DECL_CONTEXT (t));
>+  return false;
> }
> 
>-/* Fix up fields of a decl_common T.  */
>+/* Check presence of pointers to decls in fields of a decl_common T. 
>*/
> 
>-static void
>-maybe_remember_with_vars_decl_common (tree t)
>+static inline bool
>+mentions_vars_p_decl_common (tree t)
> {
>-  maybe_remember_with_vars_decl_minimal (t);
>-  MAYBE_REMEMBER_WITH_VARS (DECL_SIZE (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_SIZE_UNIT (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_INITIAL (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_ATTRIBUTES (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_ABSTRACT_ORIGIN (t));
>+  if (mentions_vars_p_decl_minimal (t))
>+    return true;
>+  CHECK_VAR (DECL_SIZE (t));
>+  CHECK_VAR (DECL_SIZE_UNIT (t));
>+  CHECK_VAR (DECL_INITIAL (t));
>+  CHECK_NO_VAR (DECL_ATTRIBUTES (t));
>+  CHECK_VAR (DECL_ABSTRACT_ORIGIN (t));
>+  return false;
> }
> 
>-/* Fix up fields of a decl_with_vis T.  */
>+/* Check presence of pointers to decls in fields of a decl_with_vis T.
> */
> 
>-static void
>-maybe_remember_with_vars_decl_with_vis (tree t)
>+static inline bool
>+mentions_vars_p_decl_with_vis (tree t)
> {
>-  maybe_remember_with_vars_decl_common (t);
>+  if (mentions_vars_p_decl_common (t))
>+    return true;
> 
>   /* Accessor macro has side-effects, use field-name here. */
>-  MAYBE_REMEMBER_WITH_VARS (t->decl_with_vis.assembler_name);
>-  MAYBE_REMEMBER_WITH_VARS (DECL_SECTION_NAME (t));
>+  CHECK_NO_VAR (t->decl_with_vis.assembler_name);
>+  CHECK_NO_VAR (DECL_SECTION_NAME (t));
>+  return false;
> }
> 
>-/* Fix up fields of a decl_non_common T.  */
>+/* Check presence of pointers to decls in fields of a decl_non_common
>T.  */
> 
>-static void
>-maybe_remember_with_vars_decl_non_common (tree t)
>+static inline bool
>+mentions_vars_p_decl_non_common (tree t)
> {
>-  maybe_remember_with_vars_decl_with_vis (t);
>-  MAYBE_REMEMBER_WITH_VARS (DECL_ARGUMENT_FLD (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_RESULT_FLD (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_VINDEX (t));
>+  if (mentions_vars_p_decl_with_vis (t))
>+    return true;
>+  CHECK_NO_VAR (DECL_ARGUMENT_FLD (t));
>+  CHECK_NO_VAR (DECL_RESULT_FLD (t));
>+  CHECK_NO_VAR (DECL_VINDEX (t));
>+  return false;
> }
> 
>-/* Fix up fields of a decl_non_common T.  */
>+/* Check presence of pointers to decls in fields of a decl_non_common
>T.  */
> 
>-static void
>-maybe_remember_with_vars_function (tree t)
>+static bool
>+mentions_vars_p_function (tree t)
> {
>-  maybe_remember_with_vars_decl_non_common (t);
>-  MAYBE_REMEMBER_WITH_VARS (DECL_FUNCTION_PERSONALITY (t));
>+  if (mentions_vars_p_decl_non_common (t))
>+    return true;
>+  CHECK_VAR (DECL_FUNCTION_PERSONALITY (t));
>+  return false;
> }
> 
>-/* Fix up fields of a field_decl T.  */
>+/* Check presence of pointers to decls in fields of a field_decl T. 
>*/
> 
>-static void
>-maybe_remember_with_vars_field_decl (tree t)
>+static bool
>+mentions_vars_p_field_decl (tree t)
> {
>-  maybe_remember_with_vars_decl_common (t);
>-  MAYBE_REMEMBER_WITH_VARS (DECL_FIELD_OFFSET (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_BIT_FIELD_TYPE (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_QUALIFIER (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_FIELD_BIT_OFFSET (t));
>-  MAYBE_REMEMBER_WITH_VARS (DECL_FCONTEXT (t));
>+  if (mentions_vars_p_decl_common (t))
>+    return true;
>+  CHECK_NO_VAR (DECL_FIELD_OFFSET (t));
>+  CHECK_NO_VAR (DECL_BIT_FIELD_TYPE (t));
>+  CHECK_NO_VAR (DECL_QUALIFIER (t));
>+  CHECK_NO_VAR (DECL_FIELD_BIT_OFFSET (t));
>+  CHECK_NO_VAR (DECL_FCONTEXT (t));
>+  return false;
> }
> 
>-/* Fix up fields of a type T.  */
>+/* Check presence of pointers to decls in fields of a type T.  */
> 
>-static void
>-maybe_remember_with_vars_type (tree t)
>+static bool
>+mentions_vars_p_type (tree t)
> {
>-  maybe_remember_with_vars_common (t);
>-  MAYBE_REMEMBER_WITH_VARS (TYPE_CACHED_VALUES (t));
>-  MAYBE_REMEMBER_WITH_VARS (TYPE_SIZE (t));
>-  MAYBE_REMEMBER_WITH_VARS (TYPE_SIZE_UNIT (t));
>-  MAYBE_REMEMBER_WITH_VARS (TYPE_ATTRIBUTES (t));
>-  MAYBE_REMEMBER_WITH_VARS (TYPE_NAME (t));
>-
>-  /* Accessors are for derived node types only. */
>-  if (!POINTER_TYPE_P (t))
>-    MAYBE_REMEMBER_WITH_VARS (TYPE_MINVAL (t));
>-  MAYBE_REMEMBER_WITH_VARS (TYPE_MAXVAL (t));
>+  if (mentions_vars_p_common (t))
>+    return true;
>+  CHECK_NO_VAR (TYPE_CACHED_VALUES (t));
>+  CHECK_VAR (TYPE_SIZE (t));
>+  CHECK_VAR (TYPE_SIZE_UNIT (t));
>+  CHECK_NO_VAR (TYPE_ATTRIBUTES (t));
>+  CHECK_NO_VAR (TYPE_NAME (t));
>+
>+  CHECK_VAR (TYPE_MINVAL (t));
>+  CHECK_VAR (TYPE_MAXVAL (t));
> 
>   /* Accessor is for derived node types only. */
>-  MAYBE_REMEMBER_WITH_VARS (t->type_non_common.binfo);
>+  CHECK_NO_VAR (t->type_non_common.binfo);
> 
>-  MAYBE_REMEMBER_WITH_VARS (TYPE_CONTEXT (t));
>+  CHECK_VAR (TYPE_CONTEXT (t));
>+  CHECK_NO_VAR (TYPE_CANONICAL (t));
>+  CHECK_NO_VAR (TYPE_MAIN_VARIANT (t));
>+  CHECK_NO_VAR (TYPE_NEXT_VARIANT (t));
>+  return false;
> }
> 
>-/* Fix up fields of a BINFO T.  */
>+/* Check presence of pointers to decls in fields of a BINFO T.  */
> 
>-static void
>-maybe_remember_with_vars_binfo (tree t)
>+static bool
>+mentions_vars_p_binfo (tree t)
> {
>   unsigned HOST_WIDE_INT i, n;
> 
>-  maybe_remember_with_vars_common (t);
>-  MAYBE_REMEMBER_WITH_VARS (BINFO_VTABLE (t));
>-  MAYBE_REMEMBER_WITH_VARS (BINFO_OFFSET (t));
>-  MAYBE_REMEMBER_WITH_VARS (BINFO_VIRTUALS (t));
>-  MAYBE_REMEMBER_WITH_VARS (BINFO_VPTR_FIELD (t));
>+  if (mentions_vars_p_common (t))
>+    return true;
>+  CHECK_VAR (BINFO_VTABLE (t));
>+  CHECK_NO_VAR (BINFO_OFFSET (t));
>+  CHECK_NO_VAR (BINFO_VIRTUALS (t));
>+  CHECK_NO_VAR (BINFO_VPTR_FIELD (t));
>   n = vec_safe_length (BINFO_BASE_ACCESSES (t));
>   for (i = 0; i < n; i++)
>-    MAYBE_REMEMBER_WITH_VARS (BINFO_BASE_ACCESS (t, i));
>+    CHECK_NO_VAR (BINFO_BASE_ACCESS (t, i));
>   /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
>      and BINFO_VPTR_INDEX; these are used by C++ FE only.  */
>   n = BINFO_N_BASE_BINFOS (t);
>   for (i = 0; i < n; i++)
>-    MAYBE_REMEMBER_WITH_VARS (BINFO_BASE_BINFO (t, i));
>+    CHECK_NO_VAR (BINFO_BASE_BINFO (t, i));
>+  return false;
> }
> 
>-/* Fix up fields of a CONSTRUCTOR T.  */
>+/* Check presence of pointers to decls in fields of a CONSTRUCTOR T. 
>*/
> 
>-static void
>-maybe_remember_with_vars_constructor (tree t)
>+static bool
>+mentions_vars_p_constructor (tree t)
> {
>   unsigned HOST_WIDE_INT idx;
>   constructor_elt *ce;
> 
>-  maybe_remember_with_vars_typed (t);
>+  if (mentions_vars_p_typed (t))
>+    return true;
> 
>for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce); idx++)
>     {
>-      MAYBE_REMEMBER_WITH_VARS (ce->index);
>-      MAYBE_REMEMBER_WITH_VARS (ce->value);
>+      CHECK_NO_VAR (ce->index);
>+      CHECK_VAR (ce->value);
>     }
>+  return false;
> }
> 
>-/* Fix up fields of an expression tree T.  */
>+/* Check presence of pointers to decls in fields of an expression tree
>T.  */
> 
>-static void
>-maybe_remember_with_vars_expr (tree t)
>+static bool
>+mentions_vars_p_expr (tree t)
> {
>   int i;
>-  maybe_remember_with_vars_typed (t);
>+  if (mentions_vars_p_typed (t))
>+    return true;
>   for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
>-    MAYBE_REMEMBER_WITH_VARS (TREE_OPERAND (t, i));
>+    CHECK_VAR (TREE_OPERAND (t, i));
>+  return false;
> }
> 
>-/* Given a tree T fixup fields of T by replacing types with their
>merged
>-   variant and other entities by an equal entity from an earlier
>compilation
>-   unit, or an entity being canonical in a different way.  This
>includes
>-   for instance integer or string constants.  */
>+/* Check presence of pointers to decls that needs later fixup in T. 
>*/
> 
>-static void
>-maybe_remember_with_vars (tree t)
>+static bool
>+mentions_vars_p (tree t)
> {
>   switch (TREE_CODE (t))
>     {
>@@ -1480,13 +1493,13 @@ maybe_remember_with_vars (tree t)
>       break;
> 
>     case TREE_LIST:
>-      MAYBE_REMEMBER_WITH_VARS (TREE_VALUE (t));
>-      MAYBE_REMEMBER_WITH_VARS (TREE_PURPOSE (t));
>-      MAYBE_REMEMBER_WITH_VARS (TREE_CHAIN (t));
>+      CHECK_VAR (TREE_VALUE (t));
>+      CHECK_VAR (TREE_PURPOSE (t));
>+      CHECK_NO_VAR (TREE_CHAIN (t));
>       break;
> 
>     case FIELD_DECL:
>-      maybe_remember_with_vars_field_decl (t);
>+      return mentions_vars_p_field_decl (t);
>       break;
> 
>     case LABEL_DECL:
>@@ -1494,27 +1507,28 @@ maybe_remember_with_vars (tree t)
>     case PARM_DECL:
>     case RESULT_DECL:
>     case IMPORTED_DECL:
>-      maybe_remember_with_vars_decl_common (t);
>+    case NAMESPACE_DECL:
>+      return mentions_vars_p_decl_common (t);
>       break;
> 
>     case VAR_DECL:
>-      maybe_remember_with_vars_decl_with_vis (t);
>+      return mentions_vars_p_decl_with_vis (t);
>       break;
> 
>     case TYPE_DECL:
>-      maybe_remember_with_vars_decl_non_common (t);
>+      return mentions_vars_p_decl_non_common (t);
>       break;
> 
>     case FUNCTION_DECL:
>-      maybe_remember_with_vars_function (t);
>+      return mentions_vars_p_function (t);
>       break;
> 
>     case TREE_BINFO:
>-      maybe_remember_with_vars_binfo (t);
>+      return mentions_vars_p_binfo (t);
>       break;
> 
>     case PLACEHOLDER_EXPR:
>-      maybe_remember_with_vars_common (t);
>+      return mentions_vars_p_common (t);
>       break;
> 
>     case BLOCK:
>@@ -1524,19 +1538,26 @@ maybe_remember_with_vars (tree t)
>       break;
> 
>     case CONSTRUCTOR:
>-      maybe_remember_with_vars_constructor (t);
>+      return mentions_vars_p_constructor (t);
>       break;
> 
>     default:
>       if (TYPE_P (t))
>-	maybe_remember_with_vars_type (t);
>-      else if (CONSTANT_CLASS_P (t))
>-	MAYBE_REMEMBER_WITH_VARS (TREE_TYPE (t));
>+	{
>+	  if (mentions_vars_p_type (t))
>+	    return true;
>+	}
>       else if (EXPR_P (t))
>-	maybe_remember_with_vars_expr (t);
>+	{
>+	  if (mentions_vars_p_expr (t))
>+	    return true;
>+	}
>+      else if (CONSTANT_CLASS_P (t))
>+	CHECK_NO_VAR (TREE_TYPE (t));
>       else
>-	remember_with_vars (t);
>+	gcc_unreachable ();
>     }
>+  return false;
> }
> 
> 
>@@ -2492,7 +2513,8 @@ lto_read_decls (struct lto_file_decl_dat
> 		    lto_register_function_decl_in_symtab (data_in, t, from + i);
> 		  /* Scan the tree for references to global functions or
> 		     variables and record those for later fixup.  */
>-		  maybe_remember_with_vars (t);
>+		  if (mentions_vars_p (t))
>+		    vec_safe_push (tree_with_vars, t);
> 		}
> 	    }
> 	  if (not_merged_type_same_scc)
>@@ -3137,8 +3247,12 @@ lto_wpa_write_files (void)
>    prevailing variant.  */
> #define LTO_SET_PREVAIL(tt) \
>   do {\
>-    if ((tt) && VAR_OR_FUNCTION_DECL_P (tt)) \
>-      tt = lto_symtab_prevailing_decl (tt); \
>+    if ((tt) && VAR_OR_FUNCTION_DECL_P (tt) \
>+	&& (TREE_PUBLIC (tt) || DECL_EXTERNAL (tt))) \
>+      { \
>+        tt = lto_symtab_prevailing_decl (tt); \
>+	fixed = true; \
>+      } \
>   } while (0)
> 
> /* Ensure that TT isn't a replacable var of function decl.  */
>@@ -3151,6 +3265,9 @@ static void
> lto_fixup_prevailing_decls (tree t)
> {
>   enum tree_code code = TREE_CODE (t);
>+  bool fixed = false;
>+
>+  gcc_checking_assert (code != CONSTRUCTOR && code != TREE_BINFO);
>   LTO_NO_PREVAIL (TREE_TYPE (t));
>   if (CODE_CONTAINS_STRUCT (code, TS_COMMON))
>     LTO_NO_PREVAIL (TREE_CHAIN (t));
>@@ -3198,7 +3315,7 @@ lto_fixup_prevailing_decls (tree t)
> 
>       LTO_SET_PREVAIL (TYPE_MINVAL (t));
>       LTO_SET_PREVAIL (TYPE_MAXVAL (t));
>-      LTO_SET_PREVAIL (t->type_non_common.binfo);
>+      LTO_NO_PREVAIL (t->type_non_common.binfo);
> 
>       LTO_SET_PREVAIL (TYPE_CONTEXT (t));
> 
>@@ -3219,11 +3336,15 @@ lto_fixup_prevailing_decls (tree t)
> 	case TREE_LIST:
> 	  LTO_SET_PREVAIL (TREE_VALUE (t));
> 	  LTO_SET_PREVAIL (TREE_PURPOSE (t));
>+	  LTO_NO_PREVAIL (TREE_PURPOSE (t));
> 	  break;
> 	default:
> 	  gcc_unreachable ();
> 	}
>     }
>+  /* If we fixed nothing, then we missed something seen by
>+     mentions_vars_p.  */
>+  gcc_checking_assert (fixed);
> }
> #undef LTO_SET_PREVAIL
> #undef LTO_NO_PREVAIL
>@@ -3246,7 +3368,8 @@ lto_fixup_state (struct lto_in_decl_stat
>       for (i = 0; i < table->size; i++)
> 	{
> 	  tree *tp = table->trees + i;
>-	  if (VAR_OR_FUNCTION_DECL_P (*tp))
>+	  if (VAR_OR_FUNCTION_DECL_P (*tp)
>+	      && (TREE_PUBLIC (*tp) || DECL_EXTERNAL (*tp)))
> 	    *tp = lto_symtab_prevailing_decl (*tp);
> 	}
>     }
>@@ -3270,11 +3393,11 @@ static void
> lto_fixup_decls (struct lto_file_decl_data **files)
> {
>   unsigned int i;
>-  htab_iterator hi;
>   tree t;
> 
>+  if (tree_with_vars)
>+    FOR_EACH_VEC_ELT ((*tree_with_vars), i, t)
>+      lto_fixup_prevailing_decls (t);
>-  htab_iterator hi;
>-  FOR_EACH_HTAB_ELEMENT (tree_with_vars, t, tree, hi)
>-    lto_fixup_prevailing_decls (t);
> 
>   for (i = 0; files[i]; i++)
>     {
>@@ -3364,8 +3491,6 @@ read_cgraph_and_symbols (unsigned nfiles
>     }
>   cgraph_state = CGRAPH_LTO_STREAMING;
> 
>-  tree_with_vars = htab_create_ggc (101, htab_hash_pointer,
>htab_eq_pointer,
>-				    NULL);
>   type_hash_cache = htab_create_ggc (512, tree_int_map_hash,
> 				     tree_int_map_eq, NULL);
>type_pair_cache = XCNEWVEC (struct type_pair_d, GIMPLE_TYPE_PAIR_SIZE);
>@@ -3481,9 +3605,10 @@ read_cgraph_and_symbols (unsigned nfiles
>       /* Fixup all decls.  */
>       lto_fixup_decls (all_file_decl_data);
>     }
>-  htab_delete (tree_with_vars);
>+  if (tree_with_vars)
>+    ggc_free (tree_with_vars);
>   tree_with_vars = NULL;
>   ggc_collect ();
> 
>   timevar_pop (TV_IPA_LTO_DECL_MERGE);
>   /* Each pass will set the appropriate timer.  */


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

* Re: Remove hash from remember_with_vars
  2013-08-31 17:26 ` Richard Biener
@ 2013-08-31 20:15   ` Bernhard Reutner-Fischer
  2013-09-02 14:44   ` Jan Hubicka
  1 sibling, 0 replies; 4+ messages in thread
From: Bernhard Reutner-Fischer @ 2013-08-31 20:15 UTC (permalink / raw)
  To: Richard Biener, Jan Hubicka, gcc-patches

On 31 August 2013 19:15:46 Richard Biener <rguenther@suse.de> wrote:
> Jan Hubicka <hubicka@ucw.cz> wrote:
> >Hi,
> >remember_with_vars walks trees that are read from file (now unique)
> >and looks for fields that can contain pointers to vars or functions and
> >if so, it records them to global hashtable for later fixup.
> >This is quite wasteful, because the hash is querried many times.
> >We can simply walk all fields in a tree and record the tree once
> >afterwards,
> >moreover since streaming knows when tree is newly constructed, we don't
> >need
> >hash.
> >
> >Vectors do not allow deletable elements, but I think it makes no
> >difference:
> >the trees are all used from decl states.
>
> Heh, indeed a cleanup possibility I missed.
>
> Ok.

s/Trun/Turn/g
?
Thanks
> Thanks,
> Richard.
>
> >	* lot.c (tree_with_vars): Turn into vector.
> >	(MAYBE_REMEMBER_WITH_VARS): Change to...
> >	(CHECK_VAR): ... this one.
> >	(CHECK_NO_VAR): New macro.
> >	(maybe_remember_with_vars_typed): Trun to ...
> >	(mentions_vars_p_typed): ... this one.
> >	(maybe_remember_with_vars_common): Trun to ...
> >	(mentions_vars_p_comon): ... this one.
> >	(maybe_remember_with_vars_decl_minimal): Trun to ...
> >	(mentions_vars_p_decl_minmal): ... this one.
> >	(maybe_remember_with_vars_decl_common): Trun to ...
> >	(mentions_vars_p_decl_common): ... this one.
> >	(maybe_remember_with_vars_decl_with_vis): Trun to ...
> >	(mentions_vars_p_decl_with_vis): ... this one.
> >	(maybe_remember_with_vars_decl_non_common): Trun to ...
> >	(mentions_vars_p_decl_non_common): ... this one.
> >	(maybe_remember_with_vars_function): Trun to ...
> >	(mentions_vars_p_function): ... this one.
> >	(maybe_remember_with_vars_field_decl): Trun to ...
> >	(mentions_vars_p_field_decl): ... this one.
> >	(maybe_remember_with_vars_type): Trun to ...
> >	(mentions_vars_p_type): ... this one.
> >	(maybe_remember_with_vars_binfo): Trun to ...
> >	(mentions_vars_p_binfo): ... this one.
> >	(maybe_remember_with_vars_constructor): Trun to ...
> >	(mentions_vars_p_constructor): ... this one.
> >	(maybe_remember_with_vars_expr): Trun to ...
> >	(mentions_vars_p_expr): ... this one.
> >	(maybe_remember_with_vars): Trun to ...
> >	(mentions_vars_p): ... this one.
> >	(lto_read_decls): Update.
> >	(LTO_SET_PREVAIL): Do not call function for internal decls.
> >	(lto_fixup_prevailing_decls): Update to match mentions_vars_p;
> >	check that something was updated.
> >	(lto_fixup_state): Do not care about internal decls.
> >	(lto_fixup_decls): Update.
> >	(read_cgraph_and_symbols): Update.


Sent with AquaMail for Android
http://www.aqua-mail.com


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

* Re: Remove hash from remember_with_vars
  2013-08-31 17:26 ` Richard Biener
  2013-08-31 20:15   ` Bernhard Reutner-Fischer
@ 2013-09-02 14:44   ` Jan Hubicka
  1 sibling, 0 replies; 4+ messages in thread
From: Jan Hubicka @ 2013-09-02 14:44 UTC (permalink / raw)
  To: Richard Biener; +Cc: Jan Hubicka, gcc-patches

Hi,
unfortunately this patch ICEs on the following testcase
/* This used to fail on SPARC with an unaligned memory access.  */

void foo(int n)
{
  struct S {
    int i[n];
    unsigned int b:1;
    int i2;
  } __attribute__ ((packed)) __attribute__ ((aligned (4)));

  struct S s;

  s.i2 = 0;
}

int main(void)
{
  foo(4);
  
  return 0;
}

(in a tetsuite I must have missed during testing) because it check
that field offset is always non-variable.

I merely copied this sanity check from identical one in
lto_fixup_prevailing_decls that however does not fire because it needs
mentions_vars_p_field_decl to record the var first and that never happens.

This patch fixes it by adding an fixup.  Here the variable is local, but
moving n to file scope is allowed.

I have bootstrapped/regtested ppc64-linux, will commit it as obvious.

I apologize for the breakage.  I will prioritize fixing the fallout I caused
this week.

Honza

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 202173)
+++ ChangeLog	(working copy)
@@ -1,5 +1,10 @@
 2013-08-31  Jan Hubicka  <jh@suse.cz>
 
+	* lto.c (mentions_vars_p_field_decl, lto_fixup_prevailing_decls): 
+	DECL_FIELD_OFFSET can contain an reference to variable.
+
+2013-08-31  Jan Hubicka  <jh@suse.cz>
+
 	* lto.c (tree_with_vars): Turn into vector.
 	(MAYBE_REMEMBER_WITH_VARS): Change to...
 	(CHECK_VAR): ... this one.
Index: lto.c
===================================================================
--- lto.c	(revision 202153)
+++ lto.c	(working copy)
@@ -1389,7 +1389,7 @@ mentions_vars_p_field_decl (tree t)
 {
   if (mentions_vars_p_decl_common (t))
     return true;
-  CHECK_NO_VAR (DECL_FIELD_OFFSET (t));
+  CHECK_VAR (DECL_FIELD_OFFSET (t));
   CHECK_NO_VAR (DECL_BIT_FIELD_TYPE (t));
   CHECK_NO_VAR (DECL_QUALIFIER (t));
   CHECK_NO_VAR (DECL_FIELD_BIT_OFFSET (t));
@@ -3207,7 +3207,7 @@ lto_fixup_prevailing_decls (tree t)
 	LTO_SET_PREVAIL (DECL_FUNCTION_PERSONALITY (t));
       if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
 	{
-	  LTO_NO_PREVAIL (DECL_FIELD_OFFSET (t));
+	  LTO_SET_PREVAIL (DECL_FIELD_OFFSET (t));
 	  LTO_NO_PREVAIL (DECL_BIT_FIELD_TYPE (t));
 	  LTO_NO_PREVAIL (DECL_QUALIFIER (t));
 	  LTO_NO_PREVAIL (DECL_FIELD_BIT_OFFSET (t));

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

end of thread, other threads:[~2013-09-02 14:44 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-31 16:24 Remove hash from remember_with_vars Jan Hubicka
2013-08-31 17:26 ` Richard Biener
2013-08-31 20:15   ` Bernhard Reutner-Fischer
2013-09-02 14:44   ` 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).