OSDN Git Service

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