This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH][LTO] [2/3] Fix bootstrap with -flto


This is piece two.  It reconstructs the type variant chains during
fixup time and avoids streaming TYPE_NEXT_VARIANT at all.

Bootstrapped and tested on x86_64-unknown-linux-gnu ontop of patch one.

Richard.


2009-08-19  Richard Guenther  <rguenther@suse.de>

	PR lto/41071
	* gimple.c (gimple_register_type): Unlink a non-main-variant from its
	variant chain if we will use a different type for it.
	* tree.c (free_lang_data_in_type): Do not free the variant chains.
	* lto-streamer-out.c (lto_output_ts_type_tree_pointers): Do
	not output TYPE_NEXT_VARIANT.
	* lto-streamer-in.c (lto_input_ts_type_tree_pointers): Do not
	input TYPE_NEXT_VARIANT.

	lto/
	* lto.c (lto_fixup_type): Re-build the type variant chain.


Index: lto/gcc/gimple.c
===================================================================
*** lto.orig/gcc/gimple.c	2009-08-19 10:49:51.000000000 +0200
--- lto/gcc/gimple.c	2009-08-19 11:19:39.000000000 +0200
*************** gimple_register_type (tree t)
*** 3898,3904 ****
      }
  
    slot = htab_find_slot (gimple_types, t, INSERT);
!   if (*slot)
      {
        tree new_type = (tree) *((tree *) slot);
  
--- 3898,3905 ----
      }
  
    slot = htab_find_slot (gimple_types, t, INSERT);
!   if (*slot
!       && *(tree *)slot != t)
      {
        tree new_type = (tree) *((tree *) slot);
  
*************** gimple_register_type (tree t)
*** 3907,3918 ****
  
        if (getenv ("MERGE_TYPE_DEBUG"))
  	{
! 	  if (t != new_type)
! 	    {
! 	      fprintf (stderr, "Merged with existing compatible type: %p - ",
! 		  *slot);
! 	      print_generic_stmt (stderr, new_type, 0);
! 	    }
  	}
  
        t = new_type;
--- 3908,3929 ----
  
        if (getenv ("MERGE_TYPE_DEBUG"))
  	{
! 	  fprintf (stderr, "Merged with existing compatible type: %p - ",
! 		   *slot);
! 	  print_generic_stmt (stderr, new_type, 0);
! 	}
! 
!       /* If t is not its main variant then make t unreachable from its
! 	 main variant list.  Otherwise we'd queue up a lot of duplicates
! 	 there.  */
!       if (t != TYPE_MAIN_VARIANT (t))
! 	{
! 	  tree tem = TYPE_MAIN_VARIANT (t);
! 	  while (tem && TYPE_NEXT_VARIANT (tem) != t)
! 	    tem = TYPE_NEXT_VARIANT (tem);
! 	  if (tem)
! 	    TYPE_NEXT_VARIANT (tem) = TYPE_NEXT_VARIANT (t);
! 	  TYPE_NEXT_VARIANT (t) = NULL_TREE;
  	}
  
        t = new_type;
Index: lto/gcc/lto-streamer-in.c
===================================================================
*** lto.orig/gcc/lto-streamer-in.c	2009-08-18 17:24:59.000000000 +0200
--- lto/gcc/lto-streamer-in.c	2009-08-19 10:53:32.000000000 +0200
*************** lto_input_ts_type_tree_pointers (struct
*** 1990,1997 ****
    TYPE_NAME (expr) = lto_input_tree (ib, data_in);
    TYPE_MINVAL (expr) = lto_input_tree (ib, data_in);
    TYPE_MAXVAL (expr) = lto_input_tree (ib, data_in);
-   TYPE_NEXT_VARIANT (expr) = lto_input_tree (ib, data_in);
    TYPE_MAIN_VARIANT (expr) = lto_input_tree (ib, data_in);
    if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE)
      TYPE_BINFO (expr) = lto_input_tree (ib, data_in);
    TYPE_CONTEXT (expr) = lto_input_tree (ib, data_in);
--- 1990,1998 ----
    TYPE_NAME (expr) = lto_input_tree (ib, data_in);
    TYPE_MINVAL (expr) = lto_input_tree (ib, data_in);
    TYPE_MAXVAL (expr) = lto_input_tree (ib, data_in);
    TYPE_MAIN_VARIANT (expr) = lto_input_tree (ib, data_in);
+   /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
+      during fixup.  */
    if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE)
      TYPE_BINFO (expr) = lto_input_tree (ib, data_in);
    TYPE_CONTEXT (expr) = lto_input_tree (ib, data_in);
Index: lto/gcc/lto-streamer-out.c
===================================================================
*** lto.orig/gcc/lto-streamer-out.c	2009-08-19 10:49:51.000000000 +0200
--- lto/gcc/lto-streamer-out.c	2009-08-19 10:52:59.000000000 +0200
*************** lto_output_ts_type_tree_pointers (struct
*** 1066,1073 ****
    lto_output_tree_or_ref (ob, TYPE_NAME (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_MINVAL (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_MAXVAL (expr), ref_p);
-   lto_output_tree_or_ref (ob, TYPE_NEXT_VARIANT (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_MAIN_VARIANT (expr), ref_p);
    if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE)
      lto_output_tree_or_ref (ob, TYPE_BINFO (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_CONTEXT (expr), ref_p);
--- 1066,1074 ----
    lto_output_tree_or_ref (ob, TYPE_NAME (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_MINVAL (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_MAXVAL (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_MAIN_VARIANT (expr), ref_p);
+   /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
+      during fixup.  */
    if (TREE_CODE (expr) == RECORD_TYPE || TREE_CODE (expr) == UNION_TYPE)
      lto_output_tree_or_ref (ob, TYPE_BINFO (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_CONTEXT (expr), ref_p);
Index: lto/gcc/lto/lto.c
===================================================================
*** lto.orig/gcc/lto/lto.c	2009-08-19 10:49:51.000000000 +0200
--- lto/gcc/lto/lto.c	2009-08-19 11:16:15.000000000 +0200
*************** lto_fixup_field_decl (tree t, void *data
*** 1202,1207 ****
--- 1202,1209 ----
  static void
  lto_fixup_type (tree t, void *data)
  {
+   tree tem, mv;
+ 
    lto_fixup_common (t, data);
    LTO_FIXUP_SUBTREE (TYPE_CACHED_VALUES (t));
    LTO_FIXUP_SUBTREE (TYPE_SIZE (t));
*************** lto_fixup_type (tree t, void *data)
*** 1215,1228 ****
    LTO_FIXUP_SUBTREE (t->type.minval);
    LTO_FIXUP_SUBTREE (t->type.maxval);
  
-   LTO_FIXUP_SUBTREE (TYPE_NEXT_VARIANT (t));
-   LTO_FIXUP_SUBTREE (TYPE_MAIN_VARIANT (t));
- 
    /* Accessor is for derived node types only. */
    LTO_FIXUP_SUBTREE (t->type.binfo);
  
    LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CONTEXT (t));
    LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CANONICAL (t));
  }
  
  /* Fix up fields of a BINFO T.  DATA points to fix-up states.  */
--- 1217,1271 ----
    LTO_FIXUP_SUBTREE (t->type.minval);
    LTO_FIXUP_SUBTREE (t->type.maxval);
  
    /* Accessor is for derived node types only. */
    LTO_FIXUP_SUBTREE (t->type.binfo);
  
    LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CONTEXT (t));
    LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_CANONICAL (t));
+ 
+   /* The following re-creates proper variant lists while fixing up
+      the variant leaders.  We do not stream TYPE_NEXT_VARIANT so the
+      variant list state before fixup is broken.  */
+ 
+   /* Remove us from our main variant list if we are not the variant leader.  */
+   if (TYPE_MAIN_VARIANT (t) != t)
+     {
+       tem = TYPE_MAIN_VARIANT (t);
+       while (tem && TYPE_NEXT_VARIANT (tem) != t)
+ 	tem = TYPE_NEXT_VARIANT (tem);
+       if (tem)
+ 	TYPE_NEXT_VARIANT (tem) = TYPE_NEXT_VARIANT (t);
+       TYPE_NEXT_VARIANT (t) = NULL_TREE;
+     }
+ 
+   /* Query our new main variant.  */
+   mv = gimple_register_type (TYPE_MAIN_VARIANT (t));
+ 
+   /* If we were the variant leader and we get replaced ourselves drop
+      all variants from our list.  */
+   if (TYPE_MAIN_VARIANT (t) == t
+       && mv != t)
+     {
+       tem = t;
+       while (tem)
+ 	{
+ 	  tree tem2 = TYPE_NEXT_VARIANT (tem);
+ 	  TYPE_NEXT_VARIANT (tem) = NULL_TREE;
+ 	  tem = tem2;
+ 	}
+     }
+ 
+   /* If we are not our own variant leader link us into our new leaders
+      variant list.  */
+   if (mv != t)
+     {
+       TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (mv);
+       TYPE_NEXT_VARIANT (mv) = t;
+     }
+ 
+   /* Finally adjust our main variant and fix it up.  */
+   TYPE_MAIN_VARIANT (t) = mv;
+   LTO_FIXUP_SUBTREE (TYPE_MAIN_VARIANT (t));
  }
  
  /* Fix up fields of a BINFO T.  DATA points to fix-up states.  */
Index: lto/gcc/tree.c
===================================================================
*** lto.orig/gcc/tree.c	2009-08-18 17:24:59.000000000 +0200
--- lto/gcc/tree.c	2009-08-19 10:52:25.000000000 +0200
*************** free_lang_data_in_type (tree type)
*** 4222,4237 ****
  
    /* FIXME lto: This will break debug info generation.  */
    TYPE_STUB_DECL (type) = NULL_TREE;
- 
-   /* Remove type variants other than the main variant.  This is both
-      wasteful and it may introduce infinite loops when the types are
-      read from disk and merged (since the variant will be the same
-      type as the main variant, traversing type variants will get into
-      an infinite loop).  */
-   if (TYPE_MAIN_VARIANT (type))
-     TYPE_NEXT_VARIANT (TYPE_MAIN_VARIANT (type)) = NULL_TREE;
- 
-   TYPE_NEXT_VARIANT (type) = NULL_TREE;
  }
  
  
--- 4222,4227 ----


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]