OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [lto-streamer.c] - Blame information for rev 717

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 684 jeremybenn
/* 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 "tree-streamer.h"
36
#include "lto-streamer.h"
37
#include "streamer-hooks.h"
38
 
39
/* Statistics gathered during LTO, WPA and LTRANS.  */
40
struct lto_stats_d lto_stats;
41
 
42
/* LTO uses bitmaps with different life-times.  So use a seperate
43
   obstack for all LTO bitmaps.  */
44
static bitmap_obstack lto_obstack;
45
static bool lto_obstack_initialized;
46
 
47
 
48
/* Return a string representing LTO tag TAG.  */
49
 
50
const char *
51
lto_tag_name (enum LTO_tags tag)
52
{
53
  if (lto_tag_is_tree_code_p (tag))
54
    {
55
      /* For tags representing tree nodes, return the name of the
56
         associated tree code.  */
57
      return tree_code_name[lto_tag_to_tree_code (tag)];
58
    }
59
 
60
  if (lto_tag_is_gimple_code_p (tag))
61
    {
62
      /* For tags representing gimple statements, return the name of
63
         the associated gimple code.  */
64
      return gimple_code_name[lto_tag_to_gimple_code (tag)];
65
    }
66
 
67
  switch (tag)
68
    {
69
    case LTO_null:
70
      return "LTO_null";
71
    case LTO_bb0:
72
      return "LTO_bb0";
73
    case LTO_bb1:
74
      return "LTO_bb1";
75
    case LTO_eh_region:
76
      return "LTO_eh_region";
77
    case LTO_function:
78
      return "LTO_function";
79
    case LTO_eh_table:
80
      return "LTO_eh_table";
81
    case LTO_ert_cleanup:
82
      return "LTO_ert_cleanup";
83
    case LTO_ert_try:
84
      return "LTO_ert_try";
85
    case LTO_ert_allowed_exceptions:
86
      return "LTO_ert_allowed_exceptions";
87
    case LTO_ert_must_not_throw:
88
      return "LTO_ert_must_not_throw";
89
    case LTO_tree_pickle_reference:
90
      return "LTO_tree_pickle_reference";
91
    case LTO_field_decl_ref:
92
      return "LTO_field_decl_ref";
93
    case LTO_function_decl_ref:
94
      return "LTO_function_decl_ref";
95
    case LTO_label_decl_ref:
96
      return "LTO_label_decl_ref";
97
    case LTO_namespace_decl_ref:
98
      return "LTO_namespace_decl_ref";
99
    case LTO_result_decl_ref:
100
      return "LTO_result_decl_ref";
101
    case LTO_ssa_name_ref:
102
      return "LTO_ssa_name_ref";
103
    case LTO_type_decl_ref:
104
      return "LTO_type_decl_ref";
105
    case LTO_type_ref:
106
      return "LTO_type_ref";
107
    case LTO_global_decl_ref:
108
      return "LTO_global_decl_ref";
109
    default:
110
      return "LTO_UNKNOWN";
111
    }
112
}
113
 
114
 
115
/* Allocate a bitmap from heap.  Initializes the LTO obstack if necessary.  */
116
 
117
bitmap
118
lto_bitmap_alloc (void)
119
{
120
  if (!lto_obstack_initialized)
121
    {
122
      bitmap_obstack_initialize (&lto_obstack);
123
      lto_obstack_initialized = true;
124
    }
125
  return BITMAP_ALLOC (&lto_obstack);
126
}
127
 
128
/* Free bitmap B.  */
129
 
130
void
131
lto_bitmap_free (bitmap b)
132
{
133
  BITMAP_FREE (b);
134
}
135
 
136
 
137
/* Get a section name for a particular type or name.  The NAME field
138
   is only used if SECTION_TYPE is LTO_section_function_body. For all
139
   others it is ignored.  The callee of this function is responsible
140
   to free the returned name.  */
141
 
142
char *
143
lto_get_section_name (int section_type, const char *name, struct lto_file_decl_data *f)
144
{
145
  const char *add;
146
  char post[32];
147
  const char *sep;
148
 
149
  if (section_type == LTO_section_function_body)
150
    {
151
      gcc_assert (name != NULL);
152
      if (name[0] == '*')
153
        name++;
154
      add = name;
155
      sep = "";
156
    }
157
  else if (section_type < LTO_N_SECTION_TYPES)
158
    {
159
      add = lto_section_name[section_type];
160
      sep = ".";
161
    }
162
  else
163
    internal_error ("bytecode stream: unexpected LTO section %s", name);
164
 
165
  /* Make the section name unique so that ld -r combining sections
166
     doesn't confuse the reader with merged sections.
167
 
168
     For options don't add a ID, the option reader cannot deal with them
169
     and merging should be ok here. */
170
  if (section_type == LTO_section_opts)
171
    strcpy (post, "");
172
  else if (f != NULL)
173
    sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, f->id);
174
  else
175
    sprintf (post, "." HOST_WIDE_INT_PRINT_HEX_PURE, get_random_seed (false));
176
  return concat (LTO_SECTION_NAME_PREFIX, sep, add, post, NULL);
177
}
178
 
179
 
180
/* Show various memory usage statistics related to LTO.  */
181
 
182
void
183
print_lto_report (void)
184
{
185
  const char *s = (flag_lto) ? "LTO" : (flag_wpa) ? "WPA" : "LTRANS";
186
  unsigned i;
187
 
188
  fprintf (stderr, "%s statistics\n", s);
189
  fprintf (stderr, "[%s] # of input files: "
190
           HOST_WIDE_INT_PRINT_UNSIGNED "\n", s, lto_stats.num_input_files);
191
 
192
  fprintf (stderr, "[%s] # of input cgraph nodes: "
193
           HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
194
           lto_stats.num_input_cgraph_nodes);
195
 
196
  fprintf (stderr, "[%s] # of function bodies: "
197
           HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
198
           lto_stats.num_function_bodies);
199
 
200
  fprintf (stderr, "[%s] ", s);
201
  print_gimple_types_stats ();
202
 
203
  for (i = 0; i < NUM_TREE_CODES; i++)
204
    if (lto_stats.num_trees[i])
205
      fprintf (stderr, "[%s] # of '%s' objects read: "
206
               HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
207
               tree_code_name[i], lto_stats.num_trees[i]);
208
 
209
  if (flag_lto)
210
    {
211
      fprintf (stderr, "[%s] Compression: "
212
               HOST_WIDE_INT_PRINT_UNSIGNED " output bytes, "
213
               HOST_WIDE_INT_PRINT_UNSIGNED " compressed bytes", s,
214
               lto_stats.num_output_il_bytes,
215
               lto_stats.num_compressed_il_bytes);
216
      if (lto_stats.num_output_il_bytes > 0)
217
        {
218
          const float dividend = (float) lto_stats.num_compressed_il_bytes;
219
          const float divisor = (float) lto_stats.num_output_il_bytes;
220
          fprintf (stderr, " (ratio: %f)", dividend / divisor);
221
        }
222
      fprintf (stderr, "\n");
223
    }
224
 
225
  if (flag_wpa)
226
    {
227
      fprintf (stderr, "[%s] # of output files: "
228
               HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
229
               lto_stats.num_output_files);
230
 
231
      fprintf (stderr, "[%s] # of output cgraph nodes: "
232
               HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
233
               lto_stats.num_output_cgraph_nodes);
234
 
235
      fprintf (stderr, "[%s] # callgraph partitions: "
236
               HOST_WIDE_INT_PRINT_UNSIGNED "\n", s,
237
               lto_stats.num_cgraph_partitions);
238
 
239
      fprintf (stderr, "[%s] Compression: "
240
               HOST_WIDE_INT_PRINT_UNSIGNED " input bytes, "
241
               HOST_WIDE_INT_PRINT_UNSIGNED " uncompressed bytes", s,
242
               lto_stats.num_input_il_bytes,
243
               lto_stats.num_uncompressed_il_bytes);
244
      if (lto_stats.num_input_il_bytes > 0)
245
        {
246
          const float dividend = (float) lto_stats.num_uncompressed_il_bytes;
247
          const float divisor = (float) lto_stats.num_input_il_bytes;
248
          fprintf (stderr, " (ratio: %f)", dividend / divisor);
249
        }
250
      fprintf (stderr, "\n");
251
    }
252
 
253
  for (i = 0; i < LTO_N_SECTION_TYPES; i++)
254
    fprintf (stderr, "[%s] Size of mmap'd section %s: "
255
             HOST_WIDE_INT_PRINT_UNSIGNED " bytes\n", s,
256
             lto_section_name[i], lto_stats.section_size[i]);
257
}
258
 
259
 
260
#ifdef LTO_STREAMER_DEBUG
261
static htab_t tree_htab;
262
 
263
struct tree_hash_entry
264
{
265
  tree key;
266
  intptr_t value;
267
};
268
 
269
static hashval_t
270
hash_tree (const void *p)
271
{
272
  const struct tree_hash_entry *e = (const struct tree_hash_entry *) p;
273
  return htab_hash_pointer (e->key);
274
}
275
 
276
static int
277
eq_tree (const void *p1, const void *p2)
278
{
279
  const struct tree_hash_entry *e1 = (const struct tree_hash_entry *) p1;
280
  const struct tree_hash_entry *e2 = (const struct tree_hash_entry *) p2;
281
  return (e1->key == e2->key);
282
}
283
#endif
284
 
285
/* Initialization common to the LTO reader and writer.  */
286
 
287
void
288
lto_streamer_init (void)
289
{
290
  /* Check that all the TS_* handled by the reader and writer routines
291
     match exactly the structures defined in treestruct.def.  When a
292
     new TS_* astructure is added, the streamer should be updated to
293
     handle it.  */
294
  streamer_check_handled_ts_structures ();
295
 
296
#ifdef LTO_STREAMER_DEBUG
297
  tree_htab = htab_create (31, hash_tree, eq_tree, NULL);
298
#endif
299
}
300
 
301
 
302
/* Gate function for all LTO streaming passes.  */
303
 
304
bool
305
gate_lto_out (void)
306
{
307
  return ((flag_generate_lto || in_lto_p)
308
          /* Don't bother doing anything if the program has errors.  */
309
          && !seen_error ());
310
}
311
 
312
 
313
#ifdef LTO_STREAMER_DEBUG
314
/* Add a mapping between T and ORIG_T, which is the numeric value of
315
   the original address of T as it was seen by the LTO writer.  This
316
   mapping is useful when debugging streaming problems.  A debugging
317
   session can be started on both reader and writer using ORIG_T
318
   as a breakpoint value in both sessions.
319
 
320
   Note that this mapping is transient and only valid while T is
321
   being reconstructed.  Once T is fully built, the mapping is
322
   removed.  */
323
 
324
void
325
lto_orig_address_map (tree t, intptr_t orig_t)
326
{
327
  struct tree_hash_entry ent;
328
  struct tree_hash_entry **slot;
329
 
330
  ent.key = t;
331
  ent.value = orig_t;
332
  slot
333
    = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, INSERT);
334
  gcc_assert (!*slot);
335
  *slot = XNEW (struct tree_hash_entry);
336
  **slot = ent;
337
}
338
 
339
 
340
/* Get the original address of T as it was seen by the writer.  This
341
   is only valid while T is being reconstructed.  */
342
 
343
intptr_t
344
lto_orig_address_get (tree t)
345
{
346
  struct tree_hash_entry ent;
347
  struct tree_hash_entry **slot;
348
 
349
  ent.key = t;
350
  slot
351
    = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
352
  return (slot ? (*slot)->value : 0);
353
}
354
 
355
 
356
/* Clear the mapping of T to its original address.  */
357
 
358
void
359
lto_orig_address_remove (tree t)
360
{
361
  struct tree_hash_entry ent;
362
  struct tree_hash_entry **slot;
363
 
364
  ent.key = t;
365
  slot
366
    = (struct tree_hash_entry **) htab_find_slot (tree_htab, &ent, NO_INSERT);
367
  gcc_assert (slot);
368
  free (*slot);
369
  htab_clear_slot (tree_htab, (PTR *)slot);
370
}
371
#endif
372
 
373
 
374
/* Check that the version MAJOR.MINOR is the correct version number.  */
375
 
376
void
377
lto_check_version (int major, int minor)
378
{
379
  if (major != LTO_major_version || minor != LTO_minor_version)
380
    fatal_error ("bytecode stream generated with LTO version %d.%d instead "
381
                 "of the expected %d.%d",
382
                 major, minor,
383
                 LTO_major_version, LTO_minor_version);
384
}
385
 
386
 
387
/* Initialize all the streamer hooks used for streaming GIMPLE.  */
388
 
389
void
390
lto_streamer_hooks_init (void)
391
{
392
  streamer_hooks_init ();
393
  streamer_hooks.write_tree = lto_output_tree;
394
  streamer_hooks.read_tree = lto_input_tree;
395
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.