OSDN Git Service

* tree.h (struct typed_tree): New.
[pf3gnuchains/gcc-fork.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_TYPED] = true;
274   handled_p[TS_COMMON] = true;
275   handled_p[TS_INT_CST] = true;
276   handled_p[TS_REAL_CST] = true;
277   handled_p[TS_FIXED_CST] = true;
278   handled_p[TS_VECTOR] = true;
279   handled_p[TS_STRING] = true;
280   handled_p[TS_COMPLEX] = true;
281   handled_p[TS_IDENTIFIER] = true;
282   handled_p[TS_DECL_MINIMAL] = true;
283   handled_p[TS_DECL_COMMON] = true;
284   handled_p[TS_DECL_WRTL] = true;
285   handled_p[TS_DECL_NON_COMMON] = true;
286   handled_p[TS_DECL_WITH_VIS] = true;
287   handled_p[TS_FIELD_DECL] = true;
288   handled_p[TS_VAR_DECL] = true;
289   handled_p[TS_PARM_DECL] = true;
290   handled_p[TS_LABEL_DECL] = true;
291   handled_p[TS_RESULT_DECL] = true;
292   handled_p[TS_CONST_DECL] = true;
293   handled_p[TS_TYPE_DECL] = true;
294   handled_p[TS_FUNCTION_DECL] = true;
295   handled_p[TS_TYPE] = true;
296   handled_p[TS_LIST] = true;
297   handled_p[TS_VEC] = true;
298   handled_p[TS_EXP] = true;
299   handled_p[TS_SSA_NAME] = true;
300   handled_p[TS_BLOCK] = true;
301   handled_p[TS_BINFO] = true;
302   handled_p[TS_STATEMENT_LIST] = true;
303   handled_p[TS_CONSTRUCTOR] = true;
304   handled_p[TS_OMP_CLAUSE] = true;
305   handled_p[TS_OPTIMIZATION] = true;
306   handled_p[TS_TARGET_OPTION] = true;
307   handled_p[TS_TRANSLATION_UNIT_DECL] = true;
308
309   /* Anything not marked above will trigger the following assertion.
310      If this assertion triggers, it means that there is a new TS_*
311      structure that should be handled by the streamer.  */
312   for (i = 0; i < LAST_TS_ENUM; i++)
313     gcc_assert (handled_p[i]);
314 }
315
316
317 /* Helper for lto_streamer_cache_insert_1.  Add T to CACHE->NODES at
318    slot IX.  */
319
320 static void
321 lto_streamer_cache_add_to_node_array (struct lto_streamer_cache_d *cache,
322                                       unsigned ix, tree t)
323 {
324   /* Make sure we're either replacing an old element or
325      appending consecutively.  */
326   gcc_assert (ix <= VEC_length (tree, cache->nodes));
327
328   if (ix == VEC_length (tree, cache->nodes))
329     VEC_safe_push (tree, heap, cache->nodes, t);
330   else
331     VEC_replace (tree, cache->nodes, ix, t);
332 }
333
334
335 /* Helper for lto_streamer_cache_insert and lto_streamer_cache_insert_at.
336    CACHE, T, and IX_P are as in lto_streamer_cache_insert.
337
338    If INSERT_AT_NEXT_SLOT_P is true, T is inserted at the next available
339    slot in the cache.  Otherwise, T is inserted at the position indicated
340    in *IX_P.
341
342    If T already existed in CACHE, return true.  Otherwise,
343    return false.  */
344
345 static bool
346 lto_streamer_cache_insert_1 (struct lto_streamer_cache_d *cache,
347                              tree t, unsigned *ix_p,
348                              bool insert_at_next_slot_p)
349 {
350   void **slot;
351   struct tree_int_map d_entry, *entry;
352   unsigned ix;
353   bool existed_p;
354
355   gcc_assert (t);
356
357   d_entry.base.from = t;
358   slot = htab_find_slot (cache->node_map, &d_entry, INSERT);
359   if (*slot == NULL)
360     {
361       /* Determine the next slot to use in the cache.  */
362       if (insert_at_next_slot_p)
363         ix = VEC_length (tree, cache->nodes);
364       else
365         ix = *ix_p;
366
367       entry = (struct tree_int_map *)pool_alloc (cache->node_map_entries);
368       entry->base.from = t;
369       entry->to = ix;
370       *slot = entry;
371
372       lto_streamer_cache_add_to_node_array (cache, ix, t);
373
374       /* Indicate that the item was not present in the cache.  */
375       existed_p = false;
376     }
377   else
378     {
379       entry = (struct tree_int_map *) *slot;
380       ix = entry->to;
381
382       if (!insert_at_next_slot_p && ix != *ix_p)
383         {
384           /* If the caller wants to insert T at a specific slot
385              location, and ENTRY->TO does not match *IX_P, add T to
386              the requested location slot.  This situation arises when
387              streaming builtin functions.
388
389              For instance, on the writer side we could have two
390              FUNCTION_DECLS T1 and T2 that are represented by the same
391              builtin function.  The reader will only instantiate the
392              canonical builtin, but since T1 and T2 had been
393              originally stored in different cache slots (S1 and S2),
394              the reader must be able to find the canonical builtin
395              function at slots S1 and S2.  */
396           gcc_assert (lto_stream_as_builtin_p (t));
397           ix = *ix_p;
398
399           lto_streamer_cache_add_to_node_array (cache, ix, t);
400         }
401
402       /* Indicate that T was already in the cache.  */
403       existed_p = true;
404     }
405
406   if (ix_p)
407     *ix_p = ix;
408
409   return existed_p;
410 }
411
412
413 /* Insert tree node T in CACHE.  If T already existed in the cache
414    return true.  Otherwise, return false.
415
416    If IX_P is non-null, update it with the index into the cache where
417    T has been stored.  */
418
419 bool
420 lto_streamer_cache_insert (struct lto_streamer_cache_d *cache, tree t,
421                            unsigned *ix_p)
422 {
423   return lto_streamer_cache_insert_1 (cache, t, ix_p, true);
424 }
425
426
427 /* Insert tree node T in CACHE at slot IX.  If T already
428    existed in the cache return true.  Otherwise, return false.  */
429
430 bool
431 lto_streamer_cache_insert_at (struct lto_streamer_cache_d *cache,
432                               tree t, unsigned ix)
433 {
434   return lto_streamer_cache_insert_1 (cache, t, &ix, false);
435 }
436
437
438 /* Appends tree node T to CACHE, even if T already existed in it.  */
439
440 void
441 lto_streamer_cache_append (struct lto_streamer_cache_d *cache, tree t)
442 {
443   unsigned ix = VEC_length (tree, cache->nodes);
444   lto_streamer_cache_insert_1 (cache, t, &ix, false);
445 }
446
447 /* Return true if tree node T exists in CACHE, otherwise false.  If IX_P is
448    not NULL, write to *IX_P the index into the cache where T is stored
449    ((unsigned)-1 if T is not found).  */
450
451 bool
452 lto_streamer_cache_lookup (struct lto_streamer_cache_d *cache, tree t,
453                            unsigned *ix_p)
454 {
455   void **slot;
456   struct tree_int_map d_slot;
457   bool retval;
458   unsigned ix;
459
460   gcc_assert (t);
461
462   d_slot.base.from = t;
463   slot = htab_find_slot (cache->node_map, &d_slot, NO_INSERT);
464   if (slot == NULL)
465     {
466       retval = false;
467       ix = -1;
468     }
469   else
470     {
471       retval = true;
472       ix = ((struct tree_int_map *) *slot)->to;
473     }
474
475   if (ix_p)
476     *ix_p = ix;
477
478   return retval;
479 }
480
481
482 /* Return the tree node at slot IX in CACHE.  */
483
484 tree
485 lto_streamer_cache_get (struct lto_streamer_cache_d *cache, unsigned ix)
486 {
487   gcc_assert (cache);
488
489   /* Make sure we're not requesting something we don't have.  */
490   gcc_assert (ix < VEC_length (tree, cache->nodes));
491
492   return VEC_index (tree, cache->nodes, ix);
493 }
494
495
496 /* Record NODE in COMMON_NODES if it is not NULL and is not already in
497    SEEN_NODES.  */
498
499 static void
500 lto_record_common_node (tree *nodep, VEC(tree, heap) **common_nodes,
501                         struct pointer_set_t *seen_nodes)
502 {
503   tree node = *nodep;
504
505   if (node == NULL_TREE)
506     return;
507
508   if (TYPE_P (node))
509     {
510       /* Type merging will get confused by the canonical types as they
511          are set by the middle-end.  */
512       if (in_lto_p)
513         TYPE_CANONICAL (node) = NULL_TREE;
514       node = gimple_register_type (node);
515       TYPE_CANONICAL (node) = gimple_register_canonical_type (node);
516       *nodep = node;
517     }
518
519   /* Return if node is already seen.  */
520   if (pointer_set_insert (seen_nodes, node))
521     return;
522
523   VEC_safe_push (tree, heap, *common_nodes, node);
524
525   if (POINTER_TYPE_P (node)
526       || TREE_CODE (node) == COMPLEX_TYPE
527       || TREE_CODE (node) == ARRAY_TYPE)
528     lto_record_common_node (&TREE_TYPE (node), common_nodes, seen_nodes);
529 }
530
531
532 /* Generate a vector of common nodes and make sure they are merged
533    properly according to the gimple type table.  */
534
535 static VEC(tree,heap) *
536 lto_get_common_nodes (void)
537 {
538   unsigned i;
539   VEC(tree,heap) *common_nodes = NULL;
540   struct pointer_set_t *seen_nodes;
541
542   /* The MAIN_IDENTIFIER_NODE is normally set up by the front-end, but the
543      LTO back-end must agree. Currently, the only languages that set this
544      use the name "main".  */
545   if (main_identifier_node)
546     {
547       const char *main_name = IDENTIFIER_POINTER (main_identifier_node);
548       gcc_assert (strcmp (main_name, "main") == 0);
549     }
550   else
551     main_identifier_node = get_identifier ("main");
552
553   gcc_assert (ptrdiff_type_node == integer_type_node);
554
555   /* FIXME lto.  In the C++ front-end, fileptr_type_node is defined as a
556      variant copy of of ptr_type_node, rather than ptr_node itself.  The
557      distinction should only be relevant to the front-end, so we always
558      use the C definition here in lto1.
559
560      These should be assured in pass_ipa_free_lang_data.  */
561   gcc_assert (fileptr_type_node == ptr_type_node);
562   gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
563
564   seen_nodes = pointer_set_create ();
565
566   /* Skip itk_char.  char_type_node is shared with the appropriately
567      signed variant.  */
568   for (i = itk_signed_char; i < itk_none; i++)
569     lto_record_common_node (&integer_types[i], &common_nodes, seen_nodes);
570
571   for (i = 0; i < TYPE_KIND_LAST; i++)
572     lto_record_common_node (&sizetype_tab[i], &common_nodes, seen_nodes);
573
574   for (i = 0; i < TI_MAX; i++)
575     lto_record_common_node (&global_trees[i], &common_nodes, seen_nodes);
576
577   pointer_set_destroy (seen_nodes);
578
579   return common_nodes;
580 }
581
582
583 /* Assign an index to tree node T and enter it in the streamer cache
584    CACHE.  */
585
586 static void
587 preload_common_node (struct lto_streamer_cache_d *cache, tree t)
588 {
589   gcc_assert (t);
590
591   lto_streamer_cache_insert (cache, t, NULL);
592
593  /* The FIELD_DECLs of structures should be shared, so that every
594     COMPONENT_REF uses the same tree node when referencing a field.
595     Pointer equality between FIELD_DECLs is used by the alias
596     machinery to compute overlapping memory references (See
597     nonoverlapping_component_refs_p).  */
598  if (TREE_CODE (t) == RECORD_TYPE)
599    {
600      tree f;
601
602      for (f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f))
603        preload_common_node (cache, f);
604    }
605 }
606
607
608 /* Create a cache of pickled nodes.  */
609
610 struct lto_streamer_cache_d *
611 lto_streamer_cache_create (void)
612 {
613   struct lto_streamer_cache_d *cache;
614   VEC(tree, heap) *common_nodes;
615   unsigned i;
616   tree node;
617
618   cache = XCNEW (struct lto_streamer_cache_d);
619
620   cache->node_map = htab_create (101, tree_int_map_hash, tree_int_map_eq, NULL);
621
622   cache->node_map_entries = create_alloc_pool ("node map",
623                                                sizeof (struct tree_int_map),
624                                                100);
625
626   /* Load all the well-known tree nodes that are always created by
627      the compiler on startup.  This prevents writing them out
628      unnecessarily.  */
629   common_nodes = lto_get_common_nodes ();
630
631   FOR_EACH_VEC_ELT (tree, common_nodes, i, node)
632     preload_common_node (cache, node);
633
634   VEC_free(tree, heap, common_nodes);
635
636   return cache;
637 }
638
639
640 /* Delete the streamer cache C.  */
641
642 void
643 lto_streamer_cache_delete (struct lto_streamer_cache_d *c)
644 {
645   if (c == NULL)
646     return;
647
648   htab_delete (c->node_map);
649   free_alloc_pool (c->node_map_entries);
650   VEC_free (tree, heap, c->nodes);
651   free (c);
652 }
653
654
655 #ifdef LTO_STREAMER_DEBUG
656 static htab_t tree_htab;
657
658 struct tree_hash_entry
659 {
660   tree key;
661   intptr_t value;
662 };
663
664 static hashval_t
665 hash_tree (const void *p)
666 {
667   const struct tree_hash_entry *e = (const struct tree_hash_entry *) p;
668   return htab_hash_pointer (e->key);
669 }
670
671 static int
672 eq_tree (const void *p1, const void *p2)
673 {
674   const struct tree_hash_entry *e1 = (const struct tree_hash_entry *) p1;
675   const struct tree_hash_entry *e2 = (const struct tree_hash_entry *) p2;
676   return (e1->key == e2->key);
677 }
678 #endif
679
680 /* Initialization common to the LTO reader and writer.  */
681
682 void
683 lto_streamer_init (void)
684 {
685   /* Check that all the TS_* handled by the reader and writer routines
686      match exactly the structures defined in treestruct.def.  When a
687      new TS_* astructure is added, the streamer should be updated to
688      handle it.  */
689   check_handled_ts_structures ();
690
691 #ifdef LTO_STREAMER_DEBUG
692   tree_htab = htab_create (31, hash_tree, eq_tree, NULL);
693 #endif
694 }
695
696
697 /* Gate function for all LTO streaming passes.  */
698
699 bool
700 gate_lto_out (void)
701 {
702   return ((flag_generate_lto || in_lto_p)
703           /* Don't bother doing anything if the program has errors.  */
704           && !seen_error ());
705 }
706
707
708 #ifdef LTO_STREAMER_DEBUG
709 /* Add a mapping between T and ORIG_T, which is the numeric value of
710    the original address of T as it was seen by the LTO writer.  This
711    mapping is useful when debugging streaming problems.  A debugging
712    session can be started on both reader and writer using ORIG_T
713    as a breakpoint value in both sessions.
714
715    Note that this mapping is transient and only valid while T is
716    being reconstructed.  Once T is fully built, the mapping is
717    removed.  */
718
719 void
720 lto_orig_address_map (tree t, intptr_t orig_t)
721 {
722   struct tree_hash_entry ent;
723   struct tree_hash_entry **slot;
724
725   ent.key = t;
726   ent.value = orig_t;
727   slot
728     = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, INSERT);
729   gcc_assert (!*slot);
730   *slot = XNEW (struct tree_hash_entry);
731   **slot = ent;
732 }
733
734
735 /* Get the original address of T as it was seen by the writer.  This
736    is only valid while T is being reconstructed.  */
737
738 intptr_t
739 lto_orig_address_get (tree t)
740 {
741   struct tree_hash_entry ent;
742   struct tree_hash_entry **slot;
743
744   ent.key = t;
745   slot
746     = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
747   return (slot ? (*slot)->value : 0);
748 }
749
750
751 /* Clear the mapping of T to its original address.  */
752
753 void
754 lto_orig_address_remove (tree t)
755 {
756   struct tree_hash_entry ent;
757   struct tree_hash_entry **slot;
758
759   ent.key = t;
760   slot
761     = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
762   gcc_assert (slot);
763   free (*slot);
764   htab_clear_slot (tree_htab, (PTR *)slot);
765 }
766 #endif
767
768
769 /* Check that the version MAJOR.MINOR is the correct version number.  */
770
771 void
772 lto_check_version (int major, int minor)
773 {
774   if (major != LTO_major_version || minor != LTO_minor_version)
775     fatal_error ("bytecode stream generated with LTO version %d.%d instead "
776                  "of the expected %d.%d",
777                  major, minor,
778                  LTO_major_version, LTO_minor_version);
779 }