This removes streaming of cl_target_option (we can't stream
pointers in it).  The info was redundant given that we do stream
the target attribute itself.  So the following patch re-builds
DECL_FUNCTION_SPECIFIC_TARGET at tree loading time (we need it
during WPA inline analysis as well).

LTO bootstrapped and tested on x86_64-unknown-linux-gnu, ok?

(and yes, this fixes the libcpp/lex.o miscompare I was seeing
with LTO bootstrap)

The target hook implementations never use the 'name' or 'flags'
arguments so I wonder if we should change its signature.  That
makes the values I pass to those args less arbitrary ;)

Thanks,
Richard.

2014-02-14  Richard Biener  <rguent...@suse.de>

        PR lto/60179
        * lto-streamer-out.c (DFS_write_tree_body): Do not follow
        DECL_FUNCTION_SPECIFIC_TARGET.
        (hash_tree): Do not hash DECL_FUNCTION_SPECIFIC_TARGET.
        * tree-streamer-out.c (pack_ts_target_option): Remove.
        (streamer_pack_tree_bitfields): Do not stream
        TS_TARGET_OPTION.
        (write_ts_function_decl_tree_pointers): Do not stream
        DECL_FUNCTION_SPECIFIC_TARGET.
        * tree-streamer-in.c (unpack_ts_target_option): Remove.
        (unpack_value_fields): Do not stream TS_TARGET_OPTION.
        (lto_input_ts_function_decl_tree_pointers): Do not stream
        DECL_FUNCTION_SPECIFIC_TARGET.

        lto/
        * lto.c (compare_tree_sccs_1): Do not compare
        DECL_FUNCTION_SPECIFIC_TARGET.
        (lto_read_decls): Re-build DECL_FUNCTION_SPECIFIC_TARGET.

Index: gcc/lto-streamer-out.c
===================================================================
*** gcc/lto-streamer-out.c      (revision 207756)
--- gcc/lto-streamer-out.c      (working copy)
*************** DFS_write_tree_body (struct output_block
*** 550,556 ****
    if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
      {
        DFS_follow_tree_edge (DECL_FUNCTION_PERSONALITY (expr));
!       DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_TARGET (expr));
        DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr));
      }
  
--- 550,556 ----
    if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
      {
        DFS_follow_tree_edge (DECL_FUNCTION_PERSONALITY (expr));
!       /* Do not DECL_FUNCTION_SPECIFIC_TARGET.  They will be regenerated.  */
        DFS_follow_tree_edge (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr));
      }
  
*************** hash_tree (struct streamer_tree_cache_d
*** 885,891 ****
                        strlen (TRANSLATION_UNIT_LANGUAGE (t)), v);
  
    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
!     v = iterative_hash (t, sizeof (struct cl_target_option), v);
  
    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
      v = iterative_hash (t, sizeof (struct cl_optimization), v);
--- 885,891 ----
                        strlen (TRANSLATION_UNIT_LANGUAGE (t)), v);
  
    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
!     gcc_unreachable ();
  
    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
      v = iterative_hash (t, sizeof (struct cl_optimization), v);
*************** hash_tree (struct streamer_tree_cache_d
*** 986,992 ****
    if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
      {
        visit (DECL_FUNCTION_PERSONALITY (t));
!       visit (DECL_FUNCTION_SPECIFIC_TARGET (t));
        visit (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t));
      }
  
--- 986,992 ----
    if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
      {
        visit (DECL_FUNCTION_PERSONALITY (t));
!       /* Do not follow DECL_FUNCTION_SPECIFIC_TARGET.  */
        visit (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t));
      }
  
Index: gcc/tree-streamer-out.c
===================================================================
*** gcc/tree-streamer-out.c     (revision 207756)
--- gcc/tree-streamer-out.c     (working copy)
*************** pack_ts_translation_unit_decl_value_fiel
*** 353,376 ****
    bp_pack_string (ob, bp, TRANSLATION_UNIT_LANGUAGE (expr), true);
  }
  
- /* Pack a TS_TARGET_OPTION tree in EXPR to BP.  */
- 
- static void
- pack_ts_target_option (struct bitpack_d *bp, tree expr)
- {
-   struct cl_target_option *t = TREE_TARGET_OPTION (expr);
-   unsigned i, len;
- 
-   /* The cl_target_option is target specific and generated by the options
-      awk script, so we just recreate a byte-by-byte copy here. */
- 
-   len = sizeof (struct cl_target_option);
-   for (i = 0; i < len; i++)
-     bp_pack_value (bp, ((unsigned char *)t)[i], 8);
-   /* Catch struct size mismatches between reader and writer. */
-   bp_pack_value (bp, 0x12345678, 32);
- }
- 
  /* Pack a TS_OPTIMIZATION tree in EXPR to BP.  */
  
  static void
--- 353,358 ----
*************** streamer_pack_tree_bitfields (struct out
*** 481,487 ****
      pack_ts_translation_unit_decl_value_fields (ob, bp, expr);
  
    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
!     pack_ts_target_option (bp, expr);
  
    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
      pack_ts_optimization (bp, expr);
--- 463,469 ----
      pack_ts_translation_unit_decl_value_fields (ob, bp, expr);
  
    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
!     gcc_unreachable ();
  
    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
      pack_ts_optimization (bp, expr);
*************** write_ts_function_decl_tree_pointers (st
*** 716,722 ****
    /* DECL_STRUCT_FUNCTION is handled by lto_output_function.  FIXME lto,
       maybe it should be handled here?  */
    stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
!   stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
    stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
  }
  
--- 698,704 ----
    /* DECL_STRUCT_FUNCTION is handled by lto_output_function.  FIXME lto,
       maybe it should be handled here?  */
    stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
!   /* DECL_FUNCTION_SPECIFIC_TARGET is regenerated.  */
    stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
  }
  
Index: gcc/tree-streamer-in.c
===================================================================
*** gcc/tree-streamer-in.c      (revision 207756)
--- gcc/tree-streamer-in.c      (working copy)
*************** unpack_ts_translation_unit_decl_value_fi
*** 394,414 ****
    vec_safe_push (all_translation_units, expr);
  }
  
- /* Unpack a TS_TARGET_OPTION tree from BP into EXPR.  */
- 
- static void
- unpack_ts_target_option (struct bitpack_d *bp, tree expr)
- {
-   unsigned i, len;
-   struct cl_target_option *t = TREE_TARGET_OPTION (expr);
- 
-   len = sizeof (struct cl_target_option);
-   for (i = 0; i < len; i++)
-     ((unsigned char *)t)[i] = bp_unpack_value (bp, 8);
-   if (bp_unpack_value (bp, 32) != 0x12345678)
-     fatal_error ("cl_target_option size mismatch in LTO reader and writer");
- }
- 
  /* Unpack a TS_OPTIMIZATION tree from BP into EXPR.  */
  
  static void
--- 394,399 ----
*************** unpack_value_fields (struct data_in *dat
*** 517,523 ****
      unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr);
  
    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
!     unpack_ts_target_option (bp, expr);
  
    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
      unpack_ts_optimization (bp, expr);
--- 502,508 ----
      unpack_ts_translation_unit_decl_value_fields (data_in, bp, expr);
  
    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
!     gcc_unreachable ();
  
    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
      unpack_ts_optimization (bp, expr);
*************** lto_input_ts_function_decl_tree_pointers
*** 796,802 ****
    /* DECL_STRUCT_FUNCTION is handled by lto_input_function.  FIXME lto,
       maybe it should be handled here?  */
    DECL_FUNCTION_PERSONALITY (expr) = stream_read_tree (ib, data_in);
!   DECL_FUNCTION_SPECIFIC_TARGET (expr) = stream_read_tree (ib, data_in);
    DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = stream_read_tree (ib, data_in);
  
    /* If the file contains a function with an EH personality set,
--- 781,787 ----
    /* DECL_STRUCT_FUNCTION is handled by lto_input_function.  FIXME lto,
       maybe it should be handled here?  */
    DECL_FUNCTION_PERSONALITY (expr) = stream_read_tree (ib, data_in);
!   /* DECL_FUNCTION_SPECIFIC_TARGET is regenerated from attributes.  */
    DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = stream_read_tree (ib, data_in);
  
    /* If the file contains a function with an EH personality set,
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c       (revision 207756)
--- gcc/lto/lto.c       (working copy)
*************** compare_tree_sccs_1 (tree t1, tree t2, t
*** 1367,1375 ****
        return false;
  
    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
!     if (memcmp (TREE_TARGET_OPTION (t1), TREE_TARGET_OPTION (t2),
!               sizeof (struct cl_target_option)) != 0)
!       return false;
  
    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
      if (memcmp (TREE_OPTIMIZATION (t1), TREE_OPTIMIZATION (t2),
--- 1367,1373 ----
        return false;
  
    if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
!     gcc_unreachable ();
  
    if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
      if (memcmp (TREE_OPTIMIZATION (t1), TREE_OPTIMIZATION (t2),
*************** compare_tree_sccs_1 (tree t1, tree t2, t
*** 1547,1554 ****
      {
        compare_tree_edges (DECL_FUNCTION_PERSONALITY (t1),
                          DECL_FUNCTION_PERSONALITY (t2));
!       compare_tree_edges (DECL_FUNCTION_SPECIFIC_TARGET (t1),
!                         DECL_FUNCTION_SPECIFIC_TARGET (t2));
        compare_tree_edges (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t1),
                          DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t2));
      }
--- 1545,1552 ----
      {
        compare_tree_edges (DECL_FUNCTION_PERSONALITY (t1),
                          DECL_FUNCTION_PERSONALITY (t2));
!       /* DECL_FUNCTION_SPECIFIC_TARGET is not yet created.  We compare
!          the attribute list instead.  */
        compare_tree_edges (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t1),
                          DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t2));
      }
*************** lto_read_decls (struct lto_file_decl_dat
*** 1926,1931 ****
--- 1924,1938 ----
              if (TREE_CODE (t) == INTEGER_CST
                  && !TREE_OVERFLOW (t))
                cache_integer_cst (t);
+             /* Re-build DECL_FUNCTION_SPECIFIC_TARGET, we need that
+                for both WPA and LTRANS stage.  */
+             if (TREE_CODE (t) == FUNCTION_DECL)
+               {
+                 tree attr = lookup_attribute ("target", DECL_ATTRIBUTES (t));
+                 if (attr)
+                   targetm.target_option.valid_attribute_p
+                       (t, NULL_TREE, TREE_VALUE (attr), 0);
+               }
              /* Register TYPE_DECLs with the debuginfo machinery.  */
              if (!flag_wpa
                  && TREE_CODE (t) == TYPE_DECL)

Reply via email to