OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [lto-cgraph.c] - Blame information for rev 340

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

Line No. Rev Author Line
1 280 jeremybenn
/* Write and read the cgraph to the memory mapped representation of a
2
   .o file.
3
 
4
   Copyright 2009 Free Software Foundation, Inc.
5
   Contributed by Kenneth Zadeck <zadeck@naturalbridge.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 "tree.h"
29
#include "expr.h"
30
#include "flags.h"
31
#include "params.h"
32
#include "input.h"
33
#include "varray.h"
34
#include "hashtab.h"
35
#include "langhooks.h"
36
#include "basic-block.h"
37
#include "tree-flow.h"
38
#include "cgraph.h"
39
#include "function.h"
40
#include "ggc.h"
41
#include "diagnostic.h"
42
#include "except.h"
43
#include "vec.h"
44
#include "timevar.h"
45
#include "output.h"
46
#include "pointer-set.h"
47
#include "lto-streamer.h"
48
#include "gcov-io.h"
49
 
50
/* Create a new cgraph encoder.  */
51
 
52
lto_cgraph_encoder_t
53
lto_cgraph_encoder_new (void)
54
{
55
  lto_cgraph_encoder_t encoder = XCNEW (struct lto_cgraph_encoder_d);
56
  encoder->map = pointer_map_create ();
57
  encoder->nodes = NULL;
58
  return encoder;
59
}
60
 
61
 
62
/* Delete ENCODER and its components.  */
63
 
64
void
65
lto_cgraph_encoder_delete (lto_cgraph_encoder_t encoder)
66
{
67
   VEC_free (cgraph_node_ptr, heap, encoder->nodes);
68
   pointer_map_destroy (encoder->map);
69
   free (encoder);
70
}
71
 
72
 
73
/* Return the existing reference number of NODE in the cgraph encoder in
74
   output block OB.  Assign a new reference if this is the first time
75
   NODE is encoded.  */
76
 
77
int
78
lto_cgraph_encoder_encode (lto_cgraph_encoder_t encoder,
79
                           struct cgraph_node *node)
80
{
81
  int ref;
82
  void **slot;
83
 
84
  slot = pointer_map_contains (encoder->map, node);
85
  if (!slot)
86
    {
87
      ref = VEC_length (cgraph_node_ptr, encoder->nodes);
88
      slot = pointer_map_insert (encoder->map, node);
89
      *slot = (void *) (intptr_t) ref;
90
      VEC_safe_push (cgraph_node_ptr, heap, encoder->nodes, node);
91
    }
92
  else
93
    ref = (int) (intptr_t) *slot;
94
 
95
  return ref;
96
}
97
 
98
 
99
/* Look up NODE in encoder.  Return NODE's reference if it has been encoded
100
   or LCC_NOT_FOUND if it is not there.  */
101
 
102
int
103
lto_cgraph_encoder_lookup (lto_cgraph_encoder_t encoder,
104
                           struct cgraph_node *node)
105
{
106
  void **slot = pointer_map_contains (encoder->map, node);
107
  return (slot ? (int) (intptr_t) *slot : LCC_NOT_FOUND);
108
}
109
 
110
 
111
/* Return the cgraph node corresponding to REF using ENCODER.  */
112
 
113
struct cgraph_node *
114
lto_cgraph_encoder_deref (lto_cgraph_encoder_t encoder, int ref)
115
{
116
  if (ref == LCC_NOT_FOUND)
117
    return NULL;
118
 
119
  return VEC_index (cgraph_node_ptr, encoder->nodes, ref);
120
}
121
 
122
 
123
/* Return number of encoded nodes in ENCODER.  */
124
 
125
static int
126
lto_cgraph_encoder_size (lto_cgraph_encoder_t encoder)
127
{
128
  return VEC_length (cgraph_node_ptr, encoder->nodes);
129
}
130
 
131
 
132
/* Output the cgraph EDGE to OB using ENCODER.  */
133
 
134
static void
135
lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
136
                 lto_cgraph_encoder_t encoder)
137
{
138
  unsigned int uid;
139
  intptr_t ref;
140
  struct bitpack_d *bp;
141
 
142
  lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_edge);
143
 
144
  ref = lto_cgraph_encoder_lookup (encoder, edge->caller);
145
  gcc_assert (ref != LCC_NOT_FOUND);
146
  lto_output_sleb128_stream (ob->main_stream, ref);
147
 
148
  ref = lto_cgraph_encoder_lookup (encoder, edge->callee);
149
  gcc_assert (ref != LCC_NOT_FOUND);
150
  lto_output_sleb128_stream (ob->main_stream, ref);
151
 
152
  lto_output_sleb128_stream (ob->main_stream, edge->count);
153
 
154
  bp = bitpack_create ();
155
  uid = flag_wpa ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt);
156
  bp_pack_value (bp, uid, HOST_BITS_PER_INT);
157
  bp_pack_value (bp, edge->inline_failed, HOST_BITS_PER_INT);
158
  bp_pack_value (bp, edge->frequency, HOST_BITS_PER_INT);
159
  bp_pack_value (bp, edge->loop_nest, 30);
160
  bp_pack_value (bp, edge->indirect_call, 1);
161
  bp_pack_value (bp, edge->call_stmt_cannot_inline_p, 1);
162
  bp_pack_value (bp, edge->can_throw_external, 1);
163
  lto_output_bitpack (ob->main_stream, bp);
164
  bitpack_delete (bp);
165
}
166
 
167
 
168
/* Output the cgraph NODE to OB.  ENCODER is used to find the
169
   reference number of NODE->inlined_to.  SET is the set of nodes we
170
   are writing to the current file.  If NODE is not in SET, then NODE
171
   is a boundary of a cgraph_node_set and we pretend NODE just has a
172
   decl and no callees.  WRITTEN_DECLS is the set of FUNCTION_DECLs
173
   that have had their callgraph node written so far.  This is used to
174
   determine if NODE is a clone of a previously written node.  */
175
 
176
static void
177
lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
178
                 lto_cgraph_encoder_t encoder, cgraph_node_set set,
179
                 bitmap written_decls)
180
{
181
  unsigned int tag;
182
  struct bitpack_d *bp;
183
  unsigned local, externally_visible, inlinable, analyzed;
184
  bool boundary_p, wrote_decl_p;
185
  intptr_t ref;
186
 
187
  boundary_p = !cgraph_node_in_set_p (node, set);
188
  wrote_decl_p = bitmap_bit_p (written_decls, DECL_UID (node->decl));
189
 
190
  switch (cgraph_function_body_availability (node))
191
    {
192
    case AVAIL_NOT_AVAILABLE:
193
      tag = LTO_cgraph_unavail_node;
194
      break;
195
 
196
    case AVAIL_AVAILABLE:
197
    case AVAIL_LOCAL:
198
      tag = LTO_cgraph_avail_node;
199
      break;
200
 
201
    case AVAIL_OVERWRITABLE:
202
      tag = LTO_cgraph_overwritable_node;
203
      break;
204
 
205
    default:
206
      gcc_unreachable ();
207
    }
208
 
209
  if (boundary_p)
210
    tag = LTO_cgraph_unavail_node;
211
 
212
  lto_output_uleb128_stream (ob->main_stream, tag);
213
 
214
  local = node->local.local;
215
  externally_visible = node->local.externally_visible;
216
  inlinable = node->local.inlinable;
217
  analyzed = node->analyzed;
218
 
219
  /* In WPA mode, we only output part of the call-graph.  Also, we
220
     fake cgraph node attributes.  There are two cases that we care.
221
 
222
     Boundary nodes: There are nodes that are not part of SET but are
223
     called from within SET.  We artificially make them look like
224
     externally visible nodes with no function body.
225
 
226
     Cherry-picked nodes:  These are nodes we pulled from other
227
     translation units into SET during IPA-inlining.  We make them as
228
     local static nodes to prevent clashes with other local statics.  */
229
  if (boundary_p)
230
    {
231
      /* Inline clones can not be part of boundary.  */
232
      gcc_assert (!node->global.inlined_to);
233
      local = 0;
234
      externally_visible = 1;
235
      inlinable = 0;
236
      analyzed = 0;
237
    }
238
  else if (lto_forced_extern_inline_p (node->decl))
239
    {
240
      local = 1;
241
      externally_visible = 0;
242
      inlinable = 1;
243
    }
244
 
245
  lto_output_uleb128_stream (ob->main_stream, wrote_decl_p);
246
 
247
  if (!wrote_decl_p)
248
    bitmap_set_bit (written_decls, DECL_UID (node->decl));
249
 
250
  lto_output_fn_decl_index (ob->decl_state, ob->main_stream, node->decl);
251
  lto_output_sleb128_stream (ob->main_stream, node->count);
252
 
253
  bp = bitpack_create ();
254
  bp_pack_value (bp, local, 1);
255
  bp_pack_value (bp, externally_visible, 1);
256
  bp_pack_value (bp, node->local.finalized, 1);
257
  bp_pack_value (bp, inlinable, 1);
258
  bp_pack_value (bp, node->local.disregard_inline_limits, 1);
259
  bp_pack_value (bp, node->local.redefined_extern_inline, 1);
260
  bp_pack_value (bp, node->local.for_functions_valid, 1);
261
  bp_pack_value (bp, node->local.vtable_method, 1);
262
  bp_pack_value (bp, node->needed, 1);
263
  bp_pack_value (bp, node->address_taken, 1);
264
  bp_pack_value (bp, node->abstract_and_needed, 1);
265
  bp_pack_value (bp, node->reachable, 1);
266
  bp_pack_value (bp, node->lowered, 1);
267
  bp_pack_value (bp, analyzed, 1);
268
  bp_pack_value (bp, node->process, 1);
269
  bp_pack_value (bp, node->alias, 1);
270
  bp_pack_value (bp, node->finalized_by_frontend, 1);
271
  lto_output_bitpack (ob->main_stream, bp);
272
  bitpack_delete (bp);
273
 
274
  if (tag != LTO_cgraph_unavail_node)
275
    {
276
      lto_output_sleb128_stream (ob->main_stream,
277
                                 node->local.inline_summary.estimated_self_stack_size);
278
      lto_output_sleb128_stream (ob->main_stream,
279
                                 node->local.inline_summary.self_size);
280
      lto_output_sleb128_stream (ob->main_stream,
281
                                 node->local.inline_summary.size_inlining_benefit);
282
      lto_output_sleb128_stream (ob->main_stream,
283
                                 node->local.inline_summary.self_time);
284
      lto_output_sleb128_stream (ob->main_stream,
285
                                 node->local.inline_summary.time_inlining_benefit);
286
    }
287
 
288
  /* FIXME lto: Outputting global info is not neccesary until after
289
     inliner was run.  Global structure holds results of propagation
290
     done by inliner.  */
291
  lto_output_sleb128_stream (ob->main_stream,
292
                             node->global.estimated_stack_size);
293
  lto_output_sleb128_stream (ob->main_stream,
294
                             node->global.stack_frame_offset);
295
  if (node->global.inlined_to && !boundary_p)
296
    {
297
      ref = lto_cgraph_encoder_lookup (encoder, node->global.inlined_to);
298
      gcc_assert (ref != LCC_NOT_FOUND);
299
    }
300
  else
301
    ref = LCC_NOT_FOUND;
302
  lto_output_sleb128_stream (ob->main_stream, ref);
303
 
304
  lto_output_sleb128_stream (ob->main_stream, node->global.time);
305
  lto_output_sleb128_stream (ob->main_stream, node->global.size);
306
  lto_output_sleb128_stream (ob->main_stream,
307
                             node->global.estimated_growth);
308
  lto_output_uleb128_stream (ob->main_stream, node->global.inlined);
309
  if (node->same_comdat_group)
310
    {
311
      ref = lto_cgraph_encoder_lookup (encoder, node->same_comdat_group);
312
      gcc_assert (ref != LCC_NOT_FOUND);
313
    }
314
  else
315
    ref = LCC_NOT_FOUND;
316
  lto_output_sleb128_stream (ob->main_stream, ref);
317
 
318
  if (node->same_body)
319
    {
320
      struct cgraph_node *alias;
321
      unsigned long alias_count = 1;
322
      for (alias = node->same_body; alias->next; alias = alias->next)
323
        alias_count++;
324
      lto_output_uleb128_stream (ob->main_stream, alias_count);
325
      do
326
        {
327
          lto_output_fn_decl_index (ob->decl_state, ob->main_stream,
328
                                    alias->decl);
329
          if (alias->thunk.thunk_p)
330
            {
331
              lto_output_uleb128_stream
332
                 (ob->main_stream,
333
                  1 + (alias->thunk.this_adjusting != 0) * 2
334
                  + (alias->thunk.virtual_offset_p != 0) * 4);
335
              lto_output_uleb128_stream (ob->main_stream,
336
                                         alias->thunk.fixed_offset);
337
              lto_output_uleb128_stream (ob->main_stream,
338
                                         alias->thunk.virtual_value);
339
              lto_output_fn_decl_index (ob->decl_state, ob->main_stream,
340
                                        alias->thunk.alias);
341
            }
342
          else
343
            {
344
              lto_output_uleb128_stream (ob->main_stream, 0);
345
              lto_output_fn_decl_index (ob->decl_state, ob->main_stream,
346
                                        alias->thunk.alias);
347
            }
348
          alias = alias->previous;
349
        }
350
      while (alias);
351
    }
352
  else
353
    lto_output_uleb128_stream (ob->main_stream, 0);
354
}
355
 
356
/* Stream out profile_summary to OB.  */
357
 
358
static void
359
output_profile_summary (struct lto_simple_output_block *ob)
360
{
361
  if (profile_info)
362
    {
363
      /* We do not output num, it is not terribly useful.  */
364
      gcc_assert (profile_info->runs);
365
      lto_output_uleb128_stream (ob->main_stream, profile_info->runs);
366
      lto_output_sleb128_stream (ob->main_stream, profile_info->sum_all);
367
      lto_output_sleb128_stream (ob->main_stream, profile_info->run_max);
368
      lto_output_sleb128_stream (ob->main_stream, profile_info->sum_max);
369
    }
370
  else
371
    lto_output_uleb128_stream (ob->main_stream, 0);
372
}
373
 
374
 
375
/* Output the part of the cgraph in SET.  */
376
 
377
void
378
output_cgraph (cgraph_node_set set)
379
{
380
  struct cgraph_node *node;
381
  struct lto_simple_output_block *ob;
382
  cgraph_node_set_iterator csi;
383
  struct cgraph_edge *edge;
384
  int i, n_nodes;
385
  bitmap written_decls;
386
  lto_cgraph_encoder_t encoder;
387
  struct cgraph_asm_node *can;
388
 
389
  ob = lto_create_simple_output_block (LTO_section_cgraph);
390
 
391
  output_profile_summary (ob);
392
 
393
  /* An encoder for cgraph nodes should have been created by
394
     ipa_write_summaries_1.  */
395
  gcc_assert (ob->decl_state->cgraph_node_encoder);
396
  encoder = ob->decl_state->cgraph_node_encoder;
397
 
398
  /* The FUNCTION_DECLs for which we have written a node.  The first
399
     node found is written as the "original" node, the remaining nodes
400
     are considered its clones.  */
401
  written_decls = lto_bitmap_alloc ();
402
 
403
  /* Go over all the nodes in SET and assign references.  */
404
  for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
405
    {
406
      node = csi_node (csi);
407
      lto_cgraph_encoder_encode (encoder, node);
408
    }
409
 
410
  /* Go over all the nodes again to include callees that are not in
411
     SET.  */
412
  for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
413
    {
414
      node = csi_node (csi);
415
      for (edge = node->callees; edge; edge = edge->next_callee)
416
        {
417
          struct cgraph_node *callee = edge->callee;
418
          if (!cgraph_node_in_set_p (callee, set))
419
            {
420
              /* We should have moved all the inlines.  */
421
              gcc_assert (!callee->global.inlined_to);
422
              lto_cgraph_encoder_encode (encoder, callee);
423
              /* Also with each included function include all other functions
424
                 in the same comdat group.  */
425
              if (callee->same_comdat_group)
426
                {
427
                  struct cgraph_node *next;
428
                  for (next = callee->same_comdat_group;
429
                       next != callee;
430
                       next = next->same_comdat_group)
431
                    if (!cgraph_node_in_set_p (next, set))
432
                      lto_cgraph_encoder_encode (encoder, next);
433
                }
434
            }
435
        }
436
      /* Also with each included function include all other functions
437
         in the same comdat group.  */
438
      if (node->same_comdat_group)
439
        {
440
          struct cgraph_node *next;
441
          for (next = node->same_comdat_group;
442
               next != node;
443
               next = next->same_comdat_group)
444
            if (!cgraph_node_in_set_p (next, set))
445
              lto_cgraph_encoder_encode (encoder, next);
446
        }
447
    }
448
 
449
  /* Write out the nodes.  */
450
  n_nodes = lto_cgraph_encoder_size (encoder);
451
  for (i = 0; i < n_nodes; i++)
452
    {
453
      node = lto_cgraph_encoder_deref (encoder, i);
454
      lto_output_node (ob, node, encoder, set, written_decls);
455
    }
456
 
457
  lto_bitmap_free (written_decls);
458
 
459
  /* Go over the nodes in SET again to write edges.  */
460
  for (csi = csi_start (set); !csi_end_p (csi); csi_next (&csi))
461
    {
462
      node = csi_node (csi);
463
      if (node->callees)
464
        {
465
          /* Output edges in backward direction, so the reconstructed callgraph
466
             match and it is easy to associate call sites in the IPA pass summaries.  */
467
          edge = node->callees;
468
          while (edge->next_callee)
469
            edge = edge->next_callee;
470
          for (; edge; edge = edge->prev_callee)
471
            lto_output_edge (ob, edge, encoder);
472
        }
473
    }
474
 
475
  lto_output_uleb128_stream (ob->main_stream, 0);
476
 
477
  /* Emit toplevel asms.  */
478
  for (can = cgraph_asm_nodes; can; can = can->next)
479
    {
480
      int len = TREE_STRING_LENGTH (can->asm_str);
481
      lto_output_uleb128_stream (ob->main_stream, len);
482
      for (i = 0; i < len; ++i)
483
        lto_output_1_stream (ob->main_stream,
484
                             TREE_STRING_POINTER (can->asm_str)[i]);
485
    }
486
 
487
  lto_output_uleb128_stream (ob->main_stream, 0);
488
 
489
  lto_destroy_simple_output_block (ob);
490
}
491
 
492
 
493
/* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
494
   STACK_SIZE, SELF_TIME and SELF_SIZE.  This is called either to initialize
495
   NODE or to replace the values in it, for instance because the first
496
   time we saw it, the function body was not available but now it
497
   is.  BP is a bitpack with all the bitflags for NODE read from the
498
   stream.  */
499
 
500
static void
501
input_overwrite_node (struct lto_file_decl_data *file_data,
502
                      struct cgraph_node *node,
503
                      enum LTO_cgraph_tags tag,
504
                      struct bitpack_d *bp,
505
                      unsigned int stack_size,
506
                      unsigned int self_time,
507
                      unsigned int time_inlining_benefit,
508
                      unsigned int self_size,
509
                      unsigned int size_inlining_benefit)
510
{
511
  node->aux = (void *) tag;
512
  node->local.inline_summary.estimated_self_stack_size = stack_size;
513
  node->local.inline_summary.self_time = self_time;
514
  node->local.inline_summary.time_inlining_benefit = time_inlining_benefit;
515
  node->local.inline_summary.self_size = self_size;
516
  node->local.inline_summary.size_inlining_benefit = size_inlining_benefit;
517
  node->global.time = self_time;
518
  node->global.size = self_size;
519
  node->local.lto_file_data = file_data;
520
 
521
  node->local.local = bp_unpack_value (bp, 1);
522
  node->local.externally_visible = bp_unpack_value (bp, 1);
523
  node->local.finalized = bp_unpack_value (bp, 1);
524
  node->local.inlinable = bp_unpack_value (bp, 1);
525
  node->local.disregard_inline_limits = bp_unpack_value (bp, 1);
526
  node->local.redefined_extern_inline = bp_unpack_value (bp, 1);
527
  node->local.for_functions_valid = bp_unpack_value (bp, 1);
528
  node->local.vtable_method = bp_unpack_value (bp, 1);
529
  node->needed = bp_unpack_value (bp, 1);
530
  node->address_taken = bp_unpack_value (bp, 1);
531
  node->abstract_and_needed = bp_unpack_value (bp, 1);
532
  node->reachable = bp_unpack_value (bp, 1);
533
  node->lowered = bp_unpack_value (bp, 1);
534
  node->analyzed = bp_unpack_value (bp, 1);
535
  node->process = bp_unpack_value (bp, 1);
536
  node->alias = bp_unpack_value (bp, 1);
537
  node->finalized_by_frontend = bp_unpack_value (bp, 1);
538
}
539
 
540
 
541
/* Read a node from input_block IB.  TAG is the node's tag just read.
542
   Return the node read or overwriten.  */
543
 
544
static struct cgraph_node *
545
input_node (struct lto_file_decl_data *file_data,
546
            struct lto_input_block *ib,
547
            enum LTO_cgraph_tags tag)
548
{
549
  tree fn_decl;
550
  struct cgraph_node *node;
551
  struct bitpack_d *bp;
552
  int stack_size = 0;
553
  unsigned decl_index;
554
  bool clone_p;
555
  int estimated_stack_size = 0;
556
  int stack_frame_offset = 0;
557
  int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND;
558
  int estimated_growth = 0;
559
  int time = 0;
560
  int size = 0;
561
  int self_time = 0;
562
  int self_size = 0;
563
  int time_inlining_benefit = 0;
564
  int size_inlining_benefit = 0;
565
  unsigned long same_body_count = 0;
566
  bool inlined = false;
567
 
568
  clone_p = (lto_input_uleb128 (ib) != 0);
569
 
570
  decl_index = lto_input_uleb128 (ib);
571
  fn_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index);
572
 
573
  if (clone_p)
574
    node = cgraph_clone_node (cgraph_node (fn_decl), 0,
575
                              CGRAPH_FREQ_BASE, 0, false, NULL);
576
 
577
  else
578
    node = cgraph_node (fn_decl);
579
 
580
  node->count = lto_input_sleb128 (ib);
581
  bp = lto_input_bitpack (ib);
582
 
583
  if (tag != LTO_cgraph_unavail_node)
584
    {
585
      stack_size = lto_input_sleb128 (ib);
586
      self_size = lto_input_sleb128 (ib);
587
      size_inlining_benefit = lto_input_sleb128 (ib);
588
      self_time = lto_input_sleb128 (ib);
589
      time_inlining_benefit = lto_input_sleb128 (ib);
590
    }
591
 
592
  estimated_stack_size = lto_input_sleb128 (ib);
593
  stack_frame_offset = lto_input_sleb128 (ib);
594
  ref = lto_input_sleb128 (ib);
595
  time = lto_input_sleb128 (ib);
596
  size = lto_input_sleb128 (ib);
597
  estimated_growth = lto_input_sleb128 (ib);
598
  inlined = lto_input_uleb128 (ib);
599
  ref2 = lto_input_sleb128 (ib);
600
  same_body_count = lto_input_uleb128 (ib);
601
 
602
  /* Make sure that we have not read this node before.  Nodes that
603
     have already been read will have their tag stored in the 'aux'
604
     field.  Since built-in functions can be referenced in multiple
605
     functions, they are expected to be read more than once.  */
606
  if (node->aux && !DECL_IS_BUILTIN (node->decl))
607
    internal_error ("bytecode stream: found multiple instances of cgraph "
608
                    "node %d", node->uid);
609
 
610
  input_overwrite_node (file_data, node, tag, bp, stack_size, self_time,
611
                        time_inlining_benefit, self_size,
612
                        size_inlining_benefit);
613
  bitpack_delete (bp);
614
 
615
  node->global.estimated_stack_size = estimated_stack_size;
616
  node->global.stack_frame_offset = stack_frame_offset;
617
  node->global.time = time;
618
  node->global.size = size;
619
 
620
  /* Store a reference for now, and fix up later to be a pointer.  */
621
  node->global.inlined_to = (cgraph_node_ptr) (intptr_t) ref;
622
 
623
  node->global.estimated_growth = estimated_growth;
624
  node->global.inlined = inlined;
625
 
626
  /* Store a reference for now, and fix up later to be a pointer.  */
627
  node->same_comdat_group = (cgraph_node_ptr) (intptr_t) ref2;
628
 
629
  while (same_body_count-- > 0)
630
    {
631
      tree alias_decl;
632
      int type;
633
      decl_index = lto_input_uleb128 (ib);
634
      alias_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index);
635
      type = lto_input_uleb128 (ib);
636
      if (!type)
637
        {
638
          tree real_alias;
639
          decl_index = lto_input_uleb128 (ib);
640
          real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index);
641
          cgraph_same_body_alias (alias_decl, real_alias);
642
        }
643
      else
644
        {
645
          HOST_WIDE_INT fixed_offset = lto_input_uleb128 (ib);
646
          HOST_WIDE_INT virtual_value = lto_input_uleb128 (ib);
647
          tree real_alias;
648
          decl_index = lto_input_uleb128 (ib);
649
          real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index);
650
          cgraph_add_thunk (alias_decl, fn_decl, type & 2, fixed_offset,
651
                            virtual_value,
652
                            (type & 4) ? size_int (virtual_value) : NULL_TREE,
653
                            real_alias);
654
        }
655
    }
656
  return node;
657
}
658
 
659
 
660
/* Read an edge from IB.  NODES points to a vector of previously read
661
   nodes for decoding caller and callee of the edge to be read.  */
662
 
663
static void
664
input_edge (struct lto_input_block *ib, VEC(cgraph_node_ptr, heap) *nodes)
665
{
666
  struct cgraph_node *caller, *callee;
667
  struct cgraph_edge *edge;
668
  unsigned int stmt_id;
669
  gcov_type count;
670
  int freq;
671
  unsigned int nest;
672
  cgraph_inline_failed_t inline_failed;
673
  struct bitpack_d *bp;
674
  enum ld_plugin_symbol_resolution caller_resolution;
675
 
676
  caller = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
677
  if (caller == NULL || caller->decl == NULL_TREE)
678
    internal_error ("bytecode stream: no caller found while reading edge");
679
 
680
  callee = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib));
681
  if (callee == NULL || callee->decl == NULL_TREE)
682
    internal_error ("bytecode stream: no callee found while reading edge");
683
 
684
  count = (gcov_type) lto_input_sleb128 (ib);
685
 
686
  bp = lto_input_bitpack (ib);
687
  stmt_id = (unsigned int) bp_unpack_value (bp, HOST_BITS_PER_INT);
688
  inline_failed = (cgraph_inline_failed_t) bp_unpack_value (bp,
689
                                                            HOST_BITS_PER_INT);
690
  freq = (int) bp_unpack_value (bp, HOST_BITS_PER_INT);
691
  nest = (unsigned) bp_unpack_value (bp, 30);
692
 
693
  /* If the caller was preempted, don't create the edge.
694
     ???  Should we ever have edges from a preempted caller?  */
695
  caller_resolution = lto_symtab_get_resolution (caller->decl);
696
  if (caller_resolution == LDPR_PREEMPTED_REG
697
      || caller_resolution == LDPR_PREEMPTED_IR)
698
    return;
699
 
700
  edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest);
701
  edge->lto_stmt_uid = stmt_id;
702
  edge->inline_failed = inline_failed;
703
  edge->indirect_call = bp_unpack_value (bp, 1);
704
  edge->call_stmt_cannot_inline_p = bp_unpack_value (bp, 1);
705
  edge->can_throw_external = bp_unpack_value (bp, 1);
706
  bitpack_delete (bp);
707
}
708
 
709
 
710
/* Read a cgraph from IB using the info in FILE_DATA.  */
711
 
712
static void
713
input_cgraph_1 (struct lto_file_decl_data *file_data,
714
                struct lto_input_block *ib)
715
{
716
  enum LTO_cgraph_tags tag;
717
  VEC(cgraph_node_ptr, heap) *nodes = NULL;
718
  struct cgraph_node *node;
719
  unsigned i;
720
  unsigned HOST_WIDE_INT len;
721
 
722
  tag = (enum LTO_cgraph_tags) lto_input_uleb128 (ib);
723
  while (tag)
724
    {
725
      if (tag == LTO_cgraph_edge)
726
        input_edge (ib, nodes);
727
      else
728
        {
729
          node = input_node (file_data, ib, tag);
730
          if (node == NULL || node->decl == NULL_TREE)
731
            internal_error ("bytecode stream: found empty cgraph node");
732
          VEC_safe_push (cgraph_node_ptr, heap, nodes, node);
733
          lto_cgraph_encoder_encode (file_data->cgraph_node_encoder, node);
734
        }
735
 
736
      tag = (enum LTO_cgraph_tags) lto_input_uleb128 (ib);
737
    }
738
 
739
  /* Input toplevel asms.  */
740
  len = lto_input_uleb128 (ib);
741
  while (len)
742
    {
743
      char *str = (char *)xmalloc (len + 1);
744
      for (i = 0; i < len; ++i)
745
        str[i] = lto_input_1_unsigned (ib);
746
      cgraph_add_asm_node (build_string (len, str));
747
      free (str);
748
 
749
      len = lto_input_uleb128 (ib);
750
    }
751
 
752
  for (i = 0; VEC_iterate (cgraph_node_ptr, nodes, i, node); i++)
753
    {
754
      int ref = (int) (intptr_t) node->global.inlined_to;
755
 
756
      /* Fixup inlined_to from reference to pointer.  */
757
      if (ref != LCC_NOT_FOUND)
758
        node->global.inlined_to = VEC_index (cgraph_node_ptr, nodes, ref);
759
      else
760
        node->global.inlined_to = NULL;
761
 
762
      ref = (int) (intptr_t) node->same_comdat_group;
763
 
764
      /* Fixup same_comdat_group from reference to pointer.  */
765
      if (ref != LCC_NOT_FOUND)
766
        node->same_comdat_group = VEC_index (cgraph_node_ptr, nodes, ref);
767
      else
768
        node->same_comdat_group = NULL;
769
    }
770
 
771
  VEC_free (cgraph_node_ptr, heap, nodes);
772
}
773
 
774
static struct gcov_ctr_summary lto_gcov_summary;
775
 
776
/* Input profile_info from IB.  */
777
static void
778
input_profile_summary (struct lto_input_block *ib)
779
{
780
  unsigned int runs = lto_input_uleb128 (ib);
781
  if (runs)
782
    {
783
      if (!profile_info)
784
        {
785
          profile_info = &lto_gcov_summary;
786
          lto_gcov_summary.runs = runs;
787
          lto_gcov_summary.sum_all = lto_input_sleb128 (ib);
788
          lto_gcov_summary.run_max = lto_input_sleb128 (ib);
789
          lto_gcov_summary.sum_max = lto_input_sleb128 (ib);
790
        }
791
      /* We can support this by scaling all counts to nearest common multiple
792
         of all different runs, but it is perhaps not worth the effort.  */
793
      else if (profile_info->runs != runs
794
               || profile_info->sum_all != lto_input_sleb128 (ib)
795
               || profile_info->run_max != lto_input_sleb128 (ib)
796
               || profile_info->sum_max != lto_input_sleb128 (ib))
797
        sorry ("Combining units with different profiles is not supported.");
798
      /* We allow some units to have profile and other to not have one.  This will
799
         just make unprofiled units to be size optimized that is sane.  */
800
    }
801
 
802
}
803
 
804
/* Input and merge the cgraph from each of the .o files passed to
805
   lto1.  */
806
 
807
void
808
input_cgraph (void)
809
{
810
  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
811
  struct lto_file_decl_data *file_data;
812
  unsigned int j = 0;
813
  struct cgraph_node *node;
814
 
815
  while ((file_data = file_data_vec[j++]))
816
    {
817
      const char *data;
818
      size_t len;
819
      struct lto_input_block *ib;
820
 
821
      ib = lto_create_simple_input_block (file_data, LTO_section_cgraph,
822
                                          &data, &len);
823
      input_profile_summary (ib);
824
      file_data->cgraph_node_encoder = lto_cgraph_encoder_new ();
825
      input_cgraph_1 (file_data, ib);
826
      lto_destroy_simple_input_block (file_data, LTO_section_cgraph,
827
                                      ib, data, len);
828
 
829
      /* Assume that every file read needs to be processed by LTRANS.  */
830
      if (flag_wpa)
831
        lto_mark_file_for_ltrans (file_data);
832
    }
833
 
834
  /* Clear out the aux field that was used to store enough state to
835
     tell which nodes should be overwritten.  */
836
  for (node = cgraph_nodes; node; node = node->next)
837
    {
838
      /* Some nodes may have been created by cgraph_node.  This
839
         happens when the callgraph contains nested functions.  If the
840
         node for the parent function was never emitted to the gimple
841
         file, cgraph_node will create a node for it when setting the
842
         context of the nested function.  */
843
      if (node->local.lto_file_data)
844
        node->aux = NULL;
845
    }
846
}

powered by: WebSVN 2.1.0

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