tree-streamer-out.c 33.6 KB
Newer Older
Diego Novillo committed
1 2
/* Routines for emitting trees to a file stream.

3
   Copyright (C) 2011-2019 Free Software Foundation, Inc.
Diego Novillo committed
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
   Contributed by Diego Novillo <dnovillo@google.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
25
#include "backend.h"
26
#include "target.h"
27 28
#include "tree.h"
#include "gimple.h"
29 30
#include "tree-streamer.h"
#include "cgraph.h"
31
#include "alias.h"
32
#include "stor-layout.h"
33 34
#include "gomp-constants.h"

Diego Novillo committed
35 36 37 38

/* Output the STRING constant to the string
   table in OB.  Then put the index onto the INDEX_STREAM.  */

39 40 41 42
void
streamer_write_string_cst (struct output_block *ob,
			   struct lto_output_stream *index_stream,
			   tree string)
Diego Novillo committed
43
{
44
  streamer_write_string_with_length (ob, index_stream,
45 46 47
				     string ? TREE_STRING_POINTER (string)
					    : NULL,
				     string ? TREE_STRING_LENGTH (string) : 0,
48
				     true);
Diego Novillo committed
49 50 51 52 53 54 55
}


/* Output the identifier ID to the string
   table in OB.  Then put the index onto the INDEX_STREAM.  */

static void
56
write_identifier (struct output_block *ob,
Diego Novillo committed
57 58 59
		   struct lto_output_stream *index_stream,
		   tree id)
{
60 61 62 63
  streamer_write_string_with_length (ob, index_stream,
				     IDENTIFIER_POINTER (id),
				     IDENTIFIER_LENGTH (id),
				     true);
Diego Novillo committed
64 65 66 67 68 69
}


/* Pack all the non-pointer fields of the TS_BASE structure of
   expression EXPR into bitpack BP.  */

70
static inline void
Diego Novillo committed
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
pack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
{
  bp_pack_value (bp, TREE_CODE (expr), 16);
  if (!TYPE_P (expr))
    {
      bp_pack_value (bp, TREE_SIDE_EFFECTS (expr), 1);
      bp_pack_value (bp, TREE_CONSTANT (expr), 1);
      bp_pack_value (bp, TREE_READONLY (expr), 1);

      /* TREE_PUBLIC is used on types to indicate that the type
	 has a TYPE_CACHED_VALUES vector.  This is not streamed out,
	 so we skip it here.  */
      bp_pack_value (bp, TREE_PUBLIC (expr), 1);
    }
  else
    bp_pack_value (bp, 0, 4);
  bp_pack_value (bp, TREE_ADDRESSABLE (expr), 1);
  bp_pack_value (bp, TREE_THIS_VOLATILE (expr), 1);
  if (DECL_P (expr))
90 91 92 93
    {
      bp_pack_value (bp, DECL_UNSIGNED (expr), 1);
      bp_pack_value (bp, DECL_NAMELESS (expr), 1);
    }
Diego Novillo committed
94 95 96 97
  else if (TYPE_P (expr))
    bp_pack_value (bp, TYPE_UNSIGNED (expr), 1);
  else
    bp_pack_value (bp, 0, 1);
98 99 100
  /* We write debug info two times, do not confuse the second one.
     The only relevant TREE_ASM_WRITTEN use is on SSA names.  */
  bp_pack_value (bp, (TREE_CODE (expr) != SSA_NAME
101
		      ? 0 : TREE_ASM_WRITTEN (expr)), 1);
Diego Novillo committed
102 103 104 105 106 107
  if (TYPE_P (expr))
    bp_pack_value (bp, TYPE_ARTIFICIAL (expr), 1);
  else
    bp_pack_value (bp, TREE_NO_WARNING (expr), 1);
  bp_pack_value (bp, TREE_NOTHROW (expr), 1);
  bp_pack_value (bp, TREE_STATIC (expr), 1);
108 109
  if (TREE_CODE (expr) != TREE_BINFO)
    bp_pack_value (bp, TREE_PRIVATE (expr), 1);
110 111
  else
    bp_pack_value (bp, 0, 1);
Diego Novillo committed
112 113 114
  bp_pack_value (bp, TREE_PROTECTED (expr), 1);
  bp_pack_value (bp, TREE_DEPRECATED (expr), 1);
  if (TYPE_P (expr))
115
    {
116 117 118 119
      if (AGGREGATE_TYPE_P (expr))
	bp_pack_value (bp, TYPE_REVERSE_STORAGE_ORDER (expr), 1);
      else
	bp_pack_value (bp, TYPE_SATURATING (expr), 1);
120 121
      bp_pack_value (bp, TYPE_ADDR_SPACE (expr), 8);
    }
122
  else if (TREE_CODE (expr) == BIT_FIELD_REF || TREE_CODE (expr) == MEM_REF)
123 124 125 126
    {
      bp_pack_value (bp, REF_REVERSE_STORAGE_ORDER (expr), 1);
      bp_pack_value (bp, 0, 8);
    }
Diego Novillo committed
127
  else if (TREE_CODE (expr) == SSA_NAME)
128 129 130 131
    {
      bp_pack_value (bp, SSA_NAME_IS_DEFAULT_DEF (expr), 1);
      bp_pack_value (bp, 0, 8);
    }
132 133 134 135 136
  else if (TREE_CODE (expr) == CALL_EXPR)
    {
      bp_pack_value (bp, CALL_EXPR_BY_DESCRIPTOR (expr), 1);
      bp_pack_value (bp, 0, 8);
    }
Diego Novillo committed
137
  else
138
    bp_pack_value (bp, 0, 9);
Diego Novillo committed
139 140 141
}


142 143 144 145 146 147
/* Pack all the non-pointer fields of the TS_INTEGER_CST structure of
   expression EXPR into bitpack BP.  */

static void
pack_ts_int_cst_value_fields (struct bitpack_d *bp, tree expr)
{
Kenneth Zadeck committed
148 149 150 151 152
  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));
153 154 155
}


Diego Novillo committed
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
/* Pack all the non-pointer fields of the TS_REAL_CST structure of
   expression EXPR into bitpack BP.  */

static void
pack_ts_real_cst_value_fields (struct bitpack_d *bp, tree expr)
{
  unsigned i;
  REAL_VALUE_TYPE r;

  r = TREE_REAL_CST (expr);
  bp_pack_value (bp, r.cl, 2);
  bp_pack_value (bp, r.decimal, 1);
  bp_pack_value (bp, r.sign, 1);
  bp_pack_value (bp, r.signalling, 1);
  bp_pack_value (bp, r.canonical, 1);
  bp_pack_value (bp, r.uexp, EXP_BITS);
  for (i = 0; i < SIGSZ; i++)
    bp_pack_value (bp, r.sig[i], HOST_BITS_PER_LONG);
}


/* Pack all the non-pointer fields of the TS_FIXED_CST structure of
   expression EXPR into bitpack BP.  */

static void
pack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr)
{
  struct fixed_value fv = TREE_FIXED_CST (expr);
184
  bp_pack_machine_mode (bp, fv.mode);
Diego Novillo committed
185 186 187 188 189 190 191 192 193 194
  bp_pack_var_len_int (bp, fv.data.low);
  bp_pack_var_len_int (bp, fv.data.high);
}

/* Pack all the non-pointer fields of the TS_DECL_COMMON structure
   of expression EXPR into bitpack BP.  */

static void
pack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
{
195
  bp_pack_machine_mode (bp, DECL_MODE (expr));
Diego Novillo committed
196 197 198
  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);
199
  bp_pack_value (bp, DECL_ABSTRACT_P (expr), 1);
Diego Novillo committed
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
  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);
  bp_pack_value (bp, DECL_EXTERNAL (expr), 1);
  bp_pack_value (bp, DECL_GIMPLE_REG_P (expr), 1);
  bp_pack_var_len_unsigned (bp, DECL_ALIGN (expr));

  if (TREE_CODE (expr) == LABEL_DECL)
    {
      /* Note that we do not write LABEL_DECL_UID.  The reader will
	 always assume an initial value of -1 so that the
	 label_to_block_map is recreated by gimple_set_bb.  */
      bp_pack_var_len_unsigned (bp, EH_LANDING_PAD_NR (expr));
    }

215
  else if (TREE_CODE (expr) == FIELD_DECL)
Diego Novillo committed
216 217 218
    {
      bp_pack_value (bp, DECL_PACKED (expr), 1);
      bp_pack_value (bp, DECL_NONADDRESSABLE_P (expr), 1);
219
      bp_pack_value (bp, DECL_PADDING_P (expr), 1);
Diego Novillo committed
220 221 222
      bp_pack_value (bp, expr->decl_common.off_align, 8);
    }

223
  else if (VAR_P (expr))
224 225 226 227
    {
      bp_pack_value (bp, DECL_HAS_DEBUG_EXPR_P (expr), 1);
      bp_pack_value (bp, DECL_NONLOCAL_FRAME (expr), 1);
    }
228

229 230 231
  else if (TREE_CODE (expr) == PARM_DECL)
    bp_pack_value (bp, DECL_HIDDEN_STRING_LENGTH (expr), 1);

Diego Novillo committed
232 233
  if (TREE_CODE (expr) == RESULT_DECL
      || TREE_CODE (expr) == PARM_DECL
234
      || VAR_P (expr))
Diego Novillo committed
235 236
    {
      bp_pack_value (bp, DECL_BY_REFERENCE (expr), 1);
237
      if (VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
Diego Novillo committed
238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
	bp_pack_value (bp, DECL_HAS_VALUE_EXPR_P (expr), 1);
    }
}


/* Pack all the non-pointer fields of the TS_DECL_WRTL structure
   of expression EXPR into bitpack BP.  */

static void
pack_ts_decl_wrtl_value_fields (struct bitpack_d *bp, tree expr)
{
  bp_pack_value (bp, DECL_REGISTER (expr), 1);
}


/* Pack all the non-pointer fields of the TS_DECL_WITH_VIS structure
   of expression EXPR into bitpack BP.  */

static void
pack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
{
  bp_pack_value (bp, DECL_COMMON (expr), 1);
  bp_pack_value (bp, DECL_DLLIMPORT_P (expr), 1);
  bp_pack_value (bp, DECL_WEAK (expr), 1);
  bp_pack_value (bp, DECL_SEEN_IN_BIND_EXPR_P (expr),  1);
  bp_pack_value (bp, DECL_COMDAT (expr),  1);
  bp_pack_value (bp, DECL_VISIBILITY (expr),  2);
  bp_pack_value (bp, DECL_VISIBILITY_SPECIFIED (expr),  1);

267
  if (VAR_P (expr))
Diego Novillo committed
268 269
    {
      bp_pack_value (bp, DECL_HARD_REGISTER (expr), 1);
270
      /* DECL_IN_TEXT_SECTION is set during final asm output only. */
Diego Novillo committed
271 272 273
      bp_pack_value (bp, DECL_IN_CONSTANT_POOL (expr), 1);
    }

274 275 276 277 278 279
  if (TREE_CODE (expr) == FUNCTION_DECL)
    {
      bp_pack_value (bp, DECL_FINAL_P (expr), 1);
      bp_pack_value (bp, DECL_CXX_CONSTRUCTOR_P (expr), 1);
      bp_pack_value (bp, DECL_CXX_DESTRUCTOR_P (expr), 1);
    }
Diego Novillo committed
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
}


/* Pack all the non-pointer fields of the TS_FUNCTION_DECL structure
   of expression EXPR into bitpack BP.  */

static void
pack_ts_function_decl_value_fields (struct bitpack_d *bp, tree 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);
  bp_pack_value (bp, DECL_STATIC_DESTRUCTOR (expr), 1);
  bp_pack_value (bp, DECL_UNINLINABLE (expr), 1);
  bp_pack_value (bp, DECL_POSSIBLY_INLINED (expr), 1);
  bp_pack_value (bp, DECL_IS_NOVOPS (expr), 1);
  bp_pack_value (bp, DECL_IS_RETURNS_TWICE (expr), 1);
  bp_pack_value (bp, DECL_IS_MALLOC (expr), 1);
298
  bp_pack_value (bp, DECL_IS_OPERATOR_NEW_P (expr), 1);
299
  bp_pack_value (bp, DECL_IS_OPERATOR_DELETE_P (expr), 1);
Diego Novillo committed
300 301 302 303 304 305 306 307 308
  bp_pack_value (bp, DECL_DECLARED_INLINE_P (expr), 1);
  bp_pack_value (bp, DECL_STATIC_CHAIN (expr), 1);
  bp_pack_value (bp, DECL_NO_INLINE_WARNING_P (expr), 1);
  bp_pack_value (bp, DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (expr), 1);
  bp_pack_value (bp, DECL_NO_LIMIT_STACK (expr), 1);
  bp_pack_value (bp, DECL_DISREGARD_INLINE_LIMITS (expr), 1);
  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)
309
    bp_pack_value (bp, DECL_UNCHECKED_FUNCTION_CODE (expr), 32);
Diego Novillo committed
310 311 312 313 314 315 316 317 318
}


/* Pack all the non-pointer fields of the TS_TYPE_COMMON structure
   of expression EXPR into bitpack BP.  */

static void
pack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
{
319 320 321 322
  /* 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));
323 324
  /* TYPE_NO_FORCE_BLK is private to stor-layout and need
     no streaming.  */
325 326 327 328
  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);
329 330 331 332 333 334
  unsigned vla_p;
  if (in_lto_p)
    vla_p = TYPE_LANG_FLAG_0 (TYPE_MAIN_VARIANT (expr));
  else
    vla_p = variably_modified_type_p (expr, NULL_TREE);
  bp_pack_value (bp, vla_p, 1);
335 336
  /* 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,
337
     because TYPE_ALIAS_SET == 0 was regularly lost in type merging.  */
Diego Novillo committed
338
  if (RECORD_OR_UNION_TYPE_P (expr))
339 340 341
    {
      bp_pack_value (bp, TYPE_TRANSPARENT_AGGR (expr), 1);
      bp_pack_value (bp, TYPE_FINAL_P (expr), 1);
342
      bp_pack_value (bp, TYPE_CXX_ODR_P (expr), 1);
343
    }
344 345
  else if (TREE_CODE (expr) == ARRAY_TYPE)
    bp_pack_value (bp, TYPE_NONALIASED_COMPONENT (expr), 1);
346 347
  if (TREE_CODE (expr) == ARRAY_TYPE || TREE_CODE (expr) == INTEGER_TYPE)
    bp_pack_value (bp, TYPE_STRING_FLAG (expr), 1);
348 349
  if (AGGREGATE_TYPE_P (expr))
    bp_pack_value (bp, TYPE_TYPELESS_STORAGE (expr), 1);
350
  bp_pack_value (bp, TYPE_EMPTY_P (expr), 1);
Diego Novillo committed
351 352 353 354 355 356 357 358 359
  bp_pack_var_len_unsigned (bp, TYPE_PRECISION (expr));
  bp_pack_var_len_unsigned (bp, TYPE_ALIGN (expr));
}


/* Pack all the non-pointer fields of the TS_BLOCK structure
   of expression EXPR into bitpack BP.  */

static void
360 361
pack_ts_block_value_fields (struct output_block *ob,
			    struct bitpack_d *bp, tree expr)
Diego Novillo committed
362 363
{
  /* BLOCK_NUMBER is recomputed.  */
364 365 366 367 368 369 370
  /* Stream BLOCK_SOURCE_LOCATION 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.  */
  if (inlined_function_outer_scope_p (expr))
    stream_output_location (ob, bp, BLOCK_SOURCE_LOCATION (expr));
  else
    stream_output_location (ob, bp, UNKNOWN_LOCATION);
Diego Novillo committed
371 372 373 374 375 376
}

/* Pack all the non-pointer fields of the TS_TRANSLATION_UNIT_DECL structure
   of expression EXPR into bitpack BP.  */

static void
377 378
pack_ts_translation_unit_decl_value_fields (struct output_block *ob,
					    struct bitpack_d *bp, tree expr)
Diego Novillo committed
379
{
380
  bp_pack_string (ob, bp, TRANSLATION_UNIT_LANGUAGE (expr), true);
Diego Novillo committed
381 382
}

383

384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406
/* Pack all the non-pointer fields of the TS_OMP_CLAUSE structure
   of expression EXPR into bitpack BP.  */

static void
pack_ts_omp_clause_value_fields (struct output_block *ob,
				 struct bitpack_d *bp, tree expr)
{
  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:
407
      bp_pack_enum (bp, gomp_map_kind, GOMP_MAP_LAST,
408 409 410 411 412 413 414
		    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:
415 416
    case OMP_CLAUSE_TASK_REDUCTION:
    case OMP_CLAUSE_IN_REDUCTION:
417 418 419 420 421 422 423 424 425
      bp_pack_enum (bp, tree_code, MAX_TREE_CODES,
		    OMP_CLAUSE_REDUCTION_CODE (expr));
      break;
    default:
      break;
    }
}


426
/* Pack all the bitfields in EXPR into a bit pack.  */
Diego Novillo committed
427

428
void
429
streamer_write_tree_bitfields (struct output_block *ob, tree expr)
Diego Novillo committed
430
{
431
  bitpack_d bp = bitpack_create (ob->main_stream);
Diego Novillo committed
432 433 434 435 436 437
  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.  */
438
  pack_ts_base_value_fields (&bp, expr);
Diego Novillo committed
439

440
  if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
441
    pack_ts_int_cst_value_fields (&bp, expr);
442

Diego Novillo committed
443
  if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
444
    pack_ts_real_cst_value_fields (&bp, expr);
Diego Novillo committed
445 446

  if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST))
447
    pack_ts_fixed_cst_value_fields (&bp, expr);
Diego Novillo committed
448

449
  if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
450
    stream_output_location (ob, &bp, DECL_SOURCE_LOCATION (expr));
451

Diego Novillo committed
452
  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
453
    pack_ts_decl_common_value_fields (&bp, expr);
Diego Novillo committed
454 455

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
456
    pack_ts_decl_wrtl_value_fields (&bp, expr);
Diego Novillo committed
457 458

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
459
    pack_ts_decl_with_vis_value_fields (&bp, expr);
Diego Novillo committed
460 461

  if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
462
    pack_ts_function_decl_value_fields (&bp, expr);
Diego Novillo committed
463 464

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
465
    pack_ts_type_common_value_fields (&bp, expr);
Diego Novillo committed
466

467
  if (CODE_CONTAINS_STRUCT (code, TS_EXP))
468
    {
469
      stream_output_location (ob, &bp, EXPR_LOCATION (expr));
470 471 472
      if (code == MEM_REF
	  || code == TARGET_MEM_REF)
	{
473
	  bp_pack_value (&bp, MR_DEPENDENCE_CLIQUE (expr), sizeof (short) * 8);
474
	  if (MR_DEPENDENCE_CLIQUE (expr) != 0)
475
	    bp_pack_value (&bp, MR_DEPENDENCE_BASE (expr), sizeof (short) * 8);
476
	}
477 478
      else if (code == CALL_EXPR)
	bp_pack_enum (&bp, internal_fn, IFN_LAST, CALL_EXPR_IFN (expr));
479
    }
480

Diego Novillo committed
481
  if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
482
    pack_ts_block_value_fields (ob, &bp, expr);
Diego Novillo committed
483 484

  if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
485
    pack_ts_translation_unit_decl_value_fields (ob, &bp, expr);
486 487

  if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
Martin Liska committed
488
    cl_optimization_stream_out (ob, &bp, TREE_OPTIMIZATION (expr));
489 490

  if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
491
    bp_pack_var_len_unsigned (&bp, CONSTRUCTOR_NELTS (expr));
492

493 494 495
  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION)
      /* Don't stream these when passing things to a different target.  */
      && !lto_stream_offload_p)
496
    cl_target_option_stream_out (ob, &bp, TREE_TARGET_OPTION (expr));
497

498
  if (code == OMP_CLAUSE)
499 500 501
    pack_ts_omp_clause_value_fields (ob, &bp, expr);

  streamer_write_bitpack (&bp);
Diego Novillo committed
502 503 504 505 506 507 508
}


/* Emit the chain of tree nodes starting at T.  OB is the output block
   to write to.  REF_P is true if chain elements should be emitted
   as references.  */

509
void
510
streamer_write_chain (struct output_block *ob, tree t, bool ref_p)
Diego Novillo committed
511
{
512
  while (t)
Diego Novillo committed
513
    {
514 515
      /* We avoid outputting external vars or functions by reference
	 to the global decls section as we do not want to have them
516 517 518 519
	 enter decl merging.  We should not need to do this anymore because
	 free_lang_data removes them from block scopes.  */
      gcc_assert (!VAR_OR_FUNCTION_DECL_P (t) || !DECL_EXTERNAL (t));
      stream_write_tree (ob, t, ref_p);
Diego Novillo committed
520 521 522

      t = TREE_CHAIN (t);
    }
523 524 525

  /* Write a sentinel to terminate the chain.  */
  stream_write_tree (ob, NULL_TREE, ref_p);
Diego Novillo committed
526 527 528 529 530 531 532 533
}


/* Write all pointer fields in the TS_COMMON structure of EXPR to output
   block OB.  If REF_P is true, write a reference to EXPR's pointer
   fields.  */

static void
534
write_ts_common_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
Diego Novillo committed
535 536
{
  if (TREE_CODE (expr) != IDENTIFIER_NODE)
537
    stream_write_tree (ob, TREE_TYPE (expr), ref_p);
Diego Novillo committed
538 539 540 541 542 543 544 545
}


/* Write all pointer fields in the TS_VECTOR structure of EXPR to output
   block OB.  If REF_P is true, write a reference to EXPR's pointer
   fields.  */

static void
546
write_ts_vector_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
Diego Novillo committed
547
{
548 549
  /* Note that the number of elements for EXPR has already been emitted
     in EXPR's header (see streamer_write_tree_header).  */
550 551 552
  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);
Diego Novillo committed
553 554 555
}


556 557 558 559 560 561 562 563 564 565 566 567
/* 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);
}


Diego Novillo committed
568 569 570 571 572
/* Write all pointer fields in the TS_COMPLEX structure of EXPR to output
   block OB.  If REF_P is true, write a reference to EXPR's pointer
   fields.  */

static void
573
write_ts_complex_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
Diego Novillo committed
574
{
575 576
  stream_write_tree (ob, TREE_REALPART (expr), ref_p);
  stream_write_tree (ob, TREE_IMAGPART (expr), ref_p);
Diego Novillo committed
577 578 579 580 581 582 583 584
}


/* Write all pointer fields in the TS_DECL_MINIMAL structure of EXPR
   to output block OB.  If REF_P is true, write a reference to EXPR's
   pointer fields.  */

static void
585 586
write_ts_decl_minimal_tree_pointers (struct output_block *ob, tree expr,
				     bool ref_p)
Diego Novillo committed
587
{
588 589 590
  /* Drop names that were created for anonymous entities.  */
  if (DECL_NAME (expr)
      && TREE_CODE (DECL_NAME (expr)) == IDENTIFIER_NODE
591
      && IDENTIFIER_ANON_P (DECL_NAME (expr)))
592 593 594
    stream_write_tree (ob, NULL_TREE, ref_p);
  else
    stream_write_tree (ob, DECL_NAME (expr), ref_p);
595 596 597 598 599
  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);
Diego Novillo committed
600 601 602 603 604 605 606 607
}


/* Write all pointer fields in the TS_DECL_COMMON structure of EXPR to
   output block OB.  If REF_P is true, write a reference to EXPR's
   pointer fields.  */

static void
608 609
write_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
				    bool ref_p)
Diego Novillo committed
610
{
611 612
  stream_write_tree (ob, DECL_SIZE (expr), ref_p);
  stream_write_tree (ob, DECL_SIZE_UNIT (expr), ref_p);
Diego Novillo committed
613 614 615 616

  /* Note, DECL_INITIAL is not handled here.  Since DECL_INITIAL needs
     special handling in LTO, it must be handled by streamer hooks.  */

617
  stream_write_tree (ob, DECL_ATTRIBUTES (expr), ref_p);
618 619 620 621 622 623 624 625 626 627

  /* 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);
Diego Novillo committed
628

629
  if ((VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
Diego Novillo committed
630
      && DECL_HAS_VALUE_EXPR_P (expr))
631
    stream_write_tree (ob, DECL_VALUE_EXPR (expr), ref_p);
Diego Novillo committed
632

633 634
  if (VAR_P (expr)
      && DECL_HAS_DEBUG_EXPR_P (expr))
635
    stream_write_tree (ob, DECL_DEBUG_EXPR (expr), ref_p);
Diego Novillo committed
636 637 638 639 640 641 642 643
}


/* Write all pointer fields in the TS_DECL_NON_COMMON structure of
   EXPR to output block OB.  If REF_P is true, write a reference to EXPR's
   pointer fields.  */

static void
644
write_ts_decl_non_common_tree_pointers (struct output_block *, tree, bool)
Diego Novillo committed
645 646 647 648 649 650 651 652 653
{
}


/* Write all pointer fields in the TS_DECL_WITH_VIS structure of EXPR
   to output block OB.  If REF_P is true, write a reference to EXPR's
   pointer fields.  */

static void
654 655
write_ts_decl_with_vis_tree_pointers (struct output_block *ob, tree expr,
			              bool ref_p)
Diego Novillo committed
656 657 658
{
  /* Make sure we don't inadvertently set the assembler name.  */
  if (DECL_ASSEMBLER_NAME_SET_P (expr))
659
    stream_write_tree (ob, DECL_ASSEMBLER_NAME (expr), ref_p);
Diego Novillo committed
660
  else
661
    stream_write_tree (ob, NULL_TREE, false);
Diego Novillo committed
662 663 664 665 666 667 668 669
}


/* Write all pointer fields in the TS_FIELD_DECL structure of EXPR to
   output block OB.  If REF_P is true, write a reference to EXPR's
   pointer fields.  */

static void
670 671
write_ts_field_decl_tree_pointers (struct output_block *ob, tree expr,
				   bool ref_p)
Diego Novillo committed
672
{
673 674
  stream_write_tree (ob, DECL_FIELD_OFFSET (expr), ref_p);
  stream_write_tree (ob, DECL_BIT_FIELD_TYPE (expr), ref_p);
675
  stream_write_tree (ob, DECL_BIT_FIELD_REPRESENTATIVE (expr), ref_p);
676
  stream_write_tree (ob, DECL_FIELD_BIT_OFFSET (expr), ref_p);
Diego Novillo committed
677 678 679 680 681 682 683 684
}


/* Write all pointer fields in the TS_FUNCTION_DECL structure of EXPR
   to output block OB.  If REF_P is true, write a reference to EXPR's
   pointer fields.  */

static void
685 686
write_ts_function_decl_tree_pointers (struct output_block *ob, tree expr,
				      bool ref_p)
Diego Novillo committed
687
{
688
  /* DECL_STRUCT_FUNCTION is handled by lto_output_function.  */
689
  stream_write_tree (ob, DECL_FUNCTION_PERSONALITY (expr), ref_p);
690 691 692
  /* 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);
693
  stream_write_tree (ob, DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr), ref_p);
Diego Novillo committed
694 695 696 697 698 699 700 701
}


/* Write all pointer fields in the TS_TYPE_COMMON structure of EXPR to
   output block OB.  If REF_P is true, write a reference to EXPR's
   pointer fields.  */

static void
702 703
write_ts_type_common_tree_pointers (struct output_block *ob, tree expr,
				    bool ref_p)
Diego Novillo committed
704
{
705 706 707 708 709 710
  stream_write_tree (ob, TYPE_SIZE (expr), ref_p);
  stream_write_tree (ob, TYPE_SIZE_UNIT (expr), ref_p);
  stream_write_tree (ob, TYPE_ATTRIBUTES (expr), ref_p);
  stream_write_tree (ob, TYPE_NAME (expr), ref_p);
  /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO.  They will be
     reconstructed during fixup.  */
Diego Novillo committed
711 712
  /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
     during fixup.  */
713 714
  stream_write_tree (ob, TYPE_MAIN_VARIANT (expr), ref_p);
  stream_write_tree (ob, TYPE_CONTEXT (expr), ref_p);
Diego Novillo committed
715 716
  /* TYPE_CANONICAL is re-computed during type merging, so no need
     to stream it here.  */
717
  /* Do not stream TYPE_STUB_DECL; it is not needed by LTO but currently
718
     it cannot be freed by free_lang_data without triggering ICEs in
719
     langhooks.  */
Diego Novillo committed
720 721 722 723 724 725 726
}

/* Write all pointer fields in the TS_TYPE_NON_COMMON structure of EXPR
   to output block OB.  If REF_P is true, write a reference to EXPR's
   pointer fields.  */

static void
727 728
write_ts_type_non_common_tree_pointers (struct output_block *ob, tree expr,
					bool ref_p)
Diego Novillo committed
729
{
730 731 732 733 734 735 736 737 738 739 740
  if (TREE_CODE (expr) == ENUMERAL_TYPE)
    stream_write_tree (ob, TYPE_VALUES (expr), ref_p);
  else if (TREE_CODE (expr) == ARRAY_TYPE)
    stream_write_tree (ob, TYPE_DOMAIN (expr), ref_p);
  else if (RECORD_OR_UNION_TYPE_P (expr))
    streamer_write_chain (ob, TYPE_FIELDS (expr), ref_p);
  else if (TREE_CODE (expr) == FUNCTION_TYPE
	   || TREE_CODE (expr) == METHOD_TYPE)
    stream_write_tree (ob, TYPE_ARG_TYPES (expr), ref_p);

  if (!POINTER_TYPE_P (expr))
741 742
    stream_write_tree (ob, TYPE_MIN_VALUE_RAW (expr), ref_p);
  stream_write_tree (ob, TYPE_MAX_VALUE_RAW (expr), ref_p);
Diego Novillo committed
743 744 745 746 747 748 749 750
}


/* Write all pointer fields in the TS_LIST structure of EXPR to output
   block OB.  If REF_P is true, write a reference to EXPR's pointer
   fields.  */

static void
751
write_ts_list_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
Diego Novillo committed
752
{
753 754
  stream_write_tree (ob, TREE_PURPOSE (expr), ref_p);
  stream_write_tree (ob, TREE_VALUE (expr), ref_p);
755
  stream_write_tree (ob, TREE_CHAIN (expr), ref_p);
Diego Novillo committed
756 757 758 759 760 761 762 763
}


/* Write all pointer fields in the TS_VEC structure of EXPR to output
   block OB.  If REF_P is true, write a reference to EXPR's pointer
   fields.  */

static void
764
write_ts_vec_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
Diego Novillo committed
765 766 767 768
{
  int i;

  /* Note that the number of slots for EXPR has already been emitted
769
     in EXPR's header (see streamer_write_tree_header).  */
Diego Novillo committed
770
  for (i = 0; i < TREE_VEC_LENGTH (expr); i++)
771
    stream_write_tree (ob, TREE_VEC_ELT (expr, i), ref_p);
Diego Novillo committed
772 773 774 775 776 777 778 779
}


/* Write all pointer fields in the TS_EXP structure of EXPR to output
   block OB.  If REF_P is true, write a reference to EXPR's pointer
   fields.  */

static void
780
write_ts_exp_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
Diego Novillo committed
781 782 783 784
{
  int i;

  for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
785 786
    stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
  stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
Diego Novillo committed
787 788 789 790 791 792 793 794
}


/* Write all pointer fields in the TS_BLOCK structure of EXPR to output
   block OB.  If REF_P is true, write a reference to EXPR's pointer
   fields.  */

static void
795
write_ts_block_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
Diego Novillo committed
796
{
797
  streamer_write_chain (ob, BLOCK_VARS (expr), ref_p);
Diego Novillo committed
798

799
  stream_write_tree (ob, BLOCK_SUPERCONTEXT (expr), ref_p);
800
  stream_write_tree (ob, BLOCK_ABSTRACT_ORIGIN (expr), ref_p);
801

Diego Novillo committed
802
  /* Do not stream BLOCK_NONLOCALIZED_VARS.  We cannot handle debug information
803
     for early inlined BLOCKs so drop it on the floor instead of ICEing in
Diego Novillo committed
804 805
     dwarf2out.c.  */

806 807 808
  /* BLOCK_FRAGMENT_ORIGIN and BLOCK_FRAGMENT_CHAIN is not live at LTO
     streaming time.  */

Diego Novillo committed
809 810 811 812 813 814 815 816 817 818
  /* Do not output BLOCK_SUBBLOCKS.  Instead on streaming-in this
     list is re-constructed from BLOCK_SUPERCONTEXT.  */
}


/* Write all pointer fields in the TS_BINFO structure of EXPR to output
   block OB.  If REF_P is true, write a reference to EXPR's pointer
   fields.  */

static void
819
write_ts_binfo_tree_pointers (struct output_block *ob, tree expr, bool ref_p)
Diego Novillo committed
820 821 822 823 824
{
  unsigned i;
  tree t;

  /* Note that the number of BINFO slots has already been emitted in
825
     EXPR's header (see streamer_write_tree_header) because this length
Diego Novillo committed
826
     is needed to build the empty BINFO node on the reader side.  */
827
  FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (expr), i, t)
828 829
    stream_write_tree (ob, t, ref_p);
  stream_write_tree (ob, NULL_TREE, false);
Diego Novillo committed
830

831 832
  stream_write_tree (ob, BINFO_OFFSET (expr), ref_p);
  stream_write_tree (ob, BINFO_VTABLE (expr), ref_p);
Diego Novillo committed
833

834 835
  /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX,
     BINFO_BASE_ACCESSES and BINFO_VPTR_INDEX; these are used by C++ FE only.  */
Diego Novillo committed
836 837 838 839 840 841 842 843
}


/* Write all pointer fields in the TS_CONSTRUCTOR structure of EXPR to
   output block OB.  If REF_P is true, write a reference to EXPR's
   pointer fields.  */

static void
844 845
write_ts_constructor_tree_pointers (struct output_block *ob, tree expr,
				    bool ref_p)
Diego Novillo committed
846 847 848 849 850 851
{
  unsigned i;
  tree index, value;

  FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (expr), i, index, value)
    {
852 853
      stream_write_tree (ob, index, ref_p);
      stream_write_tree (ob, value, ref_p);
Diego Novillo committed
854 855 856
    }
}

857 858 859 860 861 862 863 864 865 866 867 868

/* 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);
869
  switch (OMP_CLAUSE_CODE (expr))
870
    {
871 872 873
    case OMP_CLAUSE_REDUCTION:
    case OMP_CLAUSE_TASK_REDUCTION:
    case OMP_CLAUSE_IN_REDUCTION:
874 875 876 877
      /* 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);
878 879 880
      break;
    default:
      break;
881 882 883 884 885
    }
  stream_write_tree (ob, OMP_CLAUSE_CHAIN (expr), ref_p);
}


886 887
/* Write all pointer fields in EXPR to output block OB.  If REF_P is true,
   the leaves of EXPR are emitted as references.  */
Diego Novillo committed
888

889
void
890
streamer_write_tree_body (struct output_block *ob, tree expr, bool ref_p)
Diego Novillo committed
891 892 893
{
  enum tree_code code;

894 895
  lto_stats.num_tree_bodies_output++;

Diego Novillo committed
896 897 898
  code = TREE_CODE (expr);

  if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
899
    write_ts_common_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
900 901

  if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
902
    write_ts_vector_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
903

904 905 906
  if (CODE_CONTAINS_STRUCT (code, TS_POLY_INT_CST))
    write_ts_poly_tree_pointers (ob, expr, ref_p);

Diego Novillo committed
907
  if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX))
908
    write_ts_complex_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
909 910

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
911
    write_ts_decl_minimal_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
912 913

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
914
    write_ts_decl_common_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
915 916

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
917
    write_ts_decl_non_common_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
918 919

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
920
    write_ts_decl_with_vis_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
921 922

  if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
923
    write_ts_field_decl_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
924 925

  if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
926
    write_ts_function_decl_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
927 928

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
929
    write_ts_type_common_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
930 931

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON))
932
    write_ts_type_non_common_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
933 934

  if (CODE_CONTAINS_STRUCT (code, TS_LIST))
935
    write_ts_list_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
936 937

  if (CODE_CONTAINS_STRUCT (code, TS_VEC))
938
    write_ts_vec_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
939 940

  if (CODE_CONTAINS_STRUCT (code, TS_EXP))
941
    write_ts_exp_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
942 943

  if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
944
    write_ts_block_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
945 946

  if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
947
    write_ts_binfo_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
948 949

  if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
950
    write_ts_constructor_tree_pointers (ob, expr, ref_p);
951 952 953

  if (code == OMP_CLAUSE)
    write_ts_omp_clause_tree_pointers (ob, expr, ref_p);
Diego Novillo committed
954 955 956 957 958 959
}


/* Emit header information for tree EXPR to output block OB.  The header
   contains everything needed to instantiate an empty skeleton for
   EXPR on the reading side.  IX is the index into the streamer cache
960
   where EXPR is stored.  */
Diego Novillo committed
961

962
void
963
streamer_write_tree_header (struct output_block *ob, tree expr)
Diego Novillo committed
964 965 966 967 968 969 970 971 972 973 974 975
{
  enum LTO_tags tag;
  enum tree_code code;

  /* We should not see any tree nodes not handled by the streamer.  */
  code = TREE_CODE (expr);

  /* The header of a tree node consists of its tag, the size of
     the node, and any other information needed to instantiate
     EXPR on the reading side (such as the number of slots in
     variable sized nodes).  */
  tag = lto_tree_code_to_tag (code);
976
  streamer_write_record_start (ob, tag);
Diego Novillo committed
977 978 979 980

  /* The text in strings and identifiers are completely emitted in
     the header.  */
  if (CODE_CONTAINS_STRUCT (code, TS_STRING))
981
    streamer_write_string_cst (ob, ob->main_stream, expr);
Diego Novillo committed
982
  else if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER))
983
    write_identifier (ob, ob->main_stream, expr);
984
  else if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
985 986 987 988 989 990
    {
      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);
    }
Diego Novillo committed
991
  else if (CODE_CONTAINS_STRUCT (code, TS_VEC))
992
    streamer_write_hwi (ob, TREE_VEC_LENGTH (expr));
Diego Novillo committed
993
  else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
994
    streamer_write_uhwi (ob, BINFO_N_BASE_BINFOS (expr));
995
  else if (TREE_CODE (expr) == CALL_EXPR)
996
    streamer_write_uhwi (ob, call_expr_nargs (expr));
997 998
  else if (TREE_CODE (expr) == OMP_CLAUSE)
    streamer_write_uhwi (ob, OMP_CLAUSE_CODE (expr));
Kenneth Zadeck committed
999 1000 1001 1002 1003 1004
  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));
    }
Diego Novillo committed
1005 1006 1007 1008 1009 1010
}


/* Emit the integer constant CST to output block OB.  If REF_P is true,
   CST's type will be emitted as a reference.  */

1011
void
1012
streamer_write_integer_cst (struct output_block *ob, tree cst, bool ref_p)
Diego Novillo committed
1013
{
Kenneth Zadeck committed
1014 1015
  int i;
  int len = TREE_INT_CST_NUNITS (cst);
1016 1017
  gcc_assert (!TREE_OVERFLOW (cst));
  streamer_write_record_start (ob, LTO_integer_cst);
1018
  stream_write_tree (ob, TREE_TYPE (cst), ref_p);
Kenneth Zadeck committed
1019 1020 1021 1022 1023 1024 1025
  /* 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));
Diego Novillo committed
1026
}