]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/lto-streamer.c
Remove doubled up words.
[thirdparty/gcc.git] / gcc / lto-streamer.c
1 /* Miscellaneous utilities for GIMPLE streaming. Things that are used
2 in both input and output are here.
3
4 Copyright 2009, 2010 Free Software Foundation, Inc.
5 Contributed by Doug Kwan <dougkwan@google.com>
6
7 This file is part of GCC.
8
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.
13
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.
18
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/>. */
22
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"
36
37 /* Statistics gathered during LTO, WPA and LTRANS. */
38 struct lto_stats_d lto_stats;
39
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;
44
45
46 /* Return a string representing LTO tag TAG. */
47
48 const char *
49 lto_tag_name (enum LTO_tags tag)
50 {
51 if (lto_tag_is_tree_code_p (tag))
52 {
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)];
56 }
57
58 if (lto_tag_is_gimple_code_p (tag))
59 {
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)];
63 }
64
65 switch (tag)
66 {
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";
109 }
110 }
111
112
113 /* Allocate a bitmap from heap. Initializes the LTO obstack if necessary. */
114
115 bitmap
116 lto_bitmap_alloc (void)
117 {
118 if (!lto_obstack_initialized)
119 {
120 bitmap_obstack_initialize (&lto_obstack);
121 lto_obstack_initialized = true;
122 }
123 return BITMAP_ALLOC (&lto_obstack);
124 }
125
126 /* Free bitmap B. */
127
128 void
129 lto_bitmap_free (bitmap b)
130 {
131 BITMAP_FREE (b);
132 }
133
134
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. */
139
140 char *
141 lto_get_section_name (int section_type, const char *name, struct lto_file_decl_data *f)
142 {
143 const char *add;
144 char post[32];
145 const char *sep;
146
147 if (section_type == LTO_section_function_body)
148 {
149 gcc_assert (name != NULL);
150 if (name[0] == '*')
151 name++;
152 add = name;
153 sep = "";
154 }
155 else if (section_type < LTO_N_SECTION_TYPES)
156 {
157 add = lto_section_name[section_type];
158 sep = ".";
159 }
160 else
161 internal_error ("bytecode stream: unexpected LTO section %s", name);
162
163 /* Make the section name unique so that ld -r combining sections
164 doesn't confuse the reader with merged sections.
165
166 For options don't add a ID, the option reader cannot deal with them
167 and merging should be ok here.
168
169 XXX: use crc64 to minimize collisions? */
170 if (section_type == LTO_section_opts)
171 strcpy (post, "");
172 else
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);
175 }
176
177
178 /* Show various memory usage statistics related to LTO. */
179
180 void
181 print_lto_report (void)
182 {
183 const char *s = (flag_lto) ? "LTO" : (flag_wpa) ? "WPA" : "LTRANS";
184 unsigned i;
185
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);
189
190 fprintf (stderr, "[%s] # of input cgraph nodes: "
191 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
192 lto_stats.num_input_cgraph_nodes);
193
194 fprintf (stderr, "[%s] # of function bodies: "
195 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
196 lto_stats.num_function_bodies);
197
198 fprintf (stderr, "[%s] ", s);
199 print_gimple_types_stats ();
200
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]);
206
207 if (flag_lto)
208 {
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)
215 {
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);
219 }
220 fprintf (stderr, "\n");
221 }
222
223 if (flag_wpa)
224 {
225 fprintf (stderr, "[%s] # of output files: "
226 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
227 lto_stats.num_output_files);
228
229 fprintf (stderr, "[%s] # of output cgraph nodes: "
230 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
231 lto_stats.num_output_cgraph_nodes);
232
233 fprintf (stderr, "[%s] # callgraph partitions: "
234 HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
235 lto_stats.num_cgraph_partitions);
236
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)
243 {
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);
247 }
248 fprintf (stderr, "\n");
249 }
250
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]);
255 }
256
257
258 /* Check that all the TS_* structures handled by the lto_output_* and
259 lto_input_* routines are exactly ALL the structures defined in
260 treestruct.def. */
261
262 static void
263 check_handled_ts_structures (void)
264 {
265 bool handled_p[LAST_TS_ENUM];
266 unsigned i;
267
268 memset (&handled_p, 0, sizeof (handled_p));
269
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;
307
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]);
313 }
314
315
316 /* Helper for lto_streamer_cache_insert_1. Add T to CACHE->NODES at
317 slot IX. */
318
319 static void
320 lto_streamer_cache_add_to_node_array (struct lto_streamer_cache_d *cache,
321 unsigned ix, tree t)
322 {
323 /* Make sure we're either replacing an old element or
324 appending consecutively. */
325 gcc_assert (ix <= VEC_length (tree, cache->nodes));
326
327 if (ix == VEC_length (tree, cache->nodes))
328 VEC_safe_push (tree, heap, cache->nodes, t);
329 else
330 VEC_replace (tree, cache->nodes, ix, t);
331 }
332
333
334 /* Helper for lto_streamer_cache_insert and lto_streamer_cache_insert_at.
335 CACHE, T, and IX_P are as in lto_streamer_cache_insert.
336
337 If INSERT_AT_NEXT_SLOT_P is true, T is inserted at the next available
338 slot in the cache. Otherwise, T is inserted at the position indicated
339 in *IX_P.
340
341 If T already existed in CACHE, return true. Otherwise,
342 return false. */
343
344 static bool
345 lto_streamer_cache_insert_1 (struct lto_streamer_cache_d *cache,
346 tree t, unsigned *ix_p,
347 bool insert_at_next_slot_p)
348 {
349 void **slot;
350 struct tree_int_map d_entry, *entry;
351 unsigned ix;
352 bool existed_p;
353
354 gcc_assert (t);
355
356 d_entry.base.from = t;
357 slot = htab_find_slot (cache->node_map, &d_entry, INSERT);
358 if (*slot == NULL)
359 {
360 /* Determine the next slot to use in the cache. */
361 if (insert_at_next_slot_p)
362 ix = VEC_length (tree, cache->nodes);
363 else
364 ix = *ix_p;
365
366 entry = (struct tree_int_map *)pool_alloc (cache->node_map_entries);
367 entry->base.from = t;
368 entry->to = ix;
369 *slot = entry;
370
371 lto_streamer_cache_add_to_node_array (cache, ix, t);
372
373 /* Indicate that the item was not present in the cache. */
374 existed_p = false;
375 }
376 else
377 {
378 entry = (struct tree_int_map *) *slot;
379 ix = entry->to;
380
381 if (!insert_at_next_slot_p && ix != *ix_p)
382 {
383 /* If the caller wants to insert T at a specific slot
384 location, and ENTRY->TO does not match *IX_P, add T to
385 the requested location slot. This situation arises when
386 streaming builtin functions.
387
388 For instance, on the writer side we could have two
389 FUNCTION_DECLS T1 and T2 that are represented by the same
390 builtin function. The reader will only instantiate the
391 canonical builtin, but since T1 and T2 had been
392 originally stored in different cache slots (S1 and S2),
393 the reader must be able to find the canonical builtin
394 function at slots S1 and S2. */
395 gcc_assert (lto_stream_as_builtin_p (t));
396 ix = *ix_p;
397
398 lto_streamer_cache_add_to_node_array (cache, ix, t);
399 }
400
401 /* Indicate that T was already in the cache. */
402 existed_p = true;
403 }
404
405 if (ix_p)
406 *ix_p = ix;
407
408 return existed_p;
409 }
410
411
412 /* Insert tree node T in CACHE. If T already existed in the cache
413 return true. Otherwise, return false.
414
415 If IX_P is non-null, update it with the index into the cache where
416 T has been stored. */
417
418 bool
419 lto_streamer_cache_insert (struct lto_streamer_cache_d *cache, tree t,
420 unsigned *ix_p)
421 {
422 return lto_streamer_cache_insert_1 (cache, t, ix_p, true);
423 }
424
425
426 /* Insert tree node T in CACHE at slot IX. If T already
427 existed in the cache return true. Otherwise, return false. */
428
429 bool
430 lto_streamer_cache_insert_at (struct lto_streamer_cache_d *cache,
431 tree t, unsigned ix)
432 {
433 return lto_streamer_cache_insert_1 (cache, t, &ix, false);
434 }
435
436
437 /* Appends tree node T to CACHE, even if T already existed in it. */
438
439 void
440 lto_streamer_cache_append (struct lto_streamer_cache_d *cache, tree t)
441 {
442 unsigned ix = VEC_length (tree, cache->nodes);
443 lto_streamer_cache_insert_1 (cache, t, &ix, false);
444 }
445
446 /* Return true if tree node T exists in CACHE, otherwise false. If IX_P is
447 not NULL, write to *IX_P the index into the cache where T is stored
448 ((unsigned)-1 if T is not found). */
449
450 bool
451 lto_streamer_cache_lookup (struct lto_streamer_cache_d *cache, tree t,
452 unsigned *ix_p)
453 {
454 void **slot;
455 struct tree_int_map d_slot;
456 bool retval;
457 unsigned ix;
458
459 gcc_assert (t);
460
461 d_slot.base.from = t;
462 slot = htab_find_slot (cache->node_map, &d_slot, NO_INSERT);
463 if (slot == NULL)
464 {
465 retval = false;
466 ix = -1;
467 }
468 else
469 {
470 retval = true;
471 ix = ((struct tree_int_map *) *slot)->to;
472 }
473
474 if (ix_p)
475 *ix_p = ix;
476
477 return retval;
478 }
479
480
481 /* Return the tree node at slot IX in CACHE. */
482
483 tree
484 lto_streamer_cache_get (struct lto_streamer_cache_d *cache, unsigned ix)
485 {
486 gcc_assert (cache);
487
488 /* Make sure we're not requesting something we don't have. */
489 gcc_assert (ix < VEC_length (tree, cache->nodes));
490
491 return VEC_index (tree, cache->nodes, ix);
492 }
493
494
495 /* Record NODE in COMMON_NODES if it is not NULL and is not already in
496 SEEN_NODES. */
497
498 static void
499 lto_record_common_node (tree *nodep, VEC(tree, heap) **common_nodes,
500 struct pointer_set_t *seen_nodes)
501 {
502 tree node = *nodep;
503
504 if (node == NULL_TREE)
505 return;
506
507 if (TYPE_P (node))
508 {
509 /* Type merging will get confused by the canonical types as they
510 are set by the middle-end. */
511 if (in_lto_p)
512 TYPE_CANONICAL (node) = NULL_TREE;
513 node = gimple_register_type (node);
514 TYPE_CANONICAL (node) = gimple_register_canonical_type (node);
515 *nodep = node;
516 }
517
518 /* Return if node is already seen. */
519 if (pointer_set_insert (seen_nodes, node))
520 return;
521
522 VEC_safe_push (tree, heap, *common_nodes, node);
523
524 if (POINTER_TYPE_P (node)
525 || TREE_CODE (node) == COMPLEX_TYPE
526 || TREE_CODE (node) == ARRAY_TYPE)
527 lto_record_common_node (&TREE_TYPE (node), common_nodes, seen_nodes);
528 }
529
530
531 /* Generate a vector of common nodes and make sure they are merged
532 properly according to the gimple type table. */
533
534 static VEC(tree,heap) *
535 lto_get_common_nodes (void)
536 {
537 unsigned i;
538 VEC(tree,heap) *common_nodes = NULL;
539 struct pointer_set_t *seen_nodes;
540
541 /* The MAIN_IDENTIFIER_NODE is normally set up by the front-end, but the
542 LTO back-end must agree. Currently, the only languages that set this
543 use the name "main". */
544 if (main_identifier_node)
545 {
546 const char *main_name = IDENTIFIER_POINTER (main_identifier_node);
547 gcc_assert (strcmp (main_name, "main") == 0);
548 }
549 else
550 main_identifier_node = get_identifier ("main");
551
552 gcc_assert (ptrdiff_type_node == integer_type_node);
553
554 /* FIXME lto. In the C++ front-end, fileptr_type_node is defined as a
555 variant copy of of ptr_type_node, rather than ptr_node itself. The
556 distinction should only be relevant to the front-end, so we always
557 use the C definition here in lto1.
558
559 These should be assured in pass_ipa_free_lang_data. */
560 gcc_assert (fileptr_type_node == ptr_type_node);
561 gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
562
563 seen_nodes = pointer_set_create ();
564
565 /* Skip itk_char. char_type_node is shared with the appropriately
566 signed variant. */
567 for (i = itk_signed_char; i < itk_none; i++)
568 lto_record_common_node (&integer_types[i], &common_nodes, seen_nodes);
569
570 for (i = 0; i < TYPE_KIND_LAST; i++)
571 lto_record_common_node (&sizetype_tab[i], &common_nodes, seen_nodes);
572
573 for (i = 0; i < TI_MAX; i++)
574 lto_record_common_node (&global_trees[i], &common_nodes, seen_nodes);
575
576 pointer_set_destroy (seen_nodes);
577
578 return common_nodes;
579 }
580
581
582 /* Assign an index to tree node T and enter it in the streamer cache
583 CACHE. */
584
585 static void
586 preload_common_node (struct lto_streamer_cache_d *cache, tree t)
587 {
588 gcc_assert (t);
589
590 lto_streamer_cache_insert (cache, t, NULL);
591
592 /* The FIELD_DECLs of structures should be shared, so that every
593 COMPONENT_REF uses the same tree node when referencing a field.
594 Pointer equality between FIELD_DECLs is used by the alias
595 machinery to compute overlapping memory references (See
596 nonoverlapping_component_refs_p). */
597 if (TREE_CODE (t) == RECORD_TYPE)
598 {
599 tree f;
600
601 for (f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f))
602 preload_common_node (cache, f);
603 }
604 }
605
606
607 /* Create a cache of pickled nodes. */
608
609 struct lto_streamer_cache_d *
610 lto_streamer_cache_create (void)
611 {
612 struct lto_streamer_cache_d *cache;
613 VEC(tree, heap) *common_nodes;
614 unsigned i;
615 tree node;
616
617 cache = XCNEW (struct lto_streamer_cache_d);
618
619 cache->node_map = htab_create (101, tree_int_map_hash, tree_int_map_eq, NULL);
620
621 cache->node_map_entries = create_alloc_pool ("node map",
622 sizeof (struct tree_int_map),
623 100);
624
625 /* Load all the well-known tree nodes that are always created by
626 the compiler on startup. This prevents writing them out
627 unnecessarily. */
628 common_nodes = lto_get_common_nodes ();
629
630 FOR_EACH_VEC_ELT (tree, common_nodes, i, node)
631 preload_common_node (cache, node);
632
633 VEC_free(tree, heap, common_nodes);
634
635 return cache;
636 }
637
638
639 /* Delete the streamer cache C. */
640
641 void
642 lto_streamer_cache_delete (struct lto_streamer_cache_d *c)
643 {
644 if (c == NULL)
645 return;
646
647 htab_delete (c->node_map);
648 free_alloc_pool (c->node_map_entries);
649 VEC_free (tree, heap, c->nodes);
650 free (c);
651 }
652
653
654 #ifdef LTO_STREAMER_DEBUG
655 static htab_t tree_htab;
656
657 struct tree_hash_entry
658 {
659 tree key;
660 intptr_t value;
661 };
662
663 static hashval_t
664 hash_tree (const void *p)
665 {
666 const struct tree_hash_entry *e = (const struct tree_hash_entry *) p;
667 return htab_hash_pointer (e->key);
668 }
669
670 static int
671 eq_tree (const void *p1, const void *p2)
672 {
673 const struct tree_hash_entry *e1 = (const struct tree_hash_entry *) p1;
674 const struct tree_hash_entry *e2 = (const struct tree_hash_entry *) p2;
675 return (e1->key == e2->key);
676 }
677 #endif
678
679 /* Initialization common to the LTO reader and writer. */
680
681 void
682 lto_streamer_init (void)
683 {
684 /* Check that all the TS_* handled by the reader and writer routines
685 match exactly the structures defined in treestruct.def. When a
686 new TS_* astructure is added, the streamer should be updated to
687 handle it. */
688 check_handled_ts_structures ();
689
690 #ifdef LTO_STREAMER_DEBUG
691 tree_htab = htab_create (31, hash_tree, eq_tree, NULL);
692 #endif
693 }
694
695
696 /* Gate function for all LTO streaming passes. */
697
698 bool
699 gate_lto_out (void)
700 {
701 return ((flag_generate_lto || in_lto_p)
702 /* Don't bother doing anything if the program has errors. */
703 && !seen_error ());
704 }
705
706
707 #ifdef LTO_STREAMER_DEBUG
708 /* Add a mapping between T and ORIG_T, which is the numeric value of
709 the original address of T as it was seen by the LTO writer. This
710 mapping is useful when debugging streaming problems. A debugging
711 session can be started on both reader and writer using ORIG_T
712 as a breakpoint value in both sessions.
713
714 Note that this mapping is transient and only valid while T is
715 being reconstructed. Once T is fully built, the mapping is
716 removed. */
717
718 void
719 lto_orig_address_map (tree t, intptr_t orig_t)
720 {
721 struct tree_hash_entry ent;
722 struct tree_hash_entry **slot;
723
724 ent.key = t;
725 ent.value = orig_t;
726 slot
727 = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, INSERT);
728 gcc_assert (!*slot);
729 *slot = XNEW (struct tree_hash_entry);
730 **slot = ent;
731 }
732
733
734 /* Get the original address of T as it was seen by the writer. This
735 is only valid while T is being reconstructed. */
736
737 intptr_t
738 lto_orig_address_get (tree t)
739 {
740 struct tree_hash_entry ent;
741 struct tree_hash_entry **slot;
742
743 ent.key = t;
744 slot
745 = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
746 return (slot ? (*slot)->value : 0);
747 }
748
749
750 /* Clear the mapping of T to its original address. */
751
752 void
753 lto_orig_address_remove (tree t)
754 {
755 struct tree_hash_entry ent;
756 struct tree_hash_entry **slot;
757
758 ent.key = t;
759 slot
760 = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
761 gcc_assert (slot);
762 free (*slot);
763 htab_clear_slot (tree_htab, (PTR *)slot);
764 }
765 #endif
766
767
768 /* Check that the version MAJOR.MINOR is the correct version number. */
769
770 void
771 lto_check_version (int major, int minor)
772 {
773 if (major != LTO_major_version || minor != LTO_minor_version)
774 fatal_error ("bytecode stream generated with LTO version %d.%d instead "
775 "of the expected %d.%d",
776 major, minor,
777 LTO_major_version, LTO_minor_version);
778 }