1 /* Miscellaneous utilities for GIMPLE streaming. Things that are used
2 in both input and output are here.
4 Copyright 2009, 2010 Free Software Foundation, Inc.
5 Contributed by Doug Kwan <dougkwan@google.com>
7 This file is part of GCC.
9 GCC is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 3, or (at your option) any later
14 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19 You should have received a copy of the GNU General Public License
20 along with GCC; see the file COPYING3. If not see
21 <http://www.gnu.org/licenses/>. */
25 #include "coretypes.h"
31 #include "tree-flow.h"
32 #include "diagnostic-core.h"
35 #include "lto-streamer.h"
37 /* Statistics gathered during LTO, WPA and LTRANS. */
38 struct lto_stats_d lto_stats
;
40 /* LTO uses bitmaps with different life-times. So use a seperate
41 obstack for all LTO bitmaps. */
42 static bitmap_obstack lto_obstack
;
43 static bool lto_obstack_initialized
;
46 /* Return a string representing LTO tag TAG. */
49 lto_tag_name (enum LTO_tags tag
)
51 if (lto_tag_is_tree_code_p (tag
))
53 /* For tags representing tree nodes, return the name of the
54 associated tree code. */
55 return tree_code_name
[lto_tag_to_tree_code (tag
)];
58 if (lto_tag_is_gimple_code_p (tag
))
60 /* For tags representing gimple statements, return the name of
61 the associated gimple code. */
62 return gimple_code_name
[lto_tag_to_gimple_code (tag
)];
74 return "LTO_eh_region";
76 return "LTO_function";
78 return "LTO_eh_table";
80 return "LTO_ert_cleanup";
83 case LTO_ert_allowed_exceptions
:
84 return "LTO_ert_allowed_exceptions";
85 case LTO_ert_must_not_throw
:
86 return "LTO_ert_must_not_throw";
87 case LTO_tree_pickle_reference
:
88 return "LTO_tree_pickle_reference";
89 case LTO_field_decl_ref
:
90 return "LTO_field_decl_ref";
91 case LTO_function_decl_ref
:
92 return "LTO_function_decl_ref";
93 case LTO_label_decl_ref
:
94 return "LTO_label_decl_ref";
95 case LTO_namespace_decl_ref
:
96 return "LTO_namespace_decl_ref";
97 case LTO_result_decl_ref
:
98 return "LTO_result_decl_ref";
99 case LTO_ssa_name_ref
:
100 return "LTO_ssa_name_ref";
101 case LTO_type_decl_ref
:
102 return "LTO_type_decl_ref";
104 return "LTO_type_ref";
105 case LTO_global_decl_ref
:
106 return "LTO_global_decl_ref";
108 return "LTO_UNKNOWN";
113 /* Allocate a bitmap from heap. Initializes the LTO obstack if necessary. */
116 lto_bitmap_alloc (void)
118 if (!lto_obstack_initialized
)
120 bitmap_obstack_initialize (<o_obstack
);
121 lto_obstack_initialized
= true;
123 return BITMAP_ALLOC (<o_obstack
);
129 lto_bitmap_free (bitmap b
)
135 /* Get a section name for a particular type or name. The NAME field
136 is only used if SECTION_TYPE is LTO_section_function_body. For all
137 others it is ignored. The callee of this function is responsible
138 to free the returned name. */
141 lto_get_section_name (int section_type
, const char *name
, struct lto_file_decl_data
*f
)
147 if (section_type
== LTO_section_function_body
)
149 gcc_assert (name
!= NULL
);
155 else if (section_type
< LTO_N_SECTION_TYPES
)
157 add
= lto_section_name
[section_type
];
161 internal_error ("bytecode stream: unexpected LTO section %s", name
);
163 /* Make the section name unique so that ld -r combining sections
164 doesn't confuse the reader with merged sections.
166 For options don't add a ID, the option reader cannot deal with them
167 and merging should be ok here.
169 XXX: use crc64 to minimize collisions? */
170 if (section_type
== LTO_section_opts
)
173 sprintf (post
, ".%x", f
? f
->id
: crc32_string(0, get_random_seed (false)));
174 return concat (LTO_SECTION_NAME_PREFIX
, sep
, add
, post
, NULL
);
178 /* Show various memory usage statistics related to LTO. */
181 print_lto_report (void)
183 const char *s
= (flag_lto
) ? "LTO" : (flag_wpa
) ? "WPA" : "LTRANS";
186 fprintf (stderr
, "%s statistics\n", s
);
187 fprintf (stderr
, "[%s] # of input files: "
188 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
, lto_stats
.num_input_files
);
190 fprintf (stderr
, "[%s] # of input cgraph nodes: "
191 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
192 lto_stats
.num_input_cgraph_nodes
);
194 fprintf (stderr
, "[%s] # of function bodies: "
195 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
196 lto_stats
.num_function_bodies
);
198 fprintf (stderr
, "[%s] ", s
);
199 print_gimple_types_stats ();
201 for (i
= 0; i
< NUM_TREE_CODES
; i
++)
202 if (lto_stats
.num_trees
[i
])
203 fprintf (stderr
, "[%s] # of '%s' objects read: "
204 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
205 tree_code_name
[i
], lto_stats
.num_trees
[i
]);
209 fprintf (stderr
, "[%s] Compression: "
210 HOST_WIDE_INT_PRINT_UNSIGNED
" output bytes, "
211 HOST_WIDE_INT_PRINT_UNSIGNED
" compressed bytes", s
,
212 lto_stats
.num_output_il_bytes
,
213 lto_stats
.num_compressed_il_bytes
);
214 if (lto_stats
.num_output_il_bytes
> 0)
216 const float dividend
= (float) lto_stats
.num_compressed_il_bytes
;
217 const float divisor
= (float) lto_stats
.num_output_il_bytes
;
218 fprintf (stderr
, " (ratio: %f)", dividend
/ divisor
);
220 fprintf (stderr
, "\n");
225 fprintf (stderr
, "[%s] # of output files: "
226 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
227 lto_stats
.num_output_files
);
229 fprintf (stderr
, "[%s] # of output cgraph nodes: "
230 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
231 lto_stats
.num_output_cgraph_nodes
);
233 fprintf (stderr
, "[%s] # callgraph partitions: "
234 HOST_WIDE_INT_PRINT_UNSIGNED
"\n", s
,
235 lto_stats
.num_cgraph_partitions
);
237 fprintf (stderr
, "[%s] Compression: "
238 HOST_WIDE_INT_PRINT_UNSIGNED
" input bytes, "
239 HOST_WIDE_INT_PRINT_UNSIGNED
" uncompressed bytes", s
,
240 lto_stats
.num_input_il_bytes
,
241 lto_stats
.num_uncompressed_il_bytes
);
242 if (lto_stats
.num_input_il_bytes
> 0)
244 const float dividend
= (float) lto_stats
.num_uncompressed_il_bytes
;
245 const float divisor
= (float) lto_stats
.num_input_il_bytes
;
246 fprintf (stderr
, " (ratio: %f)", dividend
/ divisor
);
248 fprintf (stderr
, "\n");
251 for (i
= 0; i
< LTO_N_SECTION_TYPES
; i
++)
252 fprintf (stderr
, "[%s] Size of mmap'd section %s: "
253 HOST_WIDE_INT_PRINT_UNSIGNED
" bytes\n", s
,
254 lto_section_name
[i
], lto_stats
.section_size
[i
]);
258 /* Check that all the TS_* structures handled by the lto_output_* and
259 lto_input_* routines are exactly ALL the structures defined in
263 check_handled_ts_structures (void)
265 bool handled_p
[LAST_TS_ENUM
];
268 memset (&handled_p
, 0, sizeof (handled_p
));
270 /* These are the TS_* structures that are either handled or
271 explicitly ignored by the streamer routines. */
272 handled_p
[TS_BASE
] = true;
273 handled_p
[TS_COMMON
] = true;
274 handled_p
[TS_INT_CST
] = true;
275 handled_p
[TS_REAL_CST
] = true;
276 handled_p
[TS_FIXED_CST
] = true;
277 handled_p
[TS_VECTOR
] = true;
278 handled_p
[TS_STRING
] = true;
279 handled_p
[TS_COMPLEX
] = true;
280 handled_p
[TS_IDENTIFIER
] = true;
281 handled_p
[TS_DECL_MINIMAL
] = true;
282 handled_p
[TS_DECL_COMMON
] = true;
283 handled_p
[TS_DECL_WRTL
] = true;
284 handled_p
[TS_DECL_NON_COMMON
] = true;
285 handled_p
[TS_DECL_WITH_VIS
] = true;
286 handled_p
[TS_FIELD_DECL
] = true;
287 handled_p
[TS_VAR_DECL
] = true;
288 handled_p
[TS_PARM_DECL
] = true;
289 handled_p
[TS_LABEL_DECL
] = true;
290 handled_p
[TS_RESULT_DECL
] = true;
291 handled_p
[TS_CONST_DECL
] = true;
292 handled_p
[TS_TYPE_DECL
] = true;
293 handled_p
[TS_FUNCTION_DECL
] = true;
294 handled_p
[TS_TYPE
] = true;
295 handled_p
[TS_LIST
] = true;
296 handled_p
[TS_VEC
] = true;
297 handled_p
[TS_EXP
] = true;
298 handled_p
[TS_SSA_NAME
] = true;
299 handled_p
[TS_BLOCK
] = true;
300 handled_p
[TS_BINFO
] = true;
301 handled_p
[TS_STATEMENT_LIST
] = true;
302 handled_p
[TS_CONSTRUCTOR
] = true;
303 handled_p
[TS_OMP_CLAUSE
] = true;
304 handled_p
[TS_OPTIMIZATION
] = true;
305 handled_p
[TS_TARGET_OPTION
] = true;
306 handled_p
[TS_TRANSLATION_UNIT_DECL
] = true;
308 /* Anything not marked above will trigger the following assertion.
309 If this assertion triggers, it means that there is a new TS_*
310 structure that should be handled by the streamer. */
311 for (i
= 0; i
< LAST_TS_ENUM
; i
++)
312 gcc_assert (handled_p
[i
]);
316 /* Helper for lto_streamer_cache_insert_1. Add T to CACHE->NODES at
317 slot IX. Add OFFSET to CACHE->OFFSETS at slot IX. */
320 lto_streamer_cache_add_to_node_array (struct lto_streamer_cache_d
*cache
,
321 int ix
, tree t
, unsigned offset
)
323 gcc_assert (ix
>= 0);
325 /* Grow the array of nodes and offsets to accomodate T at IX. */
326 if (ix
>= (int) VEC_length (tree
, cache
->nodes
))
328 size_t sz
= ix
+ (20 + ix
) / 4;
329 VEC_safe_grow_cleared (tree
, heap
, cache
->nodes
, sz
);
330 VEC_safe_grow_cleared (unsigned, heap
, cache
->offsets
, sz
);
333 VEC_replace (tree
, cache
->nodes
, ix
, t
);
334 VEC_replace (unsigned, cache
->offsets
, ix
, offset
);
338 /* Helper for lto_streamer_cache_insert and lto_streamer_cache_insert_at.
339 CACHE, T, IX_P and OFFSET_P are as in lto_streamer_cache_insert.
341 If INSERT_AT_NEXT_SLOT_P is true, T is inserted at the next available
342 slot in the cache. Otherwise, T is inserted at the position indicated
345 If T already existed in CACHE, return true. Otherwise,
349 lto_streamer_cache_insert_1 (struct lto_streamer_cache_d
*cache
,
350 tree t
, int *ix_p
, unsigned *offset_p
,
351 bool insert_at_next_slot_p
)
354 struct tree_int_map d_entry
, *entry
;
361 d_entry
.base
.from
= t
;
362 slot
= htab_find_slot (cache
->node_map
, &d_entry
, INSERT
);
365 /* Determine the next slot to use in the cache. */
366 if (insert_at_next_slot_p
)
367 ix
= cache
->next_slot
++;
371 entry
= (struct tree_int_map
*)pool_alloc (cache
->node_map_entries
);
372 entry
->base
.from
= t
;
373 entry
->to
= (unsigned) ix
;
376 /* If no offset was given, store the invalid offset -1. */
377 offset
= (offset_p
) ? *offset_p
: (unsigned) -1;
379 lto_streamer_cache_add_to_node_array (cache
, ix
, t
, offset
);
381 /* Indicate that the item was not present in the cache. */
386 entry
= (struct tree_int_map
*) *slot
;
387 ix
= (int) entry
->to
;
388 offset
= VEC_index (unsigned, cache
->offsets
, ix
);
390 if (!insert_at_next_slot_p
&& ix
!= *ix_p
)
392 /* If the caller wants to insert T at a specific slot
393 location, and ENTRY->TO does not match *IX_P, add T to
394 the requested location slot. This situation arises when
395 streaming builtin functions.
397 For instance, on the writer side we could have two
398 FUNCTION_DECLS T1 and T2 that are represented by the same
399 builtin function. The reader will only instantiate the
400 canonical builtin, but since T1 and T2 had been
401 originally stored in different cache slots (S1 and S2),
402 the reader must be able to find the canonical builtin
403 function at slots S1 and S2. */
404 gcc_assert (lto_stream_as_builtin_p (t
));
407 /* Since we are storing a builtin, the offset into the
408 stream is not necessary as we will not need to read
409 forward in the stream. */
410 lto_streamer_cache_add_to_node_array (cache
, ix
, t
, -1);
413 /* Indicate that T was already in the cache. */
427 /* Insert tree node T in CACHE. If T already existed in the cache
428 return true. Otherwise, return false.
430 If IX_P is non-null, update it with the index into the cache where
433 *OFFSET_P represents the offset in the stream where T is physically
434 written out. The first time T is added to the cache, *OFFSET_P is
435 recorded in the cache together with T. But if T already existed
436 in the cache, *OFFSET_P is updated with the value that was recorded
437 the first time T was added to the cache.
439 If OFFSET_P is NULL, it is ignored. */
442 lto_streamer_cache_insert (struct lto_streamer_cache_d
*cache
, tree t
,
443 int *ix_p
, unsigned *offset_p
)
445 return lto_streamer_cache_insert_1 (cache
, t
, ix_p
, offset_p
, true);
449 /* Insert tree node T in CACHE at slot IX. If T already
450 existed in the cache return true. Otherwise, return false. */
453 lto_streamer_cache_insert_at (struct lto_streamer_cache_d
*cache
,
456 return lto_streamer_cache_insert_1 (cache
, t
, &ix
, NULL
, false);
460 /* Return true if tree node T exists in CACHE. If IX_P is
461 not NULL, write to *IX_P the index into the cache where T is stored
462 (-1 if T is not found). */
465 lto_streamer_cache_lookup (struct lto_streamer_cache_d
*cache
, tree t
,
469 struct tree_int_map d_slot
;
475 d_slot
.base
.from
= t
;
476 slot
= htab_find_slot (cache
->node_map
, &d_slot
, NO_INSERT
);
485 ix
= (int) ((struct tree_int_map
*) *slot
)->to
;
495 /* Return the tree node at slot IX in CACHE. */
498 lto_streamer_cache_get (struct lto_streamer_cache_d
*cache
, int ix
)
502 /* If the reader is requesting an index beyond the length of the
503 cache, it will need to read ahead. Return NULL_TREE to indicate
505 if ((unsigned) ix
>= VEC_length (tree
, cache
->nodes
))
508 return VEC_index (tree
, cache
->nodes
, (unsigned) ix
);
512 /* Record NODE in COMMON_NODES if it is not NULL and is not already in
516 lto_record_common_node (tree
*nodep
, VEC(tree
, heap
) **common_nodes
,
517 struct pointer_set_t
*seen_nodes
)
521 if (node
== NULL_TREE
)
526 /* Type merging will get confused by the canonical types as they
527 are set by the middle-end. */
529 TYPE_CANONICAL (node
) = NULL_TREE
;
530 node
= gimple_register_type (node
);
531 TYPE_CANONICAL (node
) = gimple_register_canonical_type (node
);
535 /* Return if node is already seen. */
536 if (pointer_set_insert (seen_nodes
, node
))
539 VEC_safe_push (tree
, heap
, *common_nodes
, node
);
541 if (tree_node_can_be_shared (node
))
543 if (POINTER_TYPE_P (node
)
544 || TREE_CODE (node
) == COMPLEX_TYPE
545 || TREE_CODE (node
) == ARRAY_TYPE
)
546 lto_record_common_node (&TREE_TYPE (node
), common_nodes
, seen_nodes
);
551 /* Generate a vector of common nodes and make sure they are merged
552 properly according to the the gimple type table. */
554 static VEC(tree
,heap
) *
555 lto_get_common_nodes (void)
558 VEC(tree
,heap
) *common_nodes
= NULL
;
559 struct pointer_set_t
*seen_nodes
;
561 /* The MAIN_IDENTIFIER_NODE is normally set up by the front-end, but the
562 LTO back-end must agree. Currently, the only languages that set this
563 use the name "main". */
564 if (main_identifier_node
)
566 const char *main_name
= IDENTIFIER_POINTER (main_identifier_node
);
567 gcc_assert (strcmp (main_name
, "main") == 0);
570 main_identifier_node
= get_identifier ("main");
572 /* FIXME pph. These assertions are never met while in the front end.
573 There should be a way of checking this only when we are in LTO
576 gcc_assert (ptrdiff_type_node
== integer_type_node
);
578 /* FIXME lto. In the C++ front-end, fileptr_type_node is defined as a
579 variant copy of of ptr_type_node, rather than ptr_node itself. The
580 distinction should only be relevant to the front-end, so we always
581 use the C definition here in lto1.
583 These should be assured in pass_ipa_free_lang_data. */
584 gcc_assert (fileptr_type_node
== ptr_type_node
);
585 gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node
) == ptr_type_node
);
588 seen_nodes
= pointer_set_create ();
590 /* Skip itk_char. char_type_node is shared with the appropriately
592 for (i
= itk_signed_char
; i
< itk_none
; i
++)
593 lto_record_common_node (&integer_types
[i
], &common_nodes
, seen_nodes
);
595 for (i
= 0; i
< TYPE_KIND_LAST
; i
++)
596 lto_record_common_node (&sizetype_tab
[i
], &common_nodes
, seen_nodes
);
598 for (i
= 0; i
< TI_MAX
; i
++)
599 lto_record_common_node (&global_trees
[i
], &common_nodes
, seen_nodes
);
601 pointer_set_destroy (seen_nodes
);
607 /* Assign an index to tree node T and enter it in the streamer cache
611 preload_common_node (struct lto_streamer_cache_d
*cache
, tree t
)
615 lto_streamer_cache_insert (cache
, t
, NULL
, NULL
);
617 /* The FIELD_DECLs of structures should be shared, so that every
618 COMPONENT_REF uses the same tree node when referencing a field.
619 Pointer equality between FIELD_DECLs is used by the alias
620 machinery to compute overlapping memory references (See
621 nonoverlapping_component_refs_p). */
622 if (TREE_CODE (t
) == RECORD_TYPE
)
626 for (f
= TYPE_FIELDS (t
); f
; f
= TREE_CHAIN (f
))
627 preload_common_node (cache
, f
);
632 /* Create a cache of pickled nodes. */
634 struct lto_streamer_cache_d
*
635 lto_streamer_cache_create (void)
637 struct lto_streamer_cache_d
*cache
;
638 VEC(tree
, heap
) *common_nodes
;
642 cache
= XCNEW (struct lto_streamer_cache_d
);
644 cache
->node_map
= htab_create (101, tree_int_map_hash
, tree_int_map_eq
, NULL
);
646 cache
->node_map_entries
= create_alloc_pool ("node map",
647 sizeof (struct tree_int_map
),
650 /* Load all the well-known tree nodes that are always created by
651 the compiler on startup. This prevents writing them out
653 common_nodes
= lto_get_common_nodes ();
655 FOR_EACH_VEC_ELT (tree
, common_nodes
, i
, node
)
656 preload_common_node (cache
, node
);
658 VEC_free(tree
, heap
, common_nodes
);
664 /* Delete the streamer cache C. */
667 lto_streamer_cache_delete (struct lto_streamer_cache_d
*c
)
672 htab_delete (c
->node_map
);
673 free_alloc_pool (c
->node_map_entries
);
674 VEC_free (tree
, heap
, c
->nodes
);
675 VEC_free (unsigned, heap
, c
->offsets
);
680 #ifdef LTO_STREAMER_DEBUG
681 static htab_t tree_htab
;
683 struct tree_hash_entry
690 hash_tree (const void *p
)
692 const struct tree_hash_entry
*e
= (const struct tree_hash_entry
*) p
;
693 return htab_hash_pointer (e
->key
);
697 eq_tree (const void *p1
, const void *p2
)
699 const struct tree_hash_entry
*e1
= (const struct tree_hash_entry
*) p1
;
700 const struct tree_hash_entry
*e2
= (const struct tree_hash_entry
*) p2
;
701 return (e1
->key
== e2
->key
);
705 /* Initialization common to the LTO reader and writer. */
708 lto_streamer_init (void)
710 /* Check that all the TS_* handled by the reader and writer routines
711 match exactly the structures defined in treestruct.def. When a
712 new TS_* astructure is added, the streamer should be updated to
714 check_handled_ts_structures ();
716 #ifdef LTO_STREAMER_DEBUG
717 tree_htab
= htab_create (31, hash_tree
, eq_tree
, NULL
);
722 /* Gate function for all LTO streaming passes. */
727 return ((flag_generate_lto
|| in_lto_p
)
728 /* Don't bother doing anything if the program has errors. */
733 #ifdef LTO_STREAMER_DEBUG
734 /* Add a mapping between T and ORIG_T, which is the numeric value of
735 the original address of T as it was seen by the LTO writer. This
736 mapping is useful when debugging streaming problems. A debugging
737 session can be started on both reader and writer using ORIG_T
738 as a breakpoint value in both sessions.
740 Note that this mapping is transient and only valid while T is
741 being reconstructed. Once T is fully built, the mapping is
745 lto_orig_address_map (tree t
, intptr_t orig_t
)
747 struct tree_hash_entry ent
;
748 struct tree_hash_entry
**slot
;
753 = (struct tree_hash_entry
**) htab_find_slot (tree_htab
, &ent
, INSERT
);
755 *slot
= XNEW (struct tree_hash_entry
);
760 /* Get the original address of T as it was seen by the writer. This
761 is only valid while T is being reconstructed. */
764 lto_orig_address_get (tree t
)
766 struct tree_hash_entry ent
;
767 struct tree_hash_entry
**slot
;
771 = (struct tree_hash_entry
**) htab_find_slot (tree_htab
, &ent
, NO_INSERT
);
772 return (slot
? (*slot
)->value
: 0);
776 /* Clear the mapping of T to its original address. */
779 lto_orig_address_remove (tree t
)
781 struct tree_hash_entry ent
;
782 struct tree_hash_entry
**slot
;
786 = (struct tree_hash_entry
**) htab_find_slot (tree_htab
, &ent
, NO_INSERT
);
789 htab_clear_slot (tree_htab
, (PTR
*)slot
);
794 /* Check that the version MAJOR.MINOR is the correct version number. */
797 lto_check_version (int major
, int minor
)
799 if (major
!= LTO_major_version
|| minor
!= LTO_minor_version
)
800 fatal_error ("bytecode stream generated with LTO version %d.%d instead "
801 "of the expected %d.%d",
803 LTO_major_version
, LTO_minor_version
);
807 /* Return true if EXPR is a tree node that can be written to disk. */
810 lto_is_streamable (tree expr
)
812 enum tree_code code
= TREE_CODE (expr
);
814 /* Notice that we reject SSA_NAMEs as well. We only emit the SSA
815 name version in lto_output_tree_ref (see output_ssa_names). */
816 return !is_lang_specific (expr
)
820 && code
!= MODIFY_EXPR
822 && code
!= TARGET_EXPR
824 && code
!= WITH_CLEANUP_EXPR
825 && code
!= STATEMENT_LIST
826 && code
!= OMP_CLAUSE
827 && code
!= OPTIMIZATION_NODE
828 && (code
== CASE_LABEL_EXPR
830 || TREE_CODE_CLASS (code
) != tcc_statement
);
834 /* Initialize all the streamer hooks used for streaming GIMPLE. */
837 gimple_streamer_hooks_init (void)
839 lto_streamer_hooks
*h
= streamer_hooks_init ();
841 h
->reader_init
= gimple_streamer_reader_init
;
842 h
->writer_init
= NULL
;
843 h
->is_streamable
= lto_is_streamable
;
844 h
->write_tree
= gimple_streamer_write_tree
;
845 h
->read_tree
= gimple_streamer_read_tree
;
846 h
->register_decls_in_symtab_p
= true;
850 /* Return the current set of streamer hooks. Note that only one set
851 of streamer hooks can be active at a time. */
853 static lto_streamer_hooks streamer_hooks_
;
856 streamer_hooks (void)
858 return &streamer_hooks_
;
862 /* Initialize and return the current set of streamer hooks. */
865 streamer_hooks_init (void)
867 lto_streamer_hooks
*h
= streamer_hooks ();
868 memset (h
, 0, sizeof (lto_streamer_hooks
));