]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/tree-streamer-out.c
re PR fortran/90329 (Incompatibility between gfortran and C lapack calls)
[gcc.git] / gcc / tree-streamer-out.c
index 275c22cd7aa3c6e85fd0d059d86e57afba79c67f..c48a85b57f7b372f6668f31e5e9176e21d1d8362 100644 (file)
@@ -1,6 +1,6 @@
 /* Routines for emitting trees to a file stream.
 
-   Copyright (C) 2011-2013 Free Software Foundation, Inc.
+   Copyright (C) 2011-2018 Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@google.com>
 
 This file is part of GCC.
@@ -22,14 +22,16 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
-#include "diagnostic.h"
+#include "backend.h"
+#include "target.h"
 #include "tree.h"
-#include "stor-layout.h"
 #include "gimple.h"
 #include "tree-streamer.h"
-#include "data-streamer.h"
-#include "streamer-hooks.h"
+#include "cgraph.h"
+#include "alias.h"
+#include "stor-layout.h"
+#include "gomp-constants.h"
+
 
 /* Output the STRING constant to the string
    table in OB.  Then put the index onto the INDEX_STREAM.  */
@@ -65,7 +67,7 @@ write_identifier (struct output_block *ob,
 /* Pack all the non-pointer fields of the TS_BASE structure of
    expression EXPR into bitpack BP.  */
 
-static void
+static inline void
 pack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
 {
   bp_pack_value (bp, TREE_CODE (expr), 16);
@@ -85,7 +87,10 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
   bp_pack_value (bp, TREE_ADDRESSABLE (expr), 1);
   bp_pack_value (bp, TREE_THIS_VOLATILE (expr), 1);
   if (DECL_P (expr))
-    bp_pack_value (bp, DECL_UNSIGNED (expr), 1);
+    {
+      bp_pack_value (bp, DECL_UNSIGNED (expr), 1);
+      bp_pack_value (bp, DECL_NAMELESS (expr), 1);
+    }
   else if (TYPE_P (expr))
     bp_pack_value (bp, TYPE_UNSIGNED (expr), 1);
   else
@@ -102,17 +107,35 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
   bp_pack_value (bp, TREE_STATIC (expr), 1);
   if (TREE_CODE (expr) != TREE_BINFO)
     bp_pack_value (bp, TREE_PRIVATE (expr), 1);
+  else
+    bp_pack_value (bp, 0, 1);
   bp_pack_value (bp, TREE_PROTECTED (expr), 1);
   bp_pack_value (bp, TREE_DEPRECATED (expr), 1);
   if (TYPE_P (expr))
     {
-      bp_pack_value (bp, TYPE_SATURATING (expr), 1);
+      if (AGGREGATE_TYPE_P (expr))
+       bp_pack_value (bp, TYPE_REVERSE_STORAGE_ORDER (expr), 1);
+      else
+       bp_pack_value (bp, TYPE_SATURATING (expr), 1);
       bp_pack_value (bp, TYPE_ADDR_SPACE (expr), 8);
     }
+  else if (TREE_CODE (expr) == BIT_FIELD_REF || TREE_CODE (expr) == MEM_REF)
+    {
+      bp_pack_value (bp, REF_REVERSE_STORAGE_ORDER (expr), 1);
+      bp_pack_value (bp, 0, 8);
+    }
   else if (TREE_CODE (expr) == SSA_NAME)
-    bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1);
+    {
+      bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1);
+      bp_pack_value (bp, 0, 8);
+    }
+  else if (TREE_CODE (expr) == CALL_EXPR)
+    {
+      bp_pack_value (bp, CALL_EXPR_BY_DESCRIPTOR (expr), 1);
+      bp_pack_value (bp, 0, 8);
+    }
   else
-    bp_pack_value (bp, 0, 1);
+    bp_pack_value (bp, 0, 9);
 }
 
 
@@ -122,8 +145,11 @@ pack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
 static void
 pack_ts_int_cst_value_fields (struct bitpack_d *bp, tree expr)
 {
-  bp_pack_var_len_unsigned (bp, TREE_INT_CST_LOW (expr));
-  bp_pack_var_len_int (bp, TREE_INT_CST_HIGH (expr));
+  int i;
+  /* Note that the number of elements has already been written out in
+     streamer_write_tree_header.  */
+  for (i = 0; i < TREE_INT_CST_EXT_NUNITS (expr); i++)
+    bp_pack_var_len_int (bp, TREE_INT_CST_ELT (expr, i));
 }
 
 
@@ -155,7 +181,7 @@ static void
 pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr)
 {
   struct fixed_value fv = TREE_FIXED_CST (expr);
-  bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, fv.mode);
+  bp_pack_machine_mode (bp, fv.mode);
   bp_pack_var_len_int (bp, fv.data.low);
   bp_pack_var_len_int (bp, fv.data.high);
 }
@@ -166,11 +192,11 @@ pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr)
 static void
 pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
 {
-  bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, DECL_MODE (expr));
+  bp_pack_machine_mode (bp, DECL_MODE (expr));
   bp_pack_value (bp, DECL_NONLOCAL (expr), 1);
   bp_pack_value (bp, DECL_VIRTUAL_P (expr), 1);
   bp_pack_value (bp, DECL_IGNORED_P (expr), 1);
-  bp_pack_value (bp, DECL_ABSTRACT (expr), 1);
+  bp_pack_value (bp, DECL_ABSTRACT_P (expr), 1);
   bp_pack_value (bp, DECL_ARTIFICIAL (expr), 1);
   bp_pack_value (bp, DECL_USER_ALIGN (expr), 1);
   bp_pack_value (bp, DECL_PRESERVE_P (expr), 1);
@@ -186,26 +212,29 @@ pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
       bp_pack_var_len_unsigned (bp, EH_LANDING_PAD_NR (expr));
     }
 
-  if (TREE_CODE (expr) == FIELD_DECL)
+  else if (TREE_CODE (expr) == FIELD_DECL)
     {
       bp_pack_value (bp, DECL_PACKED (expr), 1);
       bp_pack_value (bp, DECL_NONADDRESSABLE_P (expr), 1);
+      bp_pack_value (bp, DECL_PADDING_P (expr), 1);
       bp_pack_value (bp, expr->decl_common.off_align, 8);
     }
 
-  if (TREE_CODE (expr) == VAR_DECL)
+  else if (VAR_P (expr))
     {
       bp_pack_value (bp, DECL_HAS_DEBUG_EXPR_P (expr), 1);
       bp_pack_value (bp, DECL_NONLOCAL_FRAME (expr), 1);
     }
 
+  else if (TREE_CODE (expr) == PARM_DECL)
+    bp_pack_value (bp, DECL_HIDDEN_STRING_LENGTH (expr), 1);
+
   if (TREE_CODE (expr) == RESULT_DECL
       || TREE_CODE (expr) == PARM_DECL
-      || TREE_CODE (expr) == VAR_DECL)
+      || VAR_P (expr))
     {
       bp_pack_value (bp, DECL_BY_REFERENCE (expr), 1);
-      if (TREE_CODE (expr) == VAR_DECL
-         || TREE_CODE (expr) == PARM_DECL)
+      if (VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
        bp_pack_value (bp, DECL_HAS_VALUE_EXPR_P (expr), 1);
     }
 }
@@ -235,12 +264,11 @@ pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
   bp_pack_value (bp, DECL_VISIBILITY (expr),  2);
   bp_pack_value (bp, DECL_VISIBILITY_SPECIFIED (expr),  1);
 
-  if (TREE_CODE (expr) == VAR_DECL)
+  if (VAR_P (expr))
     {
       bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1);
       /* DECL_IN_TEXT_SECTION is set during final asm output only. */
       bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1);
-      bp_pack_value (bp, DECL_TLS_MODEL (expr),  3);
     }
 
   if (TREE_CODE (expr) == FUNCTION_DECL)
@@ -249,8 +277,6 @@ pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
       bp_pack_value (bp, DECL_CXX_CONSTRUCTOR_P (expr), 1);
       bp_pack_value (bp, DECL_CXX_DESTRUCTOR_P (expr), 1);
     }
-  if (VAR_OR_FUNCTION_DECL_P (expr))
-    bp_pack_var_len_unsigned (bp, DECL_INIT_PRIORITY (expr));
 }
 
 
@@ -260,10 +286,6 @@ pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
 static void
 pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
 {
-  /* For normal/md builtins we only write the class and code, so they
-     should never be handled here.  */
-  gcc_assert (!streamer_handle_as_builtin_p (expr));
-
   bp_pack_enum (bp, built_in_class, BUILT_IN_LAST,
                DECL_BUILT_IN_CLASS (expr));
   bp_pack_value (bp, DECL_STATIC_CONSTRUCTOR (expr), 1);
@@ -283,9 +305,7 @@ pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
   bp_pack_value (bp, DECL_PURE_P (expr), 1);
   bp_pack_value (bp, DECL_LOOPING_CONST_OR_PURE_P (expr), 1);
   if (DECL_BUILT_IN_CLASS (expr) != NOT_BUILT_IN)
-    bp_pack_value (bp, DECL_FUNCTION_CODE (expr), 11);
-  if (DECL_STATIC_DESTRUCTOR (expr))
-    bp_pack_var_len_unsigned (bp, DECL_FINI_PRIORITY (expr));
+    bp_pack_value (bp, DECL_FUNCTION_CODE (expr), 12);
 }
 
 
@@ -295,10 +315,21 @@ pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
 static void
 pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
 {
-  bp_pack_enum (bp, machine_mode, MAX_MACHINE_MODE, TYPE_MODE (expr));
+  /* for VECTOR_TYPE, TYPE_MODE reevaluates the mode using target_flags
+     not necessary valid in a global context.
+     Use the raw value previously set by layout_type.  */
+  bp_pack_machine_mode (bp, TYPE_MODE_RAW (expr));
   bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1);
-  bp_pack_value (bp, TYPE_NO_FORCE_BLK (expr), 1);
+  /* TYPE_NO_FORCE_BLK is private to stor-layout and need
+     no streaming.  */
   bp_pack_value (bp, TYPE_NEEDS_CONSTRUCTING (expr), 1);
+  bp_pack_value (bp, TYPE_PACKED (expr), 1);
+  bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
+  bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
+  bp_pack_value (bp, TYPE_READONLY (expr), 1);
+  /* We used to stream TYPE_ALIAS_SET == 0 information to let frontends mark
+     types that are opaque for TBAA.  This however did not work as intended,
+     because TYPE_ALIAS_SET == 0 was regularly lost in type merging.  */
   if (RECORD_OR_UNION_TYPE_P (expr))
     {
       bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
@@ -306,17 +337,11 @@ pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
     }
   else if (TREE_CODE (expr) == ARRAY_TYPE)
     bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
-  bp_pack_value (bp, TYPE_PACKED (expr), 1);
-  bp_pack_value (bp, TYPE_RESTRICT (expr), 1);
-  bp_pack_value (bp, TYPE_USER_ALIGN (expr), 1);
-  bp_pack_value (bp, TYPE_READONLY (expr), 1);
+  if (AGGREGATE_TYPE_P (expr))
+    bp_pack_value (bp, TYPE_TYPELESS_STORAGE (expr), 1);
+  bp_pack_value (bp, TYPE_EMPTY_P (expr), 1);
   bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
   bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
-  /* Make sure to preserve the fact whether the frontend would assign
-     alias-set zero to this type.  */
-  bp_pack_var_len_int (bp, (TYPE_ALIAS_SET (expr) == 0
-                           || (!in_lto_p
-                               && get_alias_set (expr) == 0)) ? 0 : -1);
 }
 
 
@@ -348,139 +373,126 @@ pack_ts_translation_unit_decl_value_fields (struct output_block *ob,
   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.  */
+/* Pack all the non-pointer fields of the TS_OMP_CLAUSE structure
+   of expression EXPR into bitpack BP.  */
 
 static void
-pack_ts_optimization (struct bitpack_d *bp, tree expr)
+pack_ts_omp_clause_value_fields (struct output_block *ob,
+                                struct bitpack_d *bp, tree expr)
 {
-  struct cl_optimization *t = TREE_OPTIMIZATION (expr);
-  unsigned i, len;
-
-  /* The cl_optimization is generated by the options
-     awk script, so we just recreate a byte-by-byte copy here. */
-
-  len = sizeof (struct cl_optimization);
-  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);
+  stream_output_location (ob, bp, OMP_CLAUSE_LOCATION (expr));
+  switch (OMP_CLAUSE_CODE (expr))
+    {
+    case OMP_CLAUSE_DEFAULT:
+      bp_pack_enum (bp, omp_clause_default_kind, OMP_CLAUSE_DEFAULT_LAST,
+                   OMP_CLAUSE_DEFAULT_KIND (expr));
+      break;
+    case OMP_CLAUSE_SCHEDULE:
+      bp_pack_enum (bp, omp_clause_schedule_kind, OMP_CLAUSE_SCHEDULE_LAST,
+                   OMP_CLAUSE_SCHEDULE_KIND (expr));
+      break;
+    case OMP_CLAUSE_DEPEND:
+      bp_pack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST,
+                   OMP_CLAUSE_DEPEND_KIND (expr));
+      break;
+    case OMP_CLAUSE_MAP:
+      bp_pack_enum (bp, gomp_map_kind, GOMP_MAP_LAST,
+                   OMP_CLAUSE_MAP_KIND (expr));
+      break;
+    case OMP_CLAUSE_PROC_BIND:
+      bp_pack_enum (bp, omp_clause_proc_bind_kind, OMP_CLAUSE_PROC_BIND_LAST,
+                   OMP_CLAUSE_PROC_BIND_KIND (expr));
+      break;
+    case OMP_CLAUSE_REDUCTION:
+      bp_pack_enum (bp, tree_code, MAX_TREE_CODES,
+                   OMP_CLAUSE_REDUCTION_CODE (expr));
+      break;
+    default:
+      break;
+    }
 }
 
 
 /* Pack all the bitfields in EXPR into a bit pack.  */
 
 void
-streamer_pack_tree_bitfields (struct output_block *ob,
-                             struct bitpack_d *bp, tree expr)
+streamer_write_tree_bitfields (struct output_block *ob, tree expr)
 {
+  bitpack_d bp = bitpack_create (ob->main_stream);
   enum tree_code code;
 
   code = TREE_CODE (expr);
 
   /* Note that all these functions are highly sensitive to changes in
      the types and sizes of each of the fields being packed.  */
-  pack_ts_base_value_fields (bp, expr);
+  pack_ts_base_value_fields (&bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
-    pack_ts_int_cst_value_fields (bp, expr);
+    pack_ts_int_cst_value_fields (&bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
-    pack_ts_real_cst_value_fields (bp, expr);
+    pack_ts_real_cst_value_fields (&bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST))
-    pack_ts_fixed_cst_value_fields (bp, expr);
+    pack_ts_fixed_cst_value_fields (&bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
-    stream_output_location (ob, bp, DECL_SOURCE_LOCATION (expr));
+    stream_output_location (ob, &bp, DECL_SOURCE_LOCATION (expr));
 
   if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
-    pack_ts_decl_common_value_fields (bp, expr);
+    pack_ts_decl_common_value_fields (&bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
-    pack_ts_decl_wrtl_value_fields (bp, expr);
+    pack_ts_decl_wrtl_value_fields (&bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
-    pack_ts_decl_with_vis_value_fields (bp, expr);
+    pack_ts_decl_with_vis_value_fields (&bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
-    pack_ts_function_decl_value_fields (bp, expr);
+    pack_ts_function_decl_value_fields (&bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
-    pack_ts_type_common_value_fields (bp, expr);
+    pack_ts_type_common_value_fields (&bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_EXP))
-    stream_output_location (ob, bp, EXPR_LOCATION (expr));
+    {
+      stream_output_location (ob, &bp, EXPR_LOCATION (expr));
+      if (code == MEM_REF
+         || code == TARGET_MEM_REF)
+       {
+         bp_pack_value (&bp, MR_DEPENDENCE_CLIQUE (expr), sizeof (short) * 8);
+         if (MR_DEPENDENCE_CLIQUE (expr) != 0)
+           bp_pack_value (&bp, MR_DEPENDENCE_BASE (expr), sizeof (short) * 8);
+       }
+      else if (code == CALL_EXPR)
+       bp_pack_enum (&bp, internal_fn, IFN_LAST, CALL_EXPR_IFN (expr));
+    }
 
   if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
-    pack_ts_block_value_fields (ob, bp, expr);
+    pack_ts_block_value_fields (ob, &bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
-    pack_ts_translation_unit_decl_value_fields (ob, bp, expr);
-
-  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
-    pack_ts_target_option (bp, expr);
+    pack_ts_translation_unit_decl_value_fields (ob, &bp, expr);
 
   if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
-    pack_ts_optimization (bp, expr);
+    cl_optimization_stream_out (&bp, TREE_OPTIMIZATION (expr));
 
   if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
-    bp_pack_var_len_unsigned (bp, vec_safe_length (BINFO_BASE_ACCESSES (expr)));
+    bp_pack_var_len_unsigned (&bp, vec_safe_length (BINFO_BASE_ACCESSES (expr)));
 
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
-    bp_pack_var_len_unsigned (bp, CONSTRUCTOR_NELTS (expr));
-}
-
-
-/* Write the code and class of builtin EXPR to output block OB.  IX is
-   the index into the streamer cache where EXPR is stored.*/
-
-void
-streamer_write_builtin (struct output_block *ob, tree expr)
-{
-  gcc_assert (streamer_handle_as_builtin_p (expr));
+    bp_pack_var_len_unsigned (&bp, CONSTRUCTOR_NELTS (expr));
 
-  if (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD
-      && !targetm.builtin_decl)
-    sorry ("tree bytecode streams do not support machine specific builtin "
-          "functions on this target");
+  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)
+      /* Don't stream these when passing things to a different target.  */
+      && !lto_stream_offload_p)
+    cl_target_option_stream_out (ob, &bp, TREE_TARGET_OPTION (expr));
 
-  streamer_write_record_start (ob, LTO_builtin_decl);
-  streamer_write_enum (ob->main_stream, built_in_class, BUILT_IN_LAST,
-                      DECL_BUILT_IN_CLASS (expr));
-  streamer_write_uhwi (ob, DECL_FUNCTION_CODE (expr));
+  if (code == OMP_CLAUSE)
+    pack_ts_omp_clause_value_fields (ob, &bp, expr);
 
-  if (DECL_ASSEMBLER_NAME_SET_P (expr))
-    {
-      /* When the assembler name of a builtin gets a user name,
-        the new name is always prefixed with '*' by
-        set_builtin_user_assembler_name.  So, to prevent the
-        reader side from adding a second '*', we omit it here.  */
-      const char *str = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (expr));
-      if (strlen (str) > 1 && str[0] == '*')
-       streamer_write_string (ob, ob->main_stream, &str[1], true);
-      else
-       streamer_write_string (ob, ob->main_stream, NULL, true);
-    }
-  else
-    streamer_write_string (ob, ob->main_stream, NULL, true);
+  streamer_write_bitpack (&bp);
 }
 
 
@@ -493,25 +505,17 @@ streamer_write_chain (struct output_block *ob, tree t, bool ref_p)
 {
   while (t)
     {
-      tree saved_chain;
-
-      /* Clear TREE_CHAIN to avoid blindly recursing into the rest
-        of the list.  */
-      saved_chain = TREE_CHAIN (t);
-      TREE_CHAIN (t) = NULL_TREE;
-
       /* We avoid outputting external vars or functions by reference
         to the global decls section as we do not want to have them
         enter decl merging.  This is, of course, only for the call
-        for streaming BLOCK_VARS, but other callers are safe.  */
-      /* ???  FIXME wrt SCC streaming.  Drop these for now.  */
+        for streaming BLOCK_VARS, but other callers are safe.
+        See also lto-streamer-out.c:DFS_write_tree_body.  */
       if (VAR_OR_FUNCTION_DECL_P (t)
          && DECL_EXTERNAL (t))
-       ; /* stream_write_tree_shallow_non_ref (ob, t, ref_p); */
+       stream_write_tree_shallow_non_ref (ob, t, ref_p);
       else
        stream_write_tree (ob, t, ref_p);
 
-      TREE_CHAIN (t) = saved_chain;
       t = TREE_CHAIN (t);
     }
 
@@ -539,11 +543,23 @@ write_ts_common_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
 static void
 write_ts_vector_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
 {
-  unsigned i;
   /* Note that the number of elements for EXPR has already been emitted
      in EXPR's header (see streamer_write_tree_header).  */
-  for (i = 0; i < VECTOR_CST_NELTS (expr); ++i)
-    stream_write_tree (ob, VECTOR_CST_ELT (expr, i), ref_p);
+  unsigned int count = vector_cst_encoded_nelts (expr);
+  for (unsigned int i = 0; i < count; ++i)
+    stream_write_tree (ob, VECTOR_CST_ENCODED_ELT (expr, i), ref_p);
+}
+
+
+/* Write all pointer fields in the TS_POLY_INT_CST structure of EXPR to
+   output block OB.  If REF_P is true, write a reference to EXPR's pointer
+   fields.  */
+
+static void
+write_ts_poly_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
+{
+  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+    stream_write_tree (ob, POLY_INT_CST_COEFF (expr, i), ref_p);
 }
 
 
@@ -570,11 +586,15 @@ write_ts_decl_minimal_tree_pointers (struct output_block *ob, tree expr,
   /* Drop names that were created for anonymous entities.  */
   if (DECL_NAME (expr)
       && TREE_CODE (DECL_NAME (expr)) == IDENTIFIER_NODE
-      && ANON_AGGRNAME_P (DECL_NAME (expr)))
+      && anon_aggrname_p (DECL_NAME (expr)))
     stream_write_tree (ob, NULL_TREE, ref_p);
   else
     stream_write_tree (ob, DECL_NAME (expr), ref_p);
-  stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
+  if (TREE_CODE (expr) != TRANSLATION_UNIT_DECL
+      && ! DECL_CONTEXT (expr))
+    stream_write_tree (ob, (*all_translation_units)[0], ref_p);
+  else
+    stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
 }
 
 
@@ -594,16 +614,22 @@ write_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
 
   stream_write_tree (ob, DECL_ATTRIBUTES (expr), ref_p);
 
-  /* Do not stream DECL_ABSTRACT_ORIGIN.  We cannot handle debug information
-     for early inlining so drop it on the floor instead of ICEing in
-     dwarf2out.c.  */
-
-  if ((TREE_CODE (expr) == VAR_DECL
-       || TREE_CODE (expr) == PARM_DECL)
+  /* On non-early-LTO enabled targets we claim we compiled with -g0
+     but dwarf2out still did its set_decl_origin_self game fooling
+     itself late.  Und that here since we won't have access to the
+     early generated abstract DIEs.  */
+  tree ao = DECL_ABSTRACT_ORIGIN (expr);
+  if (debug_info_level == DINFO_LEVEL_NONE
+      && ao == expr)
+    ao = NULL_TREE;
+  stream_write_tree (ob, ao, ref_p);
+
+  if ((VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
       && DECL_HAS_VALUE_EXPR_P (expr))
     stream_write_tree (ob, DECL_VALUE_EXPR (expr), ref_p);
 
-  if (TREE_CODE (expr) == VAR_DECL)
+  if (VAR_P (expr)
+      && DECL_HAS_DEBUG_EXPR_P (expr))
     stream_write_tree (ob, DECL_DEBUG_EXPR (expr), ref_p);
 }
 
@@ -618,7 +644,6 @@ write_ts_decl_non_common_tree_pointers (struct output_block *ob, tree expr,
 {
   if (TREE_CODE (expr) == TYPE_DECL)
     stream_write_tree (ob, DECL_ORIGINAL_TYPE (expr), ref_p);
-  stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
 }
 
 
@@ -635,9 +660,6 @@ write_ts_decl_with_vis_tree_pointers (struct output_block *ob, tree expr,
     stream_write_tree (ob, DECL_ASSEMBLER_NAME (expr), ref_p);
   else
     stream_write_tree (ob, NULL_TREE, false);
-
-  stream_write_tree (ob, DECL_SECTION_NAME (expr), ref_p);
-  stream_write_tree (ob, DECL_COMDAT_GROUP (expr), ref_p);
 }
 
 
@@ -665,10 +687,12 @@ static void
 write_ts_function_decl_tree_pointers (struct output_block *ob, tree expr,
                                      bool ref_p)
 {
-  /* DECL_STRUCT_FUNCTION is handled by lto_output_function.  FIXME lto,
-     maybe it should be handled here?  */
+  stream_write_tree (ob, DECL_VINDEX (expr), ref_p);
+  /* DECL_STRUCT_FUNCTION is handled by lto_output_function.  */
   stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
-  stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
+  /* Don't stream these when passing things to a different target.  */
+  if (!lto_stream_offload_p)
+    stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_TARGET (expr), ref_p);
   stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
 }
 
@@ -715,10 +739,8 @@ write_ts_type_non_common_tree_pointers (struct output_block *ob, tree expr,
     stream_write_tree (ob, TYPE_ARG_TYPES (expr), ref_p);
 
   if (!POINTER_TYPE_P (expr))
-    stream_write_tree (ob, TYPE_MINVAL (expr), ref_p);
-  stream_write_tree (ob, TYPE_MAXVAL (expr), ref_p);
-  if (RECORD_OR_UNION_TYPE_P (expr))
-    stream_write_tree (ob, TYPE_BINFO (expr), ref_p);
+    stream_write_tree (ob, TYPE_MIN_VALUE_RAW (expr), ref_p);
+  stream_write_tree (ob, TYPE_MAX_VALUE_RAW (expr), ref_p);
 }
 
 
@@ -779,14 +801,17 @@ write_ts_block_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
 
   /* Stream BLOCK_ABSTRACT_ORIGIN for the limited cases we can handle - those
      that represent inlined function scopes.
-     For the rest them on the floor instead of ICEing in dwarf2out.c.  */
+     For the rest them on the floor instead of ICEing in dwarf2out.c, but
+     keep the notion of whether the block is an inlined block by refering
+     to itself for the sake of tree_nonartificial_location.  */
   if (inlined_function_outer_scope_p (expr))
     {
       tree ultimate_origin = block_ultimate_origin (expr);
       stream_write_tree (ob, ultimate_origin, ref_p);
     }
   else
-    stream_write_tree (ob, NULL_TREE, ref_p);
+    stream_write_tree (ob, (BLOCK_ABSTRACT_ORIGIN (expr)
+                           ? expr : NULL_TREE), ref_p);
   /* Do not stream BLOCK_NONLOCALIZED_VARS.  We cannot handle debug information
      for early inlined BLOCKs so drop it on the floor instead of ICEing in
      dwarf2out.c.  */
@@ -848,6 +873,29 @@ write_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
     }
 }
 
+
+/* Write all pointer fields in the TS_OMP_CLAUSE structure of EXPR
+   to output block OB.  If REF_P is true, write a reference to EXPR's
+   pointer fields.  */
+
+static void
+write_ts_omp_clause_tree_pointers (struct output_block *ob, tree expr,
+                                  bool ref_p)
+{
+  int i;
+  for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
+    stream_write_tree (ob, OMP_CLAUSE_OPERAND (expr, i), ref_p);
+  if (OMP_CLAUSE_CODE (expr) == OMP_CLAUSE_REDUCTION)
+    {
+      /* We don't stream these right now, handle it if streaming
+        of them is needed.  */
+      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_INIT (expr) == NULL);
+      gcc_assert (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE (expr) == NULL);
+    }
+  stream_write_tree (ob, OMP_CLAUSE_CHAIN (expr), ref_p);
+}
+
+
 /* Write all pointer fields in EXPR to output block OB.  If REF_P is true,
    the leaves of EXPR are emitted as references.  */
 
@@ -866,6 +914,9 @@ streamer_write_tree_body (struct output_block *ob, tree expr, bool ref_p)
   if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
     write_ts_vector_tree_pointers (ob, expr, ref_p);
 
+  if (CODE_CONTAINS_STRUCT (code, TS_POLY_INT_CST))
+    write_ts_poly_tree_pointers (ob, expr, ref_p);
+
   if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX))
     write_ts_complex_tree_pointers (ob, expr, ref_p);
 
@@ -910,6 +961,9 @@ streamer_write_tree_body (struct output_block *ob, tree expr, bool ref_p)
 
   if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
     write_ts_constructor_tree_pointers (ob, expr, ref_p);
+
+  if (code == OMP_CLAUSE)
+    write_ts_omp_clause_tree_pointers (ob, expr, ref_p);
 }
 
 
@@ -934,16 +988,6 @@ streamer_write_tree_header (struct output_block *ob, tree expr)
   tag = lto_tree_code_to_tag (code);
   streamer_write_record_start (ob, tag);
 
-  /* The following will cause bootstrap miscomparisons.  Enable with care.  */
-#ifdef LTO_STREAMER_DEBUG
-  /* This is used mainly for debugging purposes.  When the reader
-     and the writer do not agree on a streamed node, the pointer
-     value for EXPR can be used to track down the differences in
-     the debugger.  */
-  gcc_assert ((HOST_WIDEST_INT) (intptr_t) expr == (intptr_t) expr);
-  streamer_write_hwi (ob, (HOST_WIDEST_INT) (intptr_t) expr);
-#endif
-
   /* The text in strings and identifiers are completely emitted in
      the header.  */
   if (CODE_CONTAINS_STRUCT (code, TS_STRING))
@@ -951,13 +995,26 @@ streamer_write_tree_header (struct output_block *ob, tree expr)
   else if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER))
     write_identifier (ob, ob->main_stream, expr);
   else if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
-    streamer_write_hwi (ob, VECTOR_CST_NELTS (expr));
+    {
+      bitpack_d bp = bitpack_create (ob->main_stream);
+      bp_pack_value (&bp, VECTOR_CST_LOG2_NPATTERNS (expr), 8);
+      bp_pack_value (&bp, VECTOR_CST_NELTS_PER_PATTERN (expr), 8);
+      streamer_write_bitpack (&bp);
+    }
   else if (CODE_CONTAINS_STRUCT (code, TS_VEC))
     streamer_write_hwi (ob, TREE_VEC_LENGTH (expr));
   else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
     streamer_write_uhwi (ob, BINFO_N_BASE_BINFOS (expr));
   else if (TREE_CODE (expr) == CALL_EXPR)
     streamer_write_uhwi (ob, call_expr_nargs (expr));
+  else if (TREE_CODE (expr) == OMP_CLAUSE)
+    streamer_write_uhwi (ob, OMP_CLAUSE_CODE (expr));
+  else if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
+    {
+      gcc_checking_assert (TREE_INT_CST_NUNITS (expr));
+      streamer_write_uhwi (ob, TREE_INT_CST_NUNITS (expr));
+      streamer_write_uhwi (ob, TREE_INT_CST_EXT_NUNITS (expr));
+    }
 }
 
 
@@ -967,9 +1024,16 @@ streamer_write_tree_header (struct output_block *ob, tree expr)
 void
 streamer_write_integer_cst (struct output_block *ob, tree cst, bool ref_p)
 {
+  int i;
+  int len = TREE_INT_CST_NUNITS (cst);
   gcc_assert (!TREE_OVERFLOW (cst));
   streamer_write_record_start (ob, LTO_integer_cst);
   stream_write_tree (ob, TREE_TYPE (cst), ref_p);
-  streamer_write_uhwi (ob, TREE_INT_CST_LOW (cst));
-  streamer_write_hwi (ob, TREE_INT_CST_HIGH (cst));
+  /* We're effectively streaming a non-sign-extended wide_int here,
+     so there's no need to stream TREE_INT_CST_EXT_NUNITS or any
+     array members beyond LEN.  We'll recreate the tree from the
+     wide_int and the type.  */
+  streamer_write_uhwi (ob, len);
+  for (i = 0; i < len; i++)
+    streamer_write_hwi (ob, TREE_INT_CST_ELT (cst, i));
 }
This page took 0.048416 seconds and 5 git commands to generate.