LTO/WHOPR summary streaming fixes

Richard Guenther rguenther@suse.de
Thu Oct 22 12:52:00 GMT 2009


On Thu, 22 Oct 2009, Richard Guenther wrote:

> On Thu, 22 Oct 2009, Richard Guenther wrote:
> 
> > On Thu, 22 Oct 2009, Jan Hubicka wrote:
> > 
> > > Hi,
> > > this should be final version of patch.  Tested on x86_64-linux and also
> > > Richard kindly tested it works with Spec2006.
> > > The patch fixes ICE in ipa-cp seen on libquantum. OK?
> > 
> > Ok.  I'll think about the fixup problem.  I think we can easily delay
> > cgraph node merging until after fixup, then read in the summaries and
> > then apply the node merging.
> 
> Like this (untested).

Which doesn't (of course) work.  The following sort-of does, with
some extra WHOPR ICEs.

Richard.

2009-10-22  Richard Guenther  <rguenther@suse.de>

	* lto-streamer.h (lto_symtab_merge_cgraph_nodes): Declare.
	* lto-symtab.c (struct lto_symtab_entry_def): Add node member.
	(lto_symtab_merge): Do not merge cgraph nodes here.
	(lto_symtab_resolve_can_prevail_p): Simplify.
	(lto_symtab_resolve_symbols): Store cgraph node.
	(lto_symtab_merge_decls_1): Simplify.  Do not drop non-prevailing
	functions from the symtab.
	(lto_symtab_merge_cgraph_nodes_1): New function.
	(lto_symtab_merge_cgraph_nodes): Likewise.

	lto/
	* lto.c (lto_fixup_jump_functions): Remove.
	(lto_fixup_decls): Do not fixup jump functions.
	(read_cgraph_and_symbols): Schedule cgraph merging after
	summary reading.  Schedule type and decl fixup before
	summary reading.

Index: gcc/lto-symtab.c
===================================================================
*** gcc/lto-symtab.c.orig	2009-10-22 12:56:48.000000000 +0200
--- gcc/lto-symtab.c	2009-10-22 13:42:17.000000000 +0200
*************** struct GTY(()) lto_symtab_entry_def
*** 41,46 ****
--- 41,49 ----
    tree id;
    /* The symbol table entry, a DECL.  */
    tree decl;
+   /* The cgraph node if decl is a function decl.  Filled in during the
+      merging process.  */
+   struct cgraph_node *node;
    /* LTO file-data and symbol resolution for this decl.  */
    struct lto_file_decl_data * GTY((skip (""))) file_data;
    enum ld_plugin_symbol_resolution resolution;
*************** lto_symtab_merge (lto_symtab_entry_t pre
*** 232,249 ****
    tree prevailing_decl = prevailing->decl;
    tree decl = entry->decl;
    tree prevailing_type, type;
-   struct cgraph_node *node;
  
    /* Merge decl state in both directions, we may still end up using
       the new decl.  */
    TREE_ADDRESSABLE (prevailing_decl) |= TREE_ADDRESSABLE (decl);
    TREE_ADDRESSABLE (decl) |= TREE_ADDRESSABLE (prevailing_decl);
  
-   /* Replace a cgraph node of entry with the prevailing one.  */
-   if (TREE_CODE (decl) == FUNCTION_DECL
-       && (node = cgraph_get_node (decl)) != NULL)
-     lto_cgraph_replace_node (node, cgraph_get_node (prevailing_decl));
- 
    /* The linker may ask us to combine two incompatible symbols.
       Detect this case and notify the caller of required diagnostics.  */
  
--- 235,246 ----
*************** lto_symtab_resolve_replaceable_p (lto_sy
*** 355,369 ****
  static bool
  lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e)
  {
-   struct cgraph_node *node;
- 
    if (!TREE_STATIC (e->decl))
      return false;
  
    /* For functions we need a non-discarded body.  */
    if (TREE_CODE (e->decl) == FUNCTION_DECL)
!     return ((node = cgraph_get_node (e->decl))
! 	    && node->analyzed);
  
    /* A variable should have a size.  */
    else if (TREE_CODE (e->decl) == VAR_DECL)
--- 352,363 ----
  static bool
  lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e)
  {
    if (!TREE_STATIC (e->decl))
      return false;
  
    /* For functions we need a non-discarded body.  */
    if (TREE_CODE (e->decl) == FUNCTION_DECL)
!     return (e->node && e->node->analyzed);
  
    /* A variable should have a size.  */
    else if (TREE_CODE (e->decl) == VAR_DECL)
*************** lto_symtab_resolve_symbols (void **slot)
*** 393,398 ****
--- 387,395 ----
       diagnose ODR violations.  */
    for (; e; e = e->next)
      {
+       if (TREE_CODE (e->decl) == FUNCTION_DECL)
+ 	e->node = cgraph_get_node (e->decl);
+ 
        if (!lto_symtab_resolve_can_prevail_p (e))
  	{
  	  e->resolution = LDPR_RESOLVED_IR;
*************** lto_symtab_merge_decls_1 (void **slot, v
*** 531,537 ****
        prevailing = (lto_symtab_entry_t) *slot;
        /* For functions choose one with a cgraph node.  */
        if (TREE_CODE (prevailing->decl) == FUNCTION_DECL)
! 	while (!cgraph_get_node (prevailing->decl)
  	       && prevailing->next)
  	  prevailing = prevailing->next;
        /* We do not stream varpool nodes, so the first decl has to
--- 528,534 ----
        prevailing = (lto_symtab_entry_t) *slot;
        /* For functions choose one with a cgraph node.  */
        if (TREE_CODE (prevailing->decl) == FUNCTION_DECL)
! 	while (!prevailing->node
  	       && prevailing->next)
  	  prevailing = prevailing->next;
        /* We do not stream varpool nodes, so the first decl has to
*************** lto_symtab_merge_decls_1 (void **slot, v
*** 600,606 ****
    lto_symtab_merge_decls_2 (slot);
  
    /* Drop all but the prevailing decl from the symtab.  */
!   prevailing->next = NULL;
  
    return 1;
  }
--- 597,604 ----
    lto_symtab_merge_decls_2 (slot);
  
    /* Drop all but the prevailing decl from the symtab.  */
!   if (TREE_CODE (prevailing->decl) != FUNCTION_DECL)
!     prevailing->next = NULL;
  
    return 1;
  }
*************** lto_symtab_merge_decls (void)
*** 614,619 ****
--- 612,651 ----
    htab_traverse (lto_symtab_identifiers, lto_symtab_merge_decls_1, NULL);
  }
  
+ /* Helper to process the decl chain for the symbol table entry *SLOT.  */
+ 
+ static int
+ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+ {
+   lto_symtab_entry_t e, prevailing = (lto_symtab_entry_t) *slot;
+ 
+   if (!prevailing->next)
+     return 1;
+ 
+   gcc_assert (TREE_CODE (prevailing->decl) == FUNCTION_DECL);
+ 
+   /* Replace the cgraph node of each entry with the prevailing one.  */
+   for (e = prevailing->next; e; e = e->next)
+     {
+       if (e->node != NULL)
+ 	lto_cgraph_replace_node (e->node, prevailing->node);
+     }
+ 
+   /* Drop all but the prevailing decl from the symtab.  */
+   prevailing->next = NULL;
+ 
+   return 1;
+ }
+ 
+ /* Merge cgraph nodes according to the symbol merging done by
+    lto_symtab_merge_decls.  */
+ 
+ void
+ lto_symtab_merge_cgraph_nodes (void)
+ {
+   lto_symtab_maybe_init_hash_table ();
+   htab_traverse (lto_symtab_identifiers, lto_symtab_merge_cgraph_nodes_1, NULL);
+ }
  
  /* Given the decl DECL, return the prevailing decl with the same name. */
  
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c.orig	2009-10-22 12:57:41.000000000 +0200
--- gcc/lto/lto.c	2009-10-22 13:42:38.000000000 +0200
*************** lto_fixup_state_aux (void **slot, void *
*** 1635,1687 ****
    return 1;
  }
  
- /* Fixup pointers in jump functions.
-    TODO: We need some generic solution that will allow tree pointers in
-    function summaries.  */
- static void
- lto_fixup_jump_functions (lto_fixup_data_t * data)
- {
-   struct cgraph_node *node;
-   struct cgraph_edge *cs;
- 
-   for (node = cgraph_nodes; node; node = node->next)
-     {
-       if (!node->analyzed)
- 	continue;
-       for (cs = node->callees; cs; cs = cs->next_callee)
- 	{
- 	  int i;
- 	  struct ipa_edge_args *args = IPA_EDGE_REF (cs);
- 	  for (i = 0; i < ipa_get_cs_argument_count (args); i++)
- 	    {
- 	      struct ipa_jump_func *jf = ipa_get_ith_jump_func (args, i);
- 	      switch (jf->type)
- 		{
- 		case IPA_JF_UNKNOWN:
- 		  break;
- 		case IPA_JF_CONST:
- 		  walk_tree (&jf->value.constant, lto_fixup_tree, data, NULL);
- 		  break;
- 		case IPA_JF_PASS_THROUGH:
- 		  walk_tree (&jf->value.pass_through.operand, lto_fixup_tree,
- 			     data, NULL);
- 		  break;
- 		case IPA_JF_ANCESTOR:
- 		  walk_tree (&jf->value.ancestor.type, lto_fixup_tree, data,
- 			     NULL);
- 		  break;
- 		case IPA_JF_CONST_MEMBER_PTR:
- 		  walk_tree (&jf->value.member_cst.pfn, lto_fixup_tree, data,
- 			     NULL);
- 		  walk_tree (&jf->value.member_cst.delta, lto_fixup_tree,
- 			     data, NULL);
- 		  break;
- 		}
- 	    }
- 	}
-     }
- }
- 
  /* Fix the decls from all FILES. Replaces each decl with the corresponding
     prevailing one.  */
  
--- 1635,1640 ----
*************** lto_fixup_decls (struct lto_file_decl_da
*** 1710,1717 ****
        if (decl != saved_decl)
  	VEC_replace (tree, lto_global_var_decls, i, decl);
      }
-   if (ipa_edge_args_vector)
-     lto_fixup_jump_functions (&data);
  
    pointer_set_destroy (seen);
  }
--- 1663,1668 ----
*************** read_cgraph_and_symbols (unsigned nfiles
*** 1851,1861 ****
    /* Read the callgraph.  */
    input_cgraph ();
  
    /* Read the IPA summary data.  */
    ipa_read_summaries ();
  
!   /* Merge global decls.  */
!   lto_symtab_merge_decls ();
  
    /* Mark cgraph nodes needed in the merged cgraph
       This normally happens in whole-program pass, but for
--- 1802,1819 ----
    /* Read the callgraph.  */
    input_cgraph ();
  
+   /* Merge global decls.  */
+   lto_symtab_merge_decls ();
+ 
+   /* Fixup all decls and types and free the type hash tables.  */
+   lto_fixup_decls (all_file_decl_data);
+   free_gimple_type_tables ();
+ 
    /* Read the IPA summary data.  */
    ipa_read_summaries ();
  
!   /* Finally merge the cgraph according to the decl merging decisions.  */
!   lto_symtab_merge_cgraph_nodes ();
  
    /* Mark cgraph nodes needed in the merged cgraph
       This normally happens in whole-program pass, but for
*************** read_cgraph_and_symbols (unsigned nfiles
*** 1872,1883 ****
  
    timevar_push (TV_IPA_LTO_DECL_IO);
  
-   /* Fixup all decls and types.  */
-   lto_fixup_decls (all_file_decl_data);
- 
-   /* Free the type hash tables.  */
-   free_gimple_type_tables ();
- 
    /* FIXME lto. This loop needs to be changed to use the pass manager to
       call the ipa passes directly.  */
    if (!errorcount)
--- 1830,1835 ----
Index: gcc/lto-streamer.h
===================================================================
*** gcc/lto-streamer.h.orig	2009-10-22 12:56:48.000000000 +0200
--- gcc/lto-streamer.h	2009-10-22 13:41:57.000000000 +0200
*************** void input_cgraph (void);
*** 845,850 ****
--- 845,851 ----
  extern void lto_symtab_register_decl (tree, ld_plugin_symbol_resolution_t,
  				      struct lto_file_decl_data *);
  extern void lto_symtab_merge_decls (void);
+ extern void lto_symtab_merge_cgraph_nodes (void);
  extern tree lto_symtab_prevailing_decl (tree decl);
  extern enum ld_plugin_symbol_resolution lto_symtab_get_resolution (tree decl);
  



More information about the Gcc-patches mailing list