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] Avoid walking in circles


I knew that using TREE_CHAIN would come back later ...

So what happens is that we replace TREE_CHAIN of one decl with its
prevailing decl which happens to be itself.  And happily we walk
in circles when trying to figure out the largest decl we want to
use for the common.  Bah.  Let's use DECL_LANG_SPECIFIC instead.

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to lto.

Richard.

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

	* lto-symtab.c (lto_symtab_merge_decl): Exchange TREE_CHAIN use
	for DECL_LANG_SPECIFIC.
	(lto_symtab_prevailing_decl): Likewise.

	lto/
	* lto.c (read_cgraph_and_symbols): Exchange TREE_CHAIN use
	for DECL_LANG_SPECIFIC.

Index: gcc/lto-symtab.c
===================================================================
*** gcc/lto-symtab.c	(revision 150751)
--- gcc/lto-symtab.c	(working copy)
*************** lto_symtab_merge_decl (tree new_decl,
*** 561,567 ****
  
    gcc_assert (TREE_PUBLIC (new_decl));
  
!   gcc_assert (TREE_CHAIN (new_decl) == NULL_TREE);
  
    /* Check that declarations reaching this function do not have
       properties inconsistent with having external linkage.  If any of
--- 561,567 ----
  
    gcc_assert (TREE_PUBLIC (new_decl));
  
!   gcc_assert (DECL_LANG_SPECIFIC (new_decl) == NULL);
  
    /* Check that declarations reaching this function do not have
       properties inconsistent with having external linkage.  If any of
*************** lto_symtab_merge_decl (tree new_decl,
*** 611,623 ****
       for that symbol.  */
    while (old_decl
  	 && !lto_symtab_compatible (old_decl, new_decl))
!     old_decl = TREE_CHAIN (old_decl);
    if (!old_decl)
      {
        old_decl = lto_symtab_get_identifier_decl (name);
!       while (TREE_CHAIN (old_decl) != NULL_TREE)
! 	old_decl = TREE_CHAIN (old_decl);
!       TREE_CHAIN (old_decl) = new_decl;
        return;
      }
  
--- 611,623 ----
       for that symbol.  */
    while (old_decl
  	 && !lto_symtab_compatible (old_decl, new_decl))
!     old_decl = (tree) DECL_LANG_SPECIFIC (old_decl);
    if (!old_decl)
      {
        old_decl = lto_symtab_get_identifier_decl (name);
!       while (DECL_LANG_SPECIFIC (old_decl) != NULL)
! 	old_decl = (tree) DECL_LANG_SPECIFIC (old_decl);
!       DECL_LANG_SPECIFIC (old_decl) = (struct lang_decl *) new_decl;
        return;
      }
  
*************** lto_symtab_merge_decl (tree new_decl,
*** 638,654 ****
        gcc_assert (old_resolution == LDPR_PREEMPTED_IR
  		  || old_resolution ==  LDPR_RESOLVED_IR
  		  || (old_resolution == resolution && !flag_no_common));
!       TREE_CHAIN (new_decl) = TREE_CHAIN (old_decl);
!       TREE_CHAIN (old_decl) = NULL_TREE;
        decl = lto_symtab_get_identifier_decl (name);
        if (decl == old_decl)
  	{
  	  lto_symtab_set_identifier_decl (name, new_decl);
  	  return;
  	}
!       while (TREE_CHAIN (decl) != old_decl)
! 	decl = TREE_CHAIN (decl);
!       TREE_CHAIN (decl) = new_decl;
        return;
      }
  
--- 638,654 ----
        gcc_assert (old_resolution == LDPR_PREEMPTED_IR
  		  || old_resolution ==  LDPR_RESOLVED_IR
  		  || (old_resolution == resolution && !flag_no_common));
!       DECL_LANG_SPECIFIC (new_decl) = DECL_LANG_SPECIFIC (old_decl);
!       DECL_LANG_SPECIFIC (old_decl) = NULL;
        decl = lto_symtab_get_identifier_decl (name);
        if (decl == old_decl)
  	{
  	  lto_symtab_set_identifier_decl (name, new_decl);
  	  return;
  	}
!       while ((tree) DECL_LANG_SPECIFIC (decl) != old_decl)
! 	decl = (tree) DECL_LANG_SPECIFIC (decl);
!       DECL_LANG_SPECIFIC (decl) = (struct lang_decl *) new_decl;
        return;
      }
  
*************** lto_symtab_prevailing_decl (tree decl)
*** 711,717 ****
    /* Walk through the list of candidates and return the one we merged to.  */
    ret = lto_symtab_get_identifier_decl (DECL_ASSEMBLER_NAME (decl));
    if (!ret
!       || TREE_CHAIN (ret) == NULL_TREE)
      return ret;
  
    /* If there are multiple decls to choose from find the one we merged
--- 711,717 ----
    /* Walk through the list of candidates and return the one we merged to.  */
    ret = lto_symtab_get_identifier_decl (DECL_ASSEMBLER_NAME (decl));
    if (!ret
!       || DECL_LANG_SPECIFIC (ret) == NULL)
      return ret;
  
    /* If there are multiple decls to choose from find the one we merged
*************** lto_symtab_prevailing_decl (tree decl)
*** 721,727 ****
        if (gimple_types_compatible_p (TREE_TYPE (decl), TREE_TYPE (ret)))
  	return ret;
  
!       ret = TREE_CHAIN (ret);
      }
  
    gcc_unreachable ();
--- 721,727 ----
        if (gimple_types_compatible_p (TREE_TYPE (decl), TREE_TYPE (ret)))
  	return ret;
  
!       ret = (tree) DECL_LANG_SPECIFIC (ret);
      }
  
    gcc_unreachable ();
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c	(revision 150751)
--- gcc/lto/lto.c	(working copy)
*************** read_cgraph_and_symbols (unsigned nfiles
*** 1597,1635 ****
        tree size;
  
        if (TREE_CODE (decl) != VAR_DECL
! 	  || !TREE_CHAIN (decl))
  	continue;
  
        /* Find the preceeding decl of the largest one.  */
        size = DECL_SIZE (decl);
        do
  	{
! 	  if (tree_int_cst_lt (size, DECL_SIZE (TREE_CHAIN (decl))))
  	    {
! 	      size = DECL_SIZE (TREE_CHAIN (decl));
  	      prev_decl = decl;
  	    }
! 	  decl = TREE_CHAIN (decl);
  	}
!       while (TREE_CHAIN (decl));
  
        /* If necessary move the largest decl to the front of the
  	 chain.  */
        if (prev_decl != NULL_TREE)
  	{
! 	  decl = TREE_CHAIN (prev_decl);
! 	  TREE_CHAIN (prev_decl) = TREE_CHAIN (decl);
! 	  TREE_CHAIN (decl) = VEC_index (tree, lto_global_var_decls, i);
  	  VEC_replace (tree, lto_global_var_decls, i, decl);
  	}
  
        /* Mark everything apart from the first var as written out and
           unlink the chain.  */
        decl = VEC_index (tree, lto_global_var_decls, i);
!       while (TREE_CHAIN (decl))
  	{
! 	  tree next = TREE_CHAIN (decl);
! 	  TREE_CHAIN (decl) = NULL_TREE;
  	  decl = next;
  	  TREE_ASM_WRITTEN (decl) = true;
  	}
--- 1597,1637 ----
        tree size;
  
        if (TREE_CODE (decl) != VAR_DECL
! 	  || !DECL_LANG_SPECIFIC (decl))
  	continue;
  
        /* Find the preceeding decl of the largest one.  */
        size = DECL_SIZE (decl);
        do
  	{
! 	  tree next = (tree) DECL_LANG_SPECIFIC (decl);
! 	  if (tree_int_cst_lt (size, DECL_SIZE (next)))
  	    {
! 	      size = DECL_SIZE (next);
  	      prev_decl = decl;
  	    }
! 	  decl = next;
  	}
!       while (DECL_LANG_SPECIFIC (decl));
  
        /* If necessary move the largest decl to the front of the
  	 chain.  */
        if (prev_decl != NULL_TREE)
  	{
! 	  decl = (tree) DECL_LANG_SPECIFIC (prev_decl);
! 	  DECL_LANG_SPECIFIC (prev_decl) = DECL_LANG_SPECIFIC (decl);
! 	  DECL_LANG_SPECIFIC (decl)
! 	    = (struct lang_decl *) VEC_index (tree, lto_global_var_decls, i);
  	  VEC_replace (tree, lto_global_var_decls, i, decl);
  	}
  
        /* Mark everything apart from the first var as written out and
           unlink the chain.  */
        decl = VEC_index (tree, lto_global_var_decls, i);
!       while (DECL_LANG_SPECIFIC (decl))
  	{
! 	  tree next = (tree) DECL_LANG_SPECIFIC (decl);
! 	  DECL_LANG_SPECIFIC (decl) = NULL;
  	  decl = next;
  	  TREE_ASM_WRITTEN (decl) = true;
  	}


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