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


I have dissected the previous big patch into three pieces.  This is
piece one which makes sure we have a consistent state before filling
the streamer cache with common nodes.  This is especially important
for WPA which else gets confused during final streaming in.
It also makes sure we replace types everywhere we should (apart from
the bits filled in in pieces 2 and 3).

Bootstrapped and tested on x86_64-unknown-linux-gnu.  The patch
removes the -funsigned-char hack as it doesn't work anymore, thus
gcc.dg/lto/20090120 now fails.

I will apply this together with the other two pieces.

Richard.

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

	PR lto/41071
	* gimple.c (compare_type_names_p): Do not look at the
	types main variant.
	* lto-streamer-out.c (output_type_ref): Remove hack for char_type_node.
	* lto-streamer.c (lto_streamer_cache_insert_1): Add debugging code.
	Remove hack for char_type_node.
	(lto_record_common_node): Canonicalize types of nodes we record.
	(lto_get_common_nodes): Record integer and size types first.
	Defer to lto_record_common_node for registering and canonicalizing
	types.

	lto/
	* lto.c (lto_fixup_constructor): New function.
	(lto_fixup_tree): Replace all types.  Properly fixup
	constructors and constants.

Index: gcc/gimple.c
===================================================================
*** gcc/gimple.c.orig	2009-08-17 12:59:36.000000000 +0200
--- gcc/gimple.c	2009-08-17 13:00:07.000000000 +0200
*************** lookup_type_pair (tree t1, tree t2, htab
*** 3185,3192 ****
  static bool
  compare_type_names_p (tree t1, tree t2)
  {
-   tree variant1 = TYPE_MAIN_VARIANT (t1);
-   tree variant2 = TYPE_MAIN_VARIANT (t2);
    tree name1 = TYPE_NAME (t1);
    tree name2 = TYPE_NAME (t2);
  
--- 3185,3190 ----
*************** compare_type_names_p (tree t1, tree t2)
*** 3215,3228 ****
    if (name1 == name2)
      return true;
  
-   /* If either type has a variant type, compare that.  This finds
-      the case where a struct is typedef'ed in one module but referred
-      to as 'struct foo' in the other; here, the main type for one is
-      'foo', and for the other 'foo_t', but the variants have the same
-      name 'foo'.  */
-   if (variant1 != t1 || variant2 != t2)
-     return compare_type_names_p (variant1, variant2);
- 
    return false;
  }
  
--- 3213,3218 ----
Index: gcc/lto-streamer-out.c
===================================================================
*** gcc/lto-streamer-out.c.orig	2009-08-17 12:59:36.000000000 +0200
--- gcc/lto-streamer-out.c	2009-08-17 16:20:07.000000000 +0200
*************** output_record_start (struct output_block
*** 367,378 ****
  static void
  output_type_ref (struct output_block *ob, tree node)
  {
-   /* FIXME lto.  This is a hack, the use of -funsigned-char should be
-      reflected in the IL by changing every reference to char_type_node
-      into unsigned_char_type_node in pass_ipa_free_lang_data.  */
-   if (flag_signed_char == 0 && node == char_type_node)
-     node = unsigned_char_type_node;
- 
    output_record_start (ob, LTO_type_ref);
    lto_output_type_ref_index (ob->decl_state, ob->main_stream, node);
  }
--- 367,372 ----
Index: gcc/lto-streamer.c
===================================================================
*** gcc/lto-streamer.c.orig	2009-08-17 13:00:06.000000000 +0200
--- gcc/lto-streamer.c	2009-08-17 16:20:06.000000000 +0200
*************** lto_streamer_cache_insert_1 (struct lto_
*** 500,511 ****
  
    gcc_assert (t);
  
-   /* If -funsigned-char is given, replace references to 'char' with
-      'unsigned char'.  FIXME lto, this should be done in
-      free_lang_data.  */
-   if (flag_signed_char == 0 && TYPE_P (t) && t == char_type_node)
-     t = unsigned_char_type_node;
- 
    d_entry.base.from = t;
    slot = htab_find_slot (cache->node_map, &d_entry, INSERT);
    if (*slot == NULL)
--- 500,505 ----
*************** lto_streamer_cache_insert_1 (struct lto_
*** 556,561 ****
--- 550,558 ----
  	     stream is not necessary as we will not need to read
  	     forward in the stream.  */
  	  lto_streamer_cache_add_to_node_array (cache, ix, t, -1);
+ 
+ 	  if (getenv ("STREAMER_DEBUG"))
+ 	    fprintf (stderr, "duplicate ");
  	}
  
        /* Indicate that T was already in the cache.  */
*************** lto_streamer_cache_insert_1 (struct lto_
*** 568,573 ****
--- 565,576 ----
    if (offset_p)
      *offset_p = offset; 
  
+   if (getenv ("STREAMER_DEBUG"))
+     {
+       fprintf (stderr, "inserting at %i[%u]%s ", ix, offset,
+ 	       existed_p ? " (present)" : "");
+       print_generic_stmt (stderr, t, 0);
+     }
  
    return existed_p;
  }
*************** lto_streamer_cache_get (struct lto_strea
*** 662,673 ****
     SEEN_NODES.  */
  
  static void
! lto_record_common_node (tree node, VEC(tree, heap) **common_nodes,
  			struct pointer_set_t *seen_nodes)
  {
    if (node == NULL_TREE)
      return;
  
    /* Return if node is already seen.  */
    if (pointer_set_insert (seen_nodes, node))
      return;
--- 665,681 ----
     SEEN_NODES.  */
  
  static void
! lto_record_common_node (tree *nodep, VEC(tree, heap) **common_nodes,
  			struct pointer_set_t *seen_nodes)
  {
+   tree node = *nodep;
+ 
    if (node == NULL_TREE)
      return;
  
+   if (TYPE_P (node))
+     *nodep = node = gimple_register_type (node);
+ 
    /* Return if node is already seen.  */
    if (pointer_set_insert (seen_nodes, node))
      return;
*************** lto_record_common_node (tree node, VEC(t
*** 676,693 ****
  
    if (tree_node_can_be_shared (node))
      {
!       if (TYPE_P (node))
! 	lto_record_common_node (TYPE_MAIN_VARIANT (node), common_nodes,
! 				seen_nodes);
! 
!       if (TREE_CODE (node) == ARRAY_TYPE)
! 	lto_record_common_node (TREE_TYPE (node), common_nodes, seen_nodes);
      }
  }
  
  
! /* Generate a vector of common nodes and register them in the gimple
!    type table as merge targets. */
  
  static VEC(tree,heap) *
  lto_get_common_nodes (void)
--- 684,699 ----
  
    if (tree_node_can_be_shared (node))
      {
!       if (POINTER_TYPE_P (node)
! 	  || TREE_CODE (node) == COMPLEX_TYPE
! 	  || TREE_CODE (node) == ARRAY_TYPE)
! 	lto_record_common_node (&TREE_TYPE (node), common_nodes, seen_nodes);
      }
  }
  
  
! /* Generate a vector of common nodes and make sure they are merged
!    properly according to the the gimple type table.  */
  
  static VEC(tree,heap) *
  lto_get_common_nodes (void)
*************** lto_get_common_nodes (void)
*** 720,753 ****
    
    seen_nodes = pointer_set_create ();
  
-   /* char_type_node is special, we have to prefer merging the other
-      char variants into it because the middle-end has pointer comparisons
-      with it.  */
-   gimple_register_type (char_type_node);
- 
-   for (i = 0; i < TI_MAX; i++)
-     {
-       tree t = global_trees[i];
-       if (t && TYPE_P (t))
- 	gimple_register_type (t);
-       lto_record_common_node (global_trees[i], &common_nodes, seen_nodes);
-     }
- 
    for (i = 0; i < itk_none; i++)
!     {
!       tree t = integer_types[i];
!       if (t && TYPE_P (t))
! 	gimple_register_type (t);
!       lto_record_common_node (integer_types[i], &common_nodes, seen_nodes);
!     }
  
    for (i = 0; i < TYPE_KIND_LAST; i++)
!     {
!       tree t = sizetype_tab[i];
!       if (t && TYPE_P (t))
! 	gimple_register_type (t);
!       lto_record_common_node (sizetype_tab[i], &common_nodes, seen_nodes);
!     }
  
    pointer_set_destroy (seen_nodes);
  
--- 726,739 ----
    
    seen_nodes = pointer_set_create ();
  
    for (i = 0; i < itk_none; i++)
!     lto_record_common_node (&integer_types[i], &common_nodes, seen_nodes);
  
    for (i = 0; i < TYPE_KIND_LAST; i++)
!     lto_record_common_node (&sizetype_tab[i], &common_nodes, seen_nodes);
! 
!   for (i = 0; i < TI_MAX; i++)
!     lto_record_common_node (&global_trees[i], &common_nodes, seen_nodes);
  
    pointer_set_destroy (seen_nodes);
  


Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c.orig	2009-08-17 12:59:36.000000000 +0200
--- gcc/lto/lto.c	2009-08-17 13:00:07.000000000 +0200
*************** lto_fixup_binfo (tree t, void *data)
*** 1259,1264 ****
--- 1300,1324 ----
      }
  }
  
+ /* Fix up fields of a CONSTRUCTOR T.  DATA points to fix-up states.  */
+ 
+ static void
+ lto_fixup_constructor (tree t, void *data)
+ {
+   unsigned HOST_WIDE_INT idx;
+   constructor_elt *ce;
+ 
+   LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TREE_TYPE (t));
+ 
+   for (idx = 0;
+        VEC_iterate(constructor_elt, CONSTRUCTOR_ELTS (t), idx, ce);
+        idx++)
+     {
+       LTO_FIXUP_SUBTREE (ce->index);
+       LTO_FIXUP_SUBTREE (ce->value);
+     }
+ }
+ 
  /* A walk_tree callback used by lto_fixup_state. TP is the pointer to the
     current tree. WALK_SUBTREES indicates if the subtrees will be walked.
     DATA is a pointer set to record visited nodes. */
*************** lto_fixup_tree (tree *tp, int *walk_subt
*** 1312,1317 ****
--- 1372,1384 ----
  	  t = prevailing;
  	}
      }
+   else if (TYPE_P (t))
+     {
+       /* Replace t with the prevailing type.  We don't want to insert the
+          other type in the seen set as we want to replace all instances of it.  */
+       t = gimple_register_type (t);
+       *tp = t;
+     }
  
    pointer_set_insert (fixup_data->seen, t);
  
*************** lto_fixup_tree (tree *tp, int *walk_subt
*** 1350,1355 ****
--- 1417,1426 ----
      default:
        if (TYPE_P (t))
  	lto_fixup_type (t, data);
+       else if (TREE_CODE (t) == CONSTRUCTOR)
+ 	lto_fixup_constructor (t, data);
+       else if (CONSTANT_CLASS_P (t))
+ 	LTO_REGISTER_TYPE_AND_FIXUP_SUBTREE (TREE_TYPE (t));
        else if (EXPR_P (t))
  	{
  	  /* walk_tree only handles TREE_OPERANDs. Do the rest here.  */


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