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] [3/3] Fix bootstrap with -flto


Third part.  This part reconstructs the pointer-to and reference-to
chains during fixup and avoids streaming them.  We were arriving with
some odd pointer-to chains previously which confuses build_pointer_type
and caused it to re-build pointers endlessly.

Bootstrapped and tested on x86_64-unknown-linux-gnu.

Richard.

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

	PR lto/41071
	* gimple.c (gimple_register_type): Unlink a pointer from its
	pointer chain if we will use a different type for it.
	* lto-streamer-out.c (lto_output_ts_type_tree_pointers):
	Do not output TYPE_POINTER_TO, TYPE_REFERENCE_TO and
	TYPE_NEXT_PTR/REF_TO.
	* lto-streamer-in.c (lto_input_ts_type_tree_pointers):
	Do not input TYPE_POINTER_TO, TYPE_REFERENCE_TO and
	TYPE_NEXT_PTR/REF_TO.

	lto/
	* lto.c (lto_fixup_common): Re-build the pointer-to chain part one.
	(lto_fixup_type): Re-build the pointer-to chain part two.

Index: lto/gcc/lto-streamer-out.c
===================================================================
*** lto.orig/gcc/lto-streamer-out.c	2009-08-19 11:32:03.000000000 +0200
--- lto/gcc/lto-streamer-out.c	2009-08-19 11:32:25.000000000 +0200
*************** lto_output_ts_type_tree_pointers (struct
*** 1061,1070 ****
    lto_output_tree_or_ref (ob, TYPE_SIZE (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_SIZE_UNIT (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_ATTRIBUTES (expr), ref_p);
-   lto_output_tree_or_ref (ob, TYPE_POINTER_TO (expr), ref_p);
-   lto_output_tree_or_ref (ob, TYPE_REFERENCE_TO (expr), ref_p);
    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
--- 1061,1071 ----
    lto_output_tree_or_ref (ob, TYPE_SIZE (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_SIZE_UNIT (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_ATTRIBUTES (expr), ref_p);
    lto_output_tree_or_ref (ob, TYPE_NAME (expr), ref_p);
!   /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO nor
!      TYPE_NEXT_PTR_TO or TYPE_NEXT_REF_TO.  */
!   if (!POINTER_TYPE_P (expr))
!     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
Index: lto/gcc/gimple.c
===================================================================
*** lto.orig/gcc/gimple.c	2009-08-19 11:19:39.000000000 +0200
--- lto/gcc/gimple.c	2009-08-19 12:28:44.000000000 +0200
*************** gimple_register_type (tree t)
*** 3926,3931 ****
--- 3926,3963 ----
  	  TYPE_NEXT_VARIANT (t) = NULL_TREE;
  	}
  
+       /* If we are a pointer then remove us from the pointer-to or
+ 	 reference-to chain.  Otherwise we'd queue up a lot of duplicates
+ 	 there.  */
+       if (TREE_CODE (t) == POINTER_TYPE)
+ 	{
+ 	  if (TYPE_POINTER_TO (TREE_TYPE (t)) == t)
+ 	    TYPE_POINTER_TO (TREE_TYPE (t)) = TYPE_NEXT_PTR_TO (t);
+ 	  else
+ 	    {
+ 	      tree tem = TYPE_POINTER_TO (TREE_TYPE (t));
+ 	      while (tem && TYPE_NEXT_PTR_TO (tem) != t)
+ 		tem = TYPE_NEXT_PTR_TO (tem);
+ 	      if (tem)
+ 		TYPE_NEXT_PTR_TO (tem) = TYPE_NEXT_PTR_TO (t);
+ 	    }
+ 	  TYPE_NEXT_PTR_TO (t) = NULL_TREE;
+ 	}
+       else if (TREE_CODE (t) == REFERENCE_TYPE)
+ 	{
+ 	  if (TYPE_REFERENCE_TO (TREE_TYPE (t)) == t)
+ 	    TYPE_REFERENCE_TO (TREE_TYPE (t)) = TYPE_NEXT_REF_TO (t);
+ 	  else
+ 	    {
+ 	      tree tem = TYPE_REFERENCE_TO (TREE_TYPE (t));
+ 	      while (tem && TYPE_NEXT_REF_TO (tem) != t)
+ 		tem = TYPE_NEXT_REF_TO (tem);
+ 	      if (tem)
+ 		TYPE_NEXT_REF_TO (tem) = TYPE_NEXT_REF_TO (t);
+ 	    }
+ 	  TYPE_NEXT_REF_TO (t) = NULL_TREE;
+ 	}
+ 
        t = new_type;
      }
    else
Index: lto/gcc/lto-streamer-in.c
===================================================================
*** lto.orig/gcc/lto-streamer-in.c	2009-08-19 11:32:16.000000000 +0200
--- lto/gcc/lto-streamer-in.c	2009-08-19 11:32:34.000000000 +0200
*************** lto_input_ts_type_tree_pointers (struct
*** 1985,1994 ****
    TYPE_SIZE (expr) = lto_input_tree (ib, data_in);
    TYPE_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
    TYPE_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
-   TYPE_POINTER_TO (expr) = lto_input_tree (ib, data_in);
-   TYPE_REFERENCE_TO (expr) = lto_input_tree (ib, data_in);
    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
--- 1985,1995 ----
    TYPE_SIZE (expr) = lto_input_tree (ib, data_in);
    TYPE_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
    TYPE_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
    TYPE_NAME (expr) = lto_input_tree (ib, data_in);
!   /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO nor
!      TYPE_NEXT_PTR_TO or TYPE_NEXT_REF_TO.  */
!   if (!POINTER_TYPE_P (expr))
!     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
Index: lto/gcc/lto/lto.c
===================================================================
*** lto.orig/gcc/lto/lto.c	2009-08-19 11:16:15.000000000 +0200
--- lto/gcc/lto/lto.c	2009-08-19 12:25:41.000000000 +0200
*************** no_fixup_p (tree t)
*** 1114,1125 ****
  static void
  lto_fixup_common (tree t, void *data)
  {
!   /* If T has a type, make sure it is registered in the global type
!      table.  If the type existed already, use the existing one.  */
!   if (TREE_TYPE (t))
!     TREE_TYPE (t) = gimple_register_type (TREE_TYPE (t));
  
-   LTO_FIXUP_SUBTREE (TREE_TYPE (t));
    /* This is not very efficient because we cannot do tail-recursion with
       a long chain of trees. */
    LTO_FIXUP_SUBTREE (TREE_CHAIN (t));
--- 1114,1159 ----
  static void
  lto_fixup_common (tree t, void *data)
  {
!   /* The following re-creates the TYPE_REFERENCE_TO and TYPE_POINTER_TO
!      lists.  We do not stream TYPE_REFERENCE_TO, TYPE_POINTER_TO or
!      TYPE_NEXT_PTR_TO and TYPE_NEXT_REF_TO.
!      First remove us from any pointer list we are on.  */
!   if (TREE_CODE (t) == POINTER_TYPE)
!     {
!       if (TYPE_POINTER_TO (TREE_TYPE (t)) == t)
! 	TYPE_POINTER_TO (TREE_TYPE (t)) = TYPE_NEXT_PTR_TO (t);
!       else
! 	{
! 	  tree tem = TYPE_POINTER_TO (TREE_TYPE (t));
! 	  while (tem && TYPE_NEXT_PTR_TO (tem) != t)
! 	    tem = TYPE_NEXT_PTR_TO (tem);
! 	  if (tem)
! 	    TYPE_NEXT_PTR_TO (tem) = TYPE_NEXT_PTR_TO (t);
! 	}
!       TYPE_NEXT_PTR_TO (t) = NULL_TREE;
!     }
!   else if (TREE_CODE (t) == REFERENCE_TYPE)
!     {
!       if (TYPE_REFERENCE_TO (TREE_TYPE (t)) == t)
! 	TYPE_REFERENCE_TO (TREE_TYPE (t)) = TYPE_NEXT_REF_TO (t);
!       else
! 	{
! 	  tree tem = TYPE_REFERENCE_TO (TREE_TYPE (t));
! 	  while (tem && TYPE_NEXT_REF_TO (tem) != t)
! 	    tem = TYPE_NEXT_REF_TO (tem);
! 	  if (tem)
! 	    TYPE_NEXT_REF_TO (tem) = TYPE_NEXT_REF_TO (t);
! 	}
!       TYPE_NEXT_REF_TO (t) = NULL_TREE;
!     }
! 
!   /* Fixup our type.  */
!   LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TREE_TYPE (t));
! 
!   /* Second put us on the list of pointers of the new pointed-to type
!      if we are a main variant.  This is done in lto_fixup_type after
!      fixing up our main variant.  */
  
    /* This is not very efficient because we cannot do tail-recursion with
       a long chain of trees. */
    LTO_FIXUP_SUBTREE (TREE_CHAIN (t));
*************** lto_fixup_type (tree t, void *data)
*** 1209,1220 ****
    LTO_FIXUP_SUBTREE (TYPE_SIZE (t));
    LTO_FIXUP_SUBTREE (TYPE_SIZE_UNIT (t));
    LTO_FIXUP_SUBTREE (TYPE_ATTRIBUTES (t));
-   LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_POINTER_TO (t));
-   LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TYPE_REFERENCE_TO (t));
    LTO_FIXUP_SUBTREE (TYPE_NAME (t));
  
    /* Accessors are for derived node types only. */
!   LTO_FIXUP_SUBTREE (t->type.minval);
    LTO_FIXUP_SUBTREE (t->type.maxval);
  
    /* Accessor is for derived node types only. */
--- 1243,1253 ----
    LTO_FIXUP_SUBTREE (TYPE_SIZE (t));
    LTO_FIXUP_SUBTREE (TYPE_SIZE_UNIT (t));
    LTO_FIXUP_SUBTREE (TYPE_ATTRIBUTES (t));
    LTO_FIXUP_SUBTREE (TYPE_NAME (t));
  
    /* Accessors are for derived node types only. */
!   if (!POINTER_TYPE_P (t))
!     LTO_FIXUP_SUBTREE (t->type.minval);
    LTO_FIXUP_SUBTREE (t->type.maxval);
  
    /* Accessor is for derived node types only. */
*************** lto_fixup_type (tree t, void *data)
*** 1266,1271 ****
--- 1299,1320 ----
    /* Finally adjust our main variant and fix it up.  */
    TYPE_MAIN_VARIANT (t) = mv;
    LTO_FIXUP_SUBTREE (TYPE_MAIN_VARIANT (t));
+ 
+   /* As the second step of reconstructing the pointer chains put us
+      on the list of pointers of the new pointed-to type
+      if we are a main variant.  See lto_fixup_common for the first step.  */
+   if (TREE_CODE (t) == POINTER_TYPE
+       && TYPE_MAIN_VARIANT (t) == t)
+     {
+       TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (TREE_TYPE (t));
+       TYPE_POINTER_TO (TREE_TYPE (t)) = t;
+     }
+   else if (TREE_CODE (t) == REFERENCE_TYPE
+ 	   && TYPE_MAIN_VARIANT (t) == t)
+     {
+       TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (TREE_TYPE (t));
+       TYPE_REFERENCE_TO (TREE_TYPE (t)) = t;
+     }
  }
  
  /* Fix up fields of a BINFO T.  DATA points to fix-up states.  */


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