This speeds up LTO type merging by only calling gimple_register_type
on those types that possibly can require fixup (by means on how
the uniquification process is designed).  This makes the behavior
for pre-loaded type nodes consistent, as we do not throw them
at gimple_register_type directly but at the moment we do so
indirectly if they are refered to by any streamed in tree node.

A slightly more complex variant of the patch (un-setting TYPE_VISITED
after processing) has passed LTO bootstrap and regtest on
x86_64-unknown-linux-gnu as well as a SPEC 2k6 build.

Re-bootstrapping and testing together with some other patch now.

Richard.

2011-12-21  Richard Guenther  <rguent...@suse.de>

        lto/
        * lto.c (GIMPLE_REGISTER_TYPE): New define.
        (LTO_FIXUP_TREE): Use it.
        (uniquify_nodes): Mark new non-prevailing types and avoid
        calling gimple_register_type on others.
        (lto_read_decls): Add comment.

Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c       (revision 182525)
--- gcc/lto/lto.c       (working copy)
*************** remember_with_vars (tree t)
*** 306,318 ****
    *(tree *) htab_find_slot (tree_with_vars, t, INSERT) = t;
  }
  
  #define LTO_FIXUP_TREE(tt) \
    do \
      { \
        if (tt) \
        { \
          if (TYPE_P (tt)) \
!           (tt) = gimple_register_type (tt); \
          if (VAR_OR_FUNCTION_DECL_P (tt) && TREE_PUBLIC (tt)) \
            remember_with_vars (t); \
        } \
--- 306,321 ----
    *(tree *) htab_find_slot (tree_with_vars, t, INSERT) = t;
  }
  
+ #define GIMPLE_REGISTER_TYPE(tt) \
+    (TREE_VISITED (tt) ? gimple_register_type (tt) : tt)
+ 
  #define LTO_FIXUP_TREE(tt) \
    do \
      { \
        if (tt) \
        { \
          if (TYPE_P (tt)) \
!           (tt) = GIMPLE_REGISTER_TYPE (tt); \
          if (VAR_OR_FUNCTION_DECL_P (tt) && TREE_PUBLIC (tt)) \
            remember_with_vars (t); \
        } \
*************** uniquify_nodes (struct data_in *data_in,
*** 731,737 ****
      {
        tree t = VEC_index (tree, cache->nodes, i);
        if (t && TYPE_P (t))
!       gimple_register_type (t);
      }
  
    /* Second fixup all trees in the new cache entries.  */
--- 734,747 ----
      {
        tree t = VEC_index (tree, cache->nodes, i);
        if (t && TYPE_P (t))
!       {
!         tree newt = gimple_register_type (t);
!         /* Mark non-prevailing types so we fix them up.  No need
!            to reset that flag afterwards - nothing that refers
!            to those types is left and they are collected.  */
!         if (newt != t)
!           TREE_VISITED (t) = 1;
!       }
      }
  
    /* Second fixup all trees in the new cache entries.  */
*************** uniquify_nodes (struct data_in *data_in,
*** 749,755 ****
        continue;
  
        /* Now try to find a canonical variant of T itself.  */
!       t = gimple_register_type (t);
  
        if (t == oldt)
        {
--- 759,765 ----
        continue;
  
        /* Now try to find a canonical variant of T itself.  */
!       t = GIMPLE_REGISTER_TYPE (t);
  
        if (t == oldt)
        {
*************** uniquify_nodes (struct data_in *data_in,
*** 771,777 ****
            }
  
          /* 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.  */
--- 781,787 ----
            }
  
          /* 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.  */
*************** lto_read_decls (struct lto_file_decl_dat
*** 901,906 ****
--- 919,927 ----
    data_in = lto_data_in_create (decl_data, (const char *) data + 
string_offset,
                                header->string_size, resolutions);
  
+   /* We do not uniquify the pre-loaded cache entries, those are middle-end
+      internal types that should not be merged.  */
+ 
    /* Read the global declarations and types.  */
    while (ib_main.p < ib_main.len)
      {

Reply via email to