* gcc.dg/vect/slp-perm-1.c (main): Make sure loops aren't vectorized.
[official-gcc.git] / gcc / lto-streamer.c
blob406096015f4a6d56c2bcd3e4ee8e967fc506ab88
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
12 version.
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
17 for more details.
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/>. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "toplev.h"
28 #include "flags.h"
29 #include "tree.h"
30 #include "gimple.h"
31 #include "tree-flow.h"
32 #include "diagnostic-core.h"
33 #include "bitmap.h"
34 #include "vec.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. */
48 const char *
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)];
65 switch (tag)
67 case LTO_null:
68 return "LTO_null";
69 case LTO_bb0:
70 return "LTO_bb0";
71 case LTO_bb1:
72 return "LTO_bb1";
73 case LTO_eh_region:
74 return "LTO_eh_region";
75 case LTO_function:
76 return "LTO_function";
77 case LTO_eh_table:
78 return "LTO_eh_table";
79 case LTO_ert_cleanup:
80 return "LTO_ert_cleanup";
81 case LTO_ert_try:
82 return "LTO_ert_try";
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";
103 case LTO_type_ref:
104 return "LTO_type_ref";
105 case LTO_global_decl_ref:
106 return "LTO_global_decl_ref";
107 default:
108 return "LTO_UNKNOWN";
113 /* Allocate a bitmap from heap. Initializes the LTO obstack if necessary. */
115 bitmap
116 lto_bitmap_alloc (void)
118 if (!lto_obstack_initialized)
120 bitmap_obstack_initialize (&lto_obstack);
121 lto_obstack_initialized = true;
123 return BITMAP_ALLOC (&lto_obstack);
126 /* Free bitmap B. */
128 void
129 lto_bitmap_free (bitmap b)
131 BITMAP_FREE (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 or
137 LTO_static_initializer. For all others it is ignored. The callee
138 of this function is responcible to free the returned name. */
140 char *
141 lto_get_section_name (int section_type, const char *name)
143 switch (section_type)
145 case LTO_section_function_body:
146 gcc_assert (name != NULL);
147 if (name[0] == '*')
148 name++;
149 return concat (LTO_SECTION_NAME_PREFIX, name, NULL);
151 case LTO_section_static_initializer:
152 return concat (LTO_SECTION_NAME_PREFIX, ".statics", NULL);
154 case LTO_section_symtab:
155 return concat (LTO_SECTION_NAME_PREFIX, ".symtab", NULL);
157 case LTO_section_decls:
158 return concat (LTO_SECTION_NAME_PREFIX, ".decls", NULL);
160 case LTO_section_cgraph:
161 return concat (LTO_SECTION_NAME_PREFIX, ".cgraph", NULL);
163 case LTO_section_varpool:
164 return concat (LTO_SECTION_NAME_PREFIX, ".vars", NULL);
166 case LTO_section_refs:
167 return concat (LTO_SECTION_NAME_PREFIX, ".refs", NULL);
169 case LTO_section_jump_functions:
170 return concat (LTO_SECTION_NAME_PREFIX, ".jmpfuncs", NULL);
172 case LTO_section_ipa_pure_const:
173 return concat (LTO_SECTION_NAME_PREFIX, ".pureconst", NULL);
175 case LTO_section_ipa_reference:
176 return concat (LTO_SECTION_NAME_PREFIX, ".reference", NULL);
178 case LTO_section_opts:
179 return concat (LTO_SECTION_NAME_PREFIX, ".opts", NULL);
181 case LTO_section_cgraph_opt_sum:
182 return concat (LTO_SECTION_NAME_PREFIX, ".cgraphopt", NULL);
184 default:
185 internal_error ("bytecode stream: unexpected LTO section %s", name);
190 /* Show various memory usage statistics related to LTO. */
192 void
193 print_lto_report (void)
195 const char *s = (flag_lto) ? "LTO" : (flag_wpa) ? "WPA" : "LTRANS";
196 unsigned i;
198 fprintf (stderr, "%s statistics\n", s);
199 fprintf (stderr, "[%s] # of input files: "
200 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s, lto_stats.num_input_files);
202 fprintf (stderr, "[%s] # of input cgraph nodes: "
203 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
204 lto_stats.num_input_cgraph_nodes);
206 fprintf (stderr, "[%s] # of function bodies: "
207 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
208 lto_stats.num_function_bodies);
210 fprintf (stderr, "[%s] ", s);
211 print_gimple_types_stats ();
213 for (i = 0; i < NUM_TREE_CODES; i++)
214 if (lto_stats.num_trees[i])
215 fprintf (stderr, "[%s] # of '%s' objects read: "
216 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
217 tree_code_name[i], lto_stats.num_trees[i]);
219 if (flag_lto)
221 fprintf (stderr, "[%s] Compression: "
222 HOST_WIDE_INT_PRINT_UNSIGNED " output bytes, "
223 HOST_WIDE_INT_PRINT_UNSIGNED " compressed bytes", s,
224 lto_stats.num_output_il_bytes,
225 lto_stats.num_compressed_il_bytes);
226 if (lto_stats.num_output_il_bytes > 0)
228 const float dividend = (float) lto_stats.num_compressed_il_bytes;
229 const float divisor = (float) lto_stats.num_output_il_bytes;
230 fprintf (stderr, " (ratio: %f)", dividend / divisor);
232 fprintf (stderr, "\n");
235 if (flag_wpa)
237 fprintf (stderr, "[%s] # of output files: "
238 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
239 lto_stats.num_output_files);
241 fprintf (stderr, "[%s] # of output cgraph nodes: "
242 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
243 lto_stats.num_output_cgraph_nodes);
245 fprintf (stderr, "[%s] # callgraph partitions: "
246 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
247 lto_stats.num_cgraph_partitions);
249 fprintf (stderr, "[%s] Compression: "
250 HOST_WIDE_INT_PRINT_UNSIGNED " input bytes, "
251 HOST_WIDE_INT_PRINT_UNSIGNED " uncompressed bytes", s,
252 lto_stats.num_input_il_bytes,
253 lto_stats.num_uncompressed_il_bytes);
254 if (lto_stats.num_input_il_bytes > 0)
256 const float dividend = (float) lto_stats.num_uncompressed_il_bytes;
257 const float divisor = (float) lto_stats.num_input_il_bytes;
258 fprintf (stderr, " (ratio: %f)", dividend / divisor);
260 fprintf (stderr, "\n");
263 for (i = 0; i < LTO_N_SECTION_TYPES; i++)
264 fprintf (stderr, "[%s] Size of mmap'd section %s: "
265 HOST_WIDE_INT_PRINT_UNSIGNED " bytes\n", s,
266 lto_section_name[i], lto_stats.section_size[i]);
270 /* Check that all the TS_* structures handled by the lto_output_* and
271 lto_input_* routines are exactly ALL the structures defined in
272 treestruct.def. */
274 static void
275 check_handled_ts_structures (void)
277 bool handled_p[LAST_TS_ENUM];
278 unsigned i;
280 memset (&handled_p, 0, sizeof (handled_p));
282 /* These are the TS_* structures that are either handled or
283 explicitly ignored by the streamer routines. */
284 handled_p[TS_BASE] = true;
285 handled_p[TS_COMMON] = true;
286 handled_p[TS_INT_CST] = true;
287 handled_p[TS_REAL_CST] = true;
288 handled_p[TS_FIXED_CST] = true;
289 handled_p[TS_VECTOR] = true;
290 handled_p[TS_STRING] = true;
291 handled_p[TS_COMPLEX] = true;
292 handled_p[TS_IDENTIFIER] = true;
293 handled_p[TS_DECL_MINIMAL] = true;
294 handled_p[TS_DECL_COMMON] = true;
295 handled_p[TS_DECL_WRTL] = true;
296 handled_p[TS_DECL_NON_COMMON] = true;
297 handled_p[TS_DECL_WITH_VIS] = true;
298 handled_p[TS_FIELD_DECL] = true;
299 handled_p[TS_VAR_DECL] = true;
300 handled_p[TS_PARM_DECL] = true;
301 handled_p[TS_LABEL_DECL] = true;
302 handled_p[TS_RESULT_DECL] = true;
303 handled_p[TS_CONST_DECL] = true;
304 handled_p[TS_TYPE_DECL] = true;
305 handled_p[TS_FUNCTION_DECL] = true;
306 handled_p[TS_TYPE] = true;
307 handled_p[TS_LIST] = true;
308 handled_p[TS_VEC] = true;
309 handled_p[TS_EXP] = true;
310 handled_p[TS_SSA_NAME] = true;
311 handled_p[TS_BLOCK] = true;
312 handled_p[TS_BINFO] = true;
313 handled_p[TS_STATEMENT_LIST] = true;
314 handled_p[TS_CONSTRUCTOR] = true;
315 handled_p[TS_OMP_CLAUSE] = true;
316 handled_p[TS_OPTIMIZATION] = true;
317 handled_p[TS_TARGET_OPTION] = true;
319 /* Anything not marked above will trigger the following assertion.
320 If this assertion triggers, it means that there is a new TS_*
321 structure that should be handled by the streamer. */
322 for (i = 0; i < LAST_TS_ENUM; i++)
323 gcc_assert (handled_p[i]);
327 /* Helper for lto_streamer_cache_insert_1. Add T to CACHE->NODES at
328 slot IX. Add OFFSET to CACHE->OFFSETS at slot IX. */
330 static void
331 lto_streamer_cache_add_to_node_array (struct lto_streamer_cache_d *cache,
332 int ix, tree t, unsigned offset)
334 gcc_assert (ix >= 0);
336 /* Grow the array of nodes and offsets to accomodate T at IX. */
337 if (ix >= (int) VEC_length (tree, cache->nodes))
339 size_t sz = ix + (20 + ix) / 4;
340 VEC_safe_grow_cleared (tree, heap, cache->nodes, sz);
341 VEC_safe_grow_cleared (unsigned, heap, cache->offsets, sz);
344 VEC_replace (tree, cache->nodes, ix, t);
345 VEC_replace (unsigned, cache->offsets, ix, offset);
349 /* Helper for lto_streamer_cache_insert and lto_streamer_cache_insert_at.
350 CACHE, T, IX_P and OFFSET_P are as in lto_streamer_cache_insert.
352 If INSERT_AT_NEXT_SLOT_P is true, T is inserted at the next available
353 slot in the cache. Otherwise, T is inserted at the position indicated
354 in *IX_P.
356 If T already existed in CACHE, return true. Otherwise,
357 return false. */
359 static bool
360 lto_streamer_cache_insert_1 (struct lto_streamer_cache_d *cache,
361 tree t, int *ix_p, unsigned *offset_p,
362 bool insert_at_next_slot_p)
364 void **slot;
365 struct tree_int_map d_entry, *entry;
366 int ix;
367 unsigned offset;
368 bool existed_p;
370 gcc_assert (t);
372 d_entry.base.from = t;
373 slot = htab_find_slot (cache->node_map, &d_entry, INSERT);
374 if (*slot == NULL)
376 /* Determine the next slot to use in the cache. */
377 if (insert_at_next_slot_p)
378 ix = cache->next_slot++;
379 else
380 ix = *ix_p;
382 entry = (struct tree_int_map *)pool_alloc (cache->node_map_entries);
383 entry->base.from = t;
384 entry->to = (unsigned) ix;
385 *slot = entry;
387 /* If no offset was given, store the invalid offset -1. */
388 offset = (offset_p) ? *offset_p : (unsigned) -1;
390 lto_streamer_cache_add_to_node_array (cache, ix, t, offset);
392 /* Indicate that the item was not present in the cache. */
393 existed_p = false;
395 else
397 entry = (struct tree_int_map *) *slot;
398 ix = (int) entry->to;
399 offset = VEC_index (unsigned, cache->offsets, ix);
401 if (!insert_at_next_slot_p && ix != *ix_p)
403 /* If the caller wants to insert T at a specific slot
404 location, and ENTRY->TO does not match *IX_P, add T to
405 the requested location slot. This situation arises when
406 streaming builtin functions.
408 For instance, on the writer side we could have two
409 FUNCTION_DECLS T1 and T2 that are represented by the same
410 builtin function. The reader will only instantiate the
411 canonical builtin, but since T1 and T2 had been
412 originally stored in different cache slots (S1 and S2),
413 the reader must be able to find the canonical builtin
414 function at slots S1 and S2. */
415 gcc_assert (lto_stream_as_builtin_p (t));
416 ix = *ix_p;
418 /* Since we are storing a builtin, the offset into the
419 stream is not necessary as we will not need to read
420 forward in the stream. */
421 lto_streamer_cache_add_to_node_array (cache, ix, t, -1);
424 /* Indicate that T was already in the cache. */
425 existed_p = true;
428 if (ix_p)
429 *ix_p = ix;
431 if (offset_p)
432 *offset_p = offset;
434 return existed_p;
438 /* Insert tree node T in CACHE. If T already existed in the cache
439 return true. Otherwise, return false.
441 If IX_P is non-null, update it with the index into the cache where
442 T has been stored.
444 *OFFSET_P represents the offset in the stream where T is physically
445 written out. The first time T is added to the cache, *OFFSET_P is
446 recorded in the cache together with T. But if T already existed
447 in the cache, *OFFSET_P is updated with the value that was recorded
448 the first time T was added to the cache.
450 If OFFSET_P is NULL, it is ignored. */
452 bool
453 lto_streamer_cache_insert (struct lto_streamer_cache_d *cache, tree t,
454 int *ix_p, unsigned *offset_p)
456 return lto_streamer_cache_insert_1 (cache, t, ix_p, offset_p, true);
460 /* Insert tree node T in CACHE at slot IX. If T already
461 existed in the cache return true. Otherwise, return false. */
463 bool
464 lto_streamer_cache_insert_at (struct lto_streamer_cache_d *cache,
465 tree t, int ix)
467 return lto_streamer_cache_insert_1 (cache, t, &ix, NULL, false);
471 /* Return true if tree node T exists in CACHE. If IX_P is
472 not NULL, write to *IX_P the index into the cache where T is stored
473 (-1 if T is not found). */
475 bool
476 lto_streamer_cache_lookup (struct lto_streamer_cache_d *cache, tree t,
477 int *ix_p)
479 void **slot;
480 struct tree_int_map d_slot;
481 bool retval;
482 int ix;
484 gcc_assert (t);
486 d_slot.base.from = t;
487 slot = htab_find_slot (cache->node_map, &d_slot, NO_INSERT);
488 if (slot == NULL)
490 retval = false;
491 ix = -1;
493 else
495 retval = true;
496 ix = (int) ((struct tree_int_map *) *slot)->to;
499 if (ix_p)
500 *ix_p = ix;
502 return retval;
506 /* Return the tree node at slot IX in CACHE. */
508 tree
509 lto_streamer_cache_get (struct lto_streamer_cache_d *cache, int ix)
511 gcc_assert (cache);
513 /* If the reader is requesting an index beyond the length of the
514 cache, it will need to read ahead. Return NULL_TREE to indicate
515 that. */
516 if ((unsigned) ix >= VEC_length (tree, cache->nodes))
517 return NULL_TREE;
519 return VEC_index (tree, cache->nodes, (unsigned) ix);
523 /* Record NODE in COMMON_NODES if it is not NULL and is not already in
524 SEEN_NODES. */
526 static void
527 lto_record_common_node (tree *nodep, VEC(tree, heap) **common_nodes,
528 struct pointer_set_t *seen_nodes)
530 tree node = *nodep;
532 if (node == NULL_TREE)
533 return;
535 if (TYPE_P (node))
537 /* Type merging will get confused by the canonical types as they
538 are set by the middle-end. */
539 TYPE_CANONICAL (node) = NULL_TREE;
540 *nodep = node = gimple_register_type (node);
543 /* Return if node is already seen. */
544 if (pointer_set_insert (seen_nodes, node))
545 return;
547 VEC_safe_push (tree, heap, *common_nodes, node);
549 if (tree_node_can_be_shared (node))
551 if (POINTER_TYPE_P (node)
552 || TREE_CODE (node) == COMPLEX_TYPE
553 || TREE_CODE (node) == ARRAY_TYPE)
554 lto_record_common_node (&TREE_TYPE (node), common_nodes, seen_nodes);
559 /* Generate a vector of common nodes and make sure they are merged
560 properly according to the the gimple type table. */
562 static VEC(tree,heap) *
563 lto_get_common_nodes (void)
565 unsigned i;
566 VEC(tree,heap) *common_nodes = NULL;
567 struct pointer_set_t *seen_nodes;
569 /* The MAIN_IDENTIFIER_NODE is normally set up by the front-end, but the
570 LTO back-end must agree. Currently, the only languages that set this
571 use the name "main". */
572 if (main_identifier_node)
574 const char *main_name = IDENTIFIER_POINTER (main_identifier_node);
575 gcc_assert (strcmp (main_name, "main") == 0);
577 else
578 main_identifier_node = get_identifier ("main");
580 gcc_assert (ptrdiff_type_node == integer_type_node);
582 /* FIXME lto. In the C++ front-end, fileptr_type_node is defined as a
583 variant copy of of ptr_type_node, rather than ptr_node itself. The
584 distinction should only be relevant to the front-end, so we always
585 use the C definition here in lto1.
587 These should be assured in pass_ipa_free_lang_data. */
588 gcc_assert (fileptr_type_node == ptr_type_node);
589 gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
591 seen_nodes = pointer_set_create ();
593 /* Skip itk_char. char_type_node is shared with the appropriately
594 signed variant. */
595 for (i = itk_signed_char; i < itk_none; i++)
596 lto_record_common_node (&integer_types[i], &common_nodes, seen_nodes);
598 for (i = 0; i < TYPE_KIND_LAST; i++)
599 lto_record_common_node (&sizetype_tab[i], &common_nodes, seen_nodes);
601 for (i = 0; i < TI_MAX; i++)
602 lto_record_common_node (&global_trees[i], &common_nodes, seen_nodes);
604 pointer_set_destroy (seen_nodes);
606 return common_nodes;
610 /* Assign an index to tree node T and enter it in the streamer cache
611 CACHE. */
613 static void
614 preload_common_node (struct lto_streamer_cache_d *cache, tree t)
616 gcc_assert (t);
618 lto_streamer_cache_insert (cache, t, NULL, NULL);
620 /* The FIELD_DECLs of structures should be shared, so that every
621 COMPONENT_REF uses the same tree node when referencing a field.
622 Pointer equality between FIELD_DECLs is used by the alias
623 machinery to compute overlapping memory references (See
624 nonoverlapping_component_refs_p). */
625 if (TREE_CODE (t) == RECORD_TYPE)
627 tree f;
629 for (f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f))
630 preload_common_node (cache, f);
635 /* Create a cache of pickled nodes. */
637 struct lto_streamer_cache_d *
638 lto_streamer_cache_create (void)
640 struct lto_streamer_cache_d *cache;
641 VEC(tree, heap) *common_nodes;
642 unsigned i;
643 tree node;
645 cache = XCNEW (struct lto_streamer_cache_d);
647 cache->node_map = htab_create (101, tree_int_map_hash, tree_int_map_eq, NULL);
649 cache->node_map_entries = create_alloc_pool ("node map",
650 sizeof (struct tree_int_map),
651 100);
653 /* Load all the well-known tree nodes that are always created by
654 the compiler on startup. This prevents writing them out
655 unnecessarily. */
656 common_nodes = lto_get_common_nodes ();
658 for (i = 0; VEC_iterate (tree, common_nodes, i, node); i++)
659 preload_common_node (cache, node);
661 VEC_free(tree, heap, common_nodes);
663 return cache;
667 /* Delete the streamer cache C. */
669 void
670 lto_streamer_cache_delete (struct lto_streamer_cache_d *c)
672 if (c == NULL)
673 return;
675 htab_delete (c->node_map);
676 free_alloc_pool (c->node_map_entries);
677 VEC_free (tree, heap, c->nodes);
678 VEC_free (unsigned, heap, c->offsets);
679 free (c);
683 #ifdef LTO_STREAMER_DEBUG
684 static htab_t tree_htab;
686 struct tree_hash_entry
688 tree key;
689 intptr_t value;
692 static hashval_t
693 hash_tree (const void *p)
695 const struct tree_hash_entry *e = (const struct tree_hash_entry *) p;
696 return htab_hash_pointer (e->key);
699 static int
700 eq_tree (const void *p1, const void *p2)
702 const struct tree_hash_entry *e1 = (const struct tree_hash_entry *) p1;
703 const struct tree_hash_entry *e2 = (const struct tree_hash_entry *) p2;
704 return (e1->key == e2->key);
706 #endif
708 /* Initialization common to the LTO reader and writer. */
710 void
711 lto_streamer_init (void)
713 /* Check that all the TS_* handled by the reader and writer routines
714 match exactly the structures defined in treestruct.def. When a
715 new TS_* astructure is added, the streamer should be updated to
716 handle it. */
717 check_handled_ts_structures ();
719 #ifdef LTO_STREAMER_DEBUG
720 tree_htab = htab_create (31, hash_tree, eq_tree, NULL);
721 #endif
725 /* Gate function for all LTO streaming passes. */
727 bool
728 gate_lto_out (void)
730 return ((flag_generate_lto || in_lto_p)
731 /* Don't bother doing anything if the program has errors. */
732 && !seen_error ());
736 #ifdef LTO_STREAMER_DEBUG
737 /* Add a mapping between T and ORIG_T, which is the numeric value of
738 the original address of T as it was seen by the LTO writer. This
739 mapping is useful when debugging streaming problems. A debugging
740 session can be started on both reader and writer using ORIG_T
741 as a breakpoint value in both sessions.
743 Note that this mapping is transient and only valid while T is
744 being reconstructed. Once T is fully built, the mapping is
745 removed. */
747 void
748 lto_orig_address_map (tree t, intptr_t orig_t)
750 struct tree_hash_entry ent;
751 struct tree_hash_entry **slot;
753 ent.key = t;
754 ent.value = orig_t;
755 slot
756 = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, INSERT);
757 gcc_assert (!*slot);
758 *slot = XNEW (struct tree_hash_entry);
759 **slot = ent;
763 /* Get the original address of T as it was seen by the writer. This
764 is only valid while T is being reconstructed. */
766 intptr_t
767 lto_orig_address_get (tree t)
769 struct tree_hash_entry ent;
770 struct tree_hash_entry **slot;
772 ent.key = t;
773 slot
774 = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
775 return (slot ? (*slot)->value : 0);
779 /* Clear the mapping of T to its original address. */
781 void
782 lto_orig_address_remove (tree t)
784 struct tree_hash_entry ent;
785 struct tree_hash_entry **slot;
787 ent.key = t;
788 slot
789 = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
790 gcc_assert (slot);
791 free (*slot);
792 htab_clear_slot (tree_htab, (PTR *)slot);
794 #endif
797 /* Check that the version MAJOR.MINOR is the correct version number. */
799 void
800 lto_check_version (int major, int minor)
802 if (major != LTO_major_version || minor != LTO_minor_version)
803 fatal_error ("bytecode stream generated with LTO version %d.%d instead "
804 "of the expected %d.%d",
805 major, minor,
806 LTO_major_version, LTO_minor_version);