Mercurial > hg > CbC > CbC_gcc
comparison gcc/lto-cgraph.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
comparison
equal
deleted
inserted
replaced
65:65488c3d617d | 67:f6334be47118 |
---|---|
1 /* Write and read the cgraph to the memory mapped representation of a | 1 /* Write and read the cgraph to the memory mapped representation of a |
2 .o file. | 2 .o file. |
3 | 3 |
4 Copyright 2009 Free Software Foundation, Inc. | 4 Copyright 2009, 2010 Free Software Foundation, Inc. |
5 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> | 5 Contributed by Kenneth Zadeck <zadeck@naturalbridge.com> |
6 | 6 |
7 This file is part of GCC. | 7 This file is part of GCC. |
8 | 8 |
9 GCC is free software; you can redistribute it and/or modify it under | 9 GCC is free software; you can redistribute it and/or modify it under |
22 | 22 |
23 #include "config.h" | 23 #include "config.h" |
24 #include "system.h" | 24 #include "system.h" |
25 #include "coretypes.h" | 25 #include "coretypes.h" |
26 #include "tm.h" | 26 #include "tm.h" |
27 #include "toplev.h" | |
28 #include "tree.h" | 27 #include "tree.h" |
29 #include "expr.h" | 28 #include "expr.h" |
30 #include "flags.h" | 29 #include "flags.h" |
31 #include "params.h" | 30 #include "params.h" |
32 #include "input.h" | 31 #include "input.h" |
35 #include "basic-block.h" | 34 #include "basic-block.h" |
36 #include "tree-flow.h" | 35 #include "tree-flow.h" |
37 #include "cgraph.h" | 36 #include "cgraph.h" |
38 #include "function.h" | 37 #include "function.h" |
39 #include "ggc.h" | 38 #include "ggc.h" |
40 #include "diagnostic.h" | 39 #include "diagnostic-core.h" |
41 #include "except.h" | 40 #include "except.h" |
42 #include "vec.h" | 41 #include "vec.h" |
43 #include "timevar.h" | 42 #include "timevar.h" |
44 #include "output.h" | 43 #include "output.h" |
45 #include "pointer-set.h" | 44 #include "pointer-set.h" |
46 #include "lto-streamer.h" | 45 #include "lto-streamer.h" |
47 #include "gcov-io.h" | 46 #include "gcov-io.h" |
48 | 47 |
49 static void output_varpool (cgraph_node_set, varpool_node_set); | 48 static void output_varpool (cgraph_node_set, varpool_node_set); |
50 static void output_cgraph_opt_summary (void); | 49 static void output_cgraph_opt_summary (cgraph_node_set set); |
51 static void input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes); | 50 static void input_cgraph_opt_summary (VEC (cgraph_node_ptr, heap) * nodes); |
52 | 51 |
53 | 52 |
54 /* Cgraph streaming is organized as set of record whose type | 53 /* Cgraph streaming is organized as set of record whose type |
55 is indicated by a tag. */ | 54 is indicated by a tag. */ |
232 | 231 |
233 return VEC_index (varpool_node_ptr, encoder->nodes, ref); | 232 return VEC_index (varpool_node_ptr, encoder->nodes, ref); |
234 } | 233 } |
235 | 234 |
236 | 235 |
237 /* Return number of encoded nodes in ENCODER. */ | |
238 | |
239 static int | |
240 lto_varpool_encoder_size (lto_varpool_encoder_t encoder) | |
241 { | |
242 return VEC_length (varpool_node_ptr, encoder->nodes); | |
243 } | |
244 | |
245 /* Return TRUE if we should encode initializer of NODE (if any). */ | 236 /* Return TRUE if we should encode initializer of NODE (if any). */ |
246 | 237 |
247 bool | 238 bool |
248 lto_varpool_encoder_encode_initializer_p (lto_varpool_encoder_t encoder, | 239 lto_varpool_encoder_encode_initializer_p (lto_varpool_encoder_t encoder, |
249 struct varpool_node *node) | 240 struct varpool_node *node) |
266 lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge, | 257 lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge, |
267 lto_cgraph_encoder_t encoder) | 258 lto_cgraph_encoder_t encoder) |
268 { | 259 { |
269 unsigned int uid; | 260 unsigned int uid; |
270 intptr_t ref; | 261 intptr_t ref; |
271 struct bitpack_d *bp; | 262 struct bitpack_d bp; |
272 | 263 |
273 if (edge->indirect_unknown_callee) | 264 if (edge->indirect_unknown_callee) |
274 lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_indirect_edge); | 265 lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_indirect_edge); |
275 else | 266 else |
276 lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_edge); | 267 lto_output_uleb128_stream (ob->main_stream, LTO_cgraph_edge); |
286 lto_output_sleb128_stream (ob->main_stream, ref); | 277 lto_output_sleb128_stream (ob->main_stream, ref); |
287 } | 278 } |
288 | 279 |
289 lto_output_sleb128_stream (ob->main_stream, edge->count); | 280 lto_output_sleb128_stream (ob->main_stream, edge->count); |
290 | 281 |
291 bp = bitpack_create (); | 282 bp = bitpack_create (ob->main_stream); |
292 uid = flag_wpa ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt); | 283 uid = (!gimple_has_body_p (edge->caller->decl) |
293 bp_pack_value (bp, uid, HOST_BITS_PER_INT); | 284 ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt)); |
294 bp_pack_value (bp, edge->inline_failed, HOST_BITS_PER_INT); | 285 bp_pack_value (&bp, uid, HOST_BITS_PER_INT); |
295 bp_pack_value (bp, edge->frequency, HOST_BITS_PER_INT); | 286 bp_pack_value (&bp, edge->inline_failed, HOST_BITS_PER_INT); |
296 bp_pack_value (bp, edge->loop_nest, 30); | 287 bp_pack_value (&bp, edge->frequency, HOST_BITS_PER_INT); |
297 bp_pack_value (bp, edge->indirect_inlining_edge, 1); | 288 bp_pack_value (&bp, edge->loop_nest, 30); |
298 bp_pack_value (bp, edge->call_stmt_cannot_inline_p, 1); | 289 bp_pack_value (&bp, edge->indirect_inlining_edge, 1); |
299 bp_pack_value (bp, edge->can_throw_external, 1); | 290 bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1); |
291 bp_pack_value (&bp, edge->can_throw_external, 1); | |
300 if (edge->indirect_unknown_callee) | 292 if (edge->indirect_unknown_callee) |
301 { | 293 { |
302 int flags = edge->indirect_info->ecf_flags; | 294 int flags = edge->indirect_info->ecf_flags; |
303 bp_pack_value (bp, (flags & ECF_CONST) != 0, 1); | 295 bp_pack_value (&bp, (flags & ECF_CONST) != 0, 1); |
304 bp_pack_value (bp, (flags & ECF_PURE) != 0, 1); | 296 bp_pack_value (&bp, (flags & ECF_PURE) != 0, 1); |
305 bp_pack_value (bp, (flags & ECF_NORETURN) != 0, 1); | 297 bp_pack_value (&bp, (flags & ECF_NORETURN) != 0, 1); |
306 bp_pack_value (bp, (flags & ECF_MALLOC) != 0, 1); | 298 bp_pack_value (&bp, (flags & ECF_MALLOC) != 0, 1); |
307 bp_pack_value (bp, (flags & ECF_NOTHROW) != 0, 1); | 299 bp_pack_value (&bp, (flags & ECF_NOTHROW) != 0, 1); |
308 bp_pack_value (bp, (flags & ECF_RETURNS_TWICE) != 0, 1); | 300 bp_pack_value (&bp, (flags & ECF_RETURNS_TWICE) != 0, 1); |
309 /* Flags that should not appear on indirect calls. */ | 301 /* Flags that should not appear on indirect calls. */ |
310 gcc_assert (!(flags & (ECF_LOOPING_CONST_OR_PURE | 302 gcc_assert (!(flags & (ECF_LOOPING_CONST_OR_PURE |
311 | ECF_MAY_BE_ALLOCA | 303 | ECF_MAY_BE_ALLOCA |
312 | ECF_SIBCALL | 304 | ECF_SIBCALL |
305 | ECF_LEAF | |
313 | ECF_NOVOPS))); | 306 | ECF_NOVOPS))); |
314 } | 307 } |
315 lto_output_bitpack (ob->main_stream, bp); | 308 lto_output_bitpack (&bp); |
316 bitpack_delete (bp); | |
317 } | 309 } |
318 | 310 |
319 /* Return if LIST contain references from other partitions. */ | 311 /* Return if LIST contain references from other partitions. */ |
320 | 312 |
321 bool | 313 bool |
326 struct ipa_ref *ref; | 318 struct ipa_ref *ref; |
327 for (i = 0; ipa_ref_list_refering_iterate (list, i, ref); i++) | 319 for (i = 0; ipa_ref_list_refering_iterate (list, i, ref); i++) |
328 { | 320 { |
329 if (ref->refering_type == IPA_REF_CGRAPH) | 321 if (ref->refering_type == IPA_REF_CGRAPH) |
330 { | 322 { |
331 if (!cgraph_node_in_set_p (ipa_ref_refering_node (ref), set)) | 323 if (ipa_ref_refering_node (ref)->in_other_partition |
324 || !cgraph_node_in_set_p (ipa_ref_refering_node (ref), set)) | |
332 return true; | 325 return true; |
333 } | 326 } |
334 else | 327 else |
335 { | 328 { |
336 if (!varpool_node_in_set_p (ipa_ref_refering_varpool_node (ref), | 329 if (ipa_ref_refering_varpool_node (ref)->in_other_partition |
337 vset)) | 330 || !varpool_node_in_set_p (ipa_ref_refering_varpool_node (ref), |
331 vset)) | |
338 return true; | 332 return true; |
339 } | 333 } |
340 } | 334 } |
341 return false; | 335 return false; |
342 } | 336 } |
350 if (!node->analyzed) | 344 if (!node->analyzed) |
351 return false; | 345 return false; |
352 if (node->global.inlined_to) | 346 if (node->global.inlined_to) |
353 return false; | 347 return false; |
354 for (e = node->callers; e; e = e->next_caller) | 348 for (e = node->callers; e; e = e->next_caller) |
355 if (!cgraph_node_in_set_p (e->caller, set)) | 349 if (e->caller->in_other_partition |
350 || !cgraph_node_in_set_p (e->caller, set)) | |
356 return true; | 351 return true; |
357 return false; | 352 return false; |
358 } | 353 } |
359 | 354 |
360 /* Return if LIST contain references from other partitions. */ | 355 /* Return if LIST contain references from other partitions. */ |
386 | 381 |
387 bool | 382 bool |
388 reachable_from_this_partition_p (struct cgraph_node *node, cgraph_node_set set) | 383 reachable_from_this_partition_p (struct cgraph_node *node, cgraph_node_set set) |
389 { | 384 { |
390 struct cgraph_edge *e; | 385 struct cgraph_edge *e; |
391 if (!node->analyzed) | |
392 return false; | |
393 if (node->global.inlined_to) | |
394 return false; | |
395 for (e = node->callers; e; e = e->next_caller) | 386 for (e = node->callers; e; e = e->next_caller) |
396 if (cgraph_node_in_set_p (e->caller, set)) | 387 if (cgraph_node_in_set_p (e->caller, set)) |
397 return true; | 388 return true; |
398 return false; | 389 return false; |
399 } | 390 } |
410 lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, | 401 lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, |
411 lto_cgraph_encoder_t encoder, cgraph_node_set set, | 402 lto_cgraph_encoder_t encoder, cgraph_node_set set, |
412 varpool_node_set vset) | 403 varpool_node_set vset) |
413 { | 404 { |
414 unsigned int tag; | 405 unsigned int tag; |
415 struct bitpack_d *bp; | 406 struct bitpack_d bp; |
416 bool boundary_p; | 407 bool boundary_p; |
417 intptr_t ref; | 408 intptr_t ref; |
418 bool in_other_partition = false; | 409 bool in_other_partition = false; |
419 struct cgraph_node *clone_of; | 410 struct cgraph_node *clone_of; |
420 | 411 |
450 in_other_partition = 1; | 441 in_other_partition = 1; |
451 } | 442 } |
452 | 443 |
453 clone_of = node->clone_of; | 444 clone_of = node->clone_of; |
454 while (clone_of | 445 while (clone_of |
455 && (ref = lto_cgraph_encoder_lookup (encoder, node->clone_of)) == LCC_NOT_FOUND) | 446 && (ref = lto_cgraph_encoder_lookup (encoder, clone_of)) == LCC_NOT_FOUND) |
456 if (clone_of->prev_sibling_clone) | 447 if (clone_of->prev_sibling_clone) |
457 clone_of = clone_of->prev_sibling_clone; | 448 clone_of = clone_of->prev_sibling_clone; |
458 else | 449 else |
459 clone_of = clone_of->clone_of; | 450 clone_of = clone_of->clone_of; |
451 | |
452 if (LTO_cgraph_analyzed_node) | |
453 gcc_assert (clone_of || !node->clone_of); | |
460 if (!clone_of) | 454 if (!clone_of) |
461 lto_output_sleb128_stream (ob->main_stream, LCC_NOT_FOUND); | 455 lto_output_sleb128_stream (ob->main_stream, LCC_NOT_FOUND); |
462 else | 456 else |
463 lto_output_sleb128_stream (ob->main_stream, ref); | 457 lto_output_sleb128_stream (ob->main_stream, ref); |
464 | 458 |
465 | 459 |
466 lto_output_fn_decl_index (ob->decl_state, ob->main_stream, node->decl); | 460 lto_output_fn_decl_index (ob->decl_state, ob->main_stream, node->decl); |
467 lto_output_sleb128_stream (ob->main_stream, node->count); | 461 lto_output_sleb128_stream (ob->main_stream, node->count); |
468 | 462 lto_output_sleb128_stream (ob->main_stream, node->count_materialization_scale); |
469 bp = bitpack_create (); | |
470 bp_pack_value (bp, node->local.local, 1); | |
471 bp_pack_value (bp, node->local.externally_visible, 1); | |
472 bp_pack_value (bp, node->local.finalized, 1); | |
473 bp_pack_value (bp, node->local.inlinable, 1); | |
474 bp_pack_value (bp, node->local.versionable, 1); | |
475 bp_pack_value (bp, node->local.disregard_inline_limits, 1); | |
476 bp_pack_value (bp, node->local.redefined_extern_inline, 1); | |
477 bp_pack_value (bp, node->local.vtable_method, 1); | |
478 bp_pack_value (bp, node->needed, 1); | |
479 bp_pack_value (bp, node->address_taken, 1); | |
480 bp_pack_value (bp, node->abstract_and_needed, 1); | |
481 bp_pack_value (bp, tag == LTO_cgraph_analyzed_node | |
482 && !DECL_EXTERNAL (node->decl) | |
483 && (reachable_from_other_partition_p (node, set) | |
484 || referenced_from_other_partition_p (&node->ref_list, set, vset)), 1); | |
485 bp_pack_value (bp, node->lowered, 1); | |
486 bp_pack_value (bp, in_other_partition, 1); | |
487 bp_pack_value (bp, node->alias, 1); | |
488 bp_pack_value (bp, node->finalized_by_frontend, 1); | |
489 bp_pack_value (bp, node->frequency, 2); | |
490 lto_output_bitpack (ob->main_stream, bp); | |
491 bitpack_delete (bp); | |
492 | 463 |
493 if (tag == LTO_cgraph_analyzed_node) | 464 if (tag == LTO_cgraph_analyzed_node) |
494 { | 465 { |
495 lto_output_sleb128_stream (ob->main_stream, | 466 lto_output_sleb128_stream (ob->main_stream, |
496 node->local.inline_summary.estimated_self_stack_size); | 467 node->local.inline_summary.estimated_self_stack_size); |
519 gcc_assert (ref != LCC_NOT_FOUND); | 490 gcc_assert (ref != LCC_NOT_FOUND); |
520 } | 491 } |
521 else | 492 else |
522 ref = LCC_NOT_FOUND; | 493 ref = LCC_NOT_FOUND; |
523 lto_output_sleb128_stream (ob->main_stream, ref); | 494 lto_output_sleb128_stream (ob->main_stream, ref); |
495 | |
496 bp = bitpack_create (ob->main_stream); | |
497 bp_pack_value (&bp, node->local.local, 1); | |
498 bp_pack_value (&bp, node->local.externally_visible, 1); | |
499 bp_pack_value (&bp, node->local.finalized, 1); | |
500 bp_pack_value (&bp, node->local.inlinable, 1); | |
501 bp_pack_value (&bp, node->local.versionable, 1); | |
502 bp_pack_value (&bp, node->local.can_change_signature, 1); | |
503 bp_pack_value (&bp, node->local.disregard_inline_limits, 1); | |
504 bp_pack_value (&bp, node->local.redefined_extern_inline, 1); | |
505 bp_pack_value (&bp, node->local.vtable_method, 1); | |
506 bp_pack_value (&bp, node->needed, 1); | |
507 bp_pack_value (&bp, node->address_taken, 1); | |
508 bp_pack_value (&bp, node->abstract_and_needed, 1); | |
509 bp_pack_value (&bp, tag == LTO_cgraph_analyzed_node | |
510 && !DECL_EXTERNAL (node->decl) | |
511 && !DECL_COMDAT (node->decl) | |
512 && (reachable_from_other_partition_p (node, set) | |
513 || referenced_from_other_partition_p (&node->ref_list, set, vset)), 1); | |
514 bp_pack_value (&bp, node->lowered, 1); | |
515 bp_pack_value (&bp, in_other_partition, 1); | |
516 bp_pack_value (&bp, node->alias, 1); | |
517 bp_pack_value (&bp, node->finalized_by_frontend, 1); | |
518 bp_pack_value (&bp, node->frequency, 2); | |
519 bp_pack_value (&bp, node->only_called_at_startup, 1); | |
520 bp_pack_value (&bp, node->only_called_at_exit, 1); | |
521 lto_output_bitpack (&bp); | |
522 lto_output_uleb128_stream (ob->main_stream, node->resolution); | |
524 | 523 |
525 if (node->same_body) | 524 if (node->same_body) |
526 { | 525 { |
527 struct cgraph_node *alias; | 526 struct cgraph_node *alias; |
528 unsigned long alias_count = 1; | 527 unsigned long alias_count = 1; |
550 { | 549 { |
551 lto_output_uleb128_stream (ob->main_stream, 0); | 550 lto_output_uleb128_stream (ob->main_stream, 0); |
552 lto_output_fn_decl_index (ob->decl_state, ob->main_stream, | 551 lto_output_fn_decl_index (ob->decl_state, ob->main_stream, |
553 alias->thunk.alias); | 552 alias->thunk.alias); |
554 } | 553 } |
554 gcc_assert (cgraph_get_node (alias->thunk.alias) == node); | |
555 lto_output_uleb128_stream (ob->main_stream, alias->resolution); | |
555 alias = alias->previous; | 556 alias = alias->previous; |
556 } | 557 } |
557 while (alias); | 558 while (alias); |
558 } | 559 } |
559 else | 560 else |
567 lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node *node, | 568 lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node *node, |
568 lto_varpool_encoder_t varpool_encoder, | 569 lto_varpool_encoder_t varpool_encoder, |
569 cgraph_node_set set, varpool_node_set vset) | 570 cgraph_node_set set, varpool_node_set vset) |
570 { | 571 { |
571 bool boundary_p = !varpool_node_in_set_p (node, vset) && node->analyzed; | 572 bool boundary_p = !varpool_node_in_set_p (node, vset) && node->analyzed; |
572 struct bitpack_d *bp; | 573 struct bitpack_d bp; |
573 struct varpool_node *alias; | 574 struct varpool_node *alias; |
574 int count = 0; | 575 int count = 0; |
575 int ref; | 576 int ref; |
576 | 577 |
577 lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->decl); | 578 lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->decl); |
578 bp = bitpack_create (); | 579 bp = bitpack_create (ob->main_stream); |
579 bp_pack_value (bp, node->externally_visible, 1); | 580 bp_pack_value (&bp, node->externally_visible, 1); |
580 bp_pack_value (bp, node->force_output, 1); | 581 bp_pack_value (&bp, node->force_output, 1); |
581 bp_pack_value (bp, node->finalized, 1); | 582 bp_pack_value (&bp, node->finalized, 1); |
582 bp_pack_value (bp, node->alias, 1); | 583 bp_pack_value (&bp, node->alias, 1); |
583 gcc_assert (!node->alias || !node->extra_name); | 584 gcc_assert (!node->alias || !node->extra_name); |
584 gcc_assert (node->finalized || !node->analyzed); | 585 gcc_assert (node->finalized || !node->analyzed); |
585 gcc_assert (node->needed); | 586 gcc_assert (node->needed); |
586 /* Constant pool initializers can be de-unified into individual ltrans units. | 587 /* Constant pool initializers can be de-unified into individual ltrans units. |
587 FIXME: Alternatively at -Os we may want to avoid generating for them the local | 588 FIXME: Alternatively at -Os we may want to avoid generating for them the local |
588 labels and share them across LTRANS partitions. */ | 589 labels and share them across LTRANS partitions. */ |
589 if (DECL_IN_CONSTANT_POOL (node->decl)) | 590 if (DECL_IN_CONSTANT_POOL (node->decl) |
590 { | 591 && !DECL_COMDAT (node->decl)) |
591 bp_pack_value (bp, 0, 1); /* used_from_other_parition. */ | 592 { |
592 bp_pack_value (bp, 0, 1); /* in_other_partition. */ | 593 bp_pack_value (&bp, 0, 1); /* used_from_other_parition. */ |
594 bp_pack_value (&bp, 0, 1); /* in_other_partition. */ | |
593 } | 595 } |
594 else | 596 else |
595 { | 597 { |
596 bp_pack_value (bp, node->analyzed | 598 bp_pack_value (&bp, node->analyzed |
597 && referenced_from_other_partition_p (&node->ref_list, | 599 && referenced_from_other_partition_p (&node->ref_list, |
598 set, vset), 1); | 600 set, vset), 1); |
599 bp_pack_value (bp, boundary_p, 1); /* in_other_partition. */ | 601 bp_pack_value (&bp, boundary_p, 1); /* in_other_partition. */ |
600 } | 602 } |
601 /* Also emit any extra name aliases. */ | 603 /* Also emit any extra name aliases. */ |
602 for (alias = node->extra_name; alias; alias = alias->next) | 604 for (alias = node->extra_name; alias; alias = alias->next) |
603 count++; | 605 count++; |
604 bp_pack_value (bp, count != 0, 1); | 606 bp_pack_value (&bp, count != 0, 1); |
605 lto_output_bitpack (ob->main_stream, bp); | 607 lto_output_bitpack (&bp); |
606 bitpack_delete (bp); | |
607 if (node->same_comdat_group && !boundary_p) | 608 if (node->same_comdat_group && !boundary_p) |
608 { | 609 { |
609 ref = lto_varpool_encoder_lookup (varpool_encoder, node->same_comdat_group); | 610 ref = lto_varpool_encoder_lookup (varpool_encoder, node->same_comdat_group); |
610 gcc_assert (ref != LCC_NOT_FOUND); | 611 gcc_assert (ref != LCC_NOT_FOUND); |
611 } | 612 } |
612 else | 613 else |
613 ref = LCC_NOT_FOUND; | 614 ref = LCC_NOT_FOUND; |
614 lto_output_sleb128_stream (ob->main_stream, ref); | 615 lto_output_sleb128_stream (ob->main_stream, ref); |
616 lto_output_uleb128_stream (ob->main_stream, node->resolution); | |
615 | 617 |
616 if (count) | 618 if (count) |
617 { | 619 { |
618 lto_output_uleb128_stream (ob->main_stream, count); | 620 lto_output_uleb128_stream (ob->main_stream, count); |
619 for (alias = node->extra_name; alias; alias = alias->next) | 621 for (alias = node->extra_name; alias; alias = alias->next) |
620 lto_output_var_decl_index (ob->decl_state, ob->main_stream, alias->decl); | 622 { |
623 lto_output_var_decl_index (ob->decl_state, ob->main_stream, alias->decl); | |
624 lto_output_uleb128_stream (ob->main_stream, alias->resolution); | |
625 } | |
621 } | 626 } |
622 } | 627 } |
623 | 628 |
624 /* Output the varpool NODE to OB. | 629 /* Output the varpool NODE to OB. |
625 If NODE is not in SET, then NODE is a boundary. */ | 630 If NODE is not in SET, then NODE is a boundary. */ |
627 static void | 632 static void |
628 lto_output_ref (struct lto_simple_output_block *ob, struct ipa_ref *ref, | 633 lto_output_ref (struct lto_simple_output_block *ob, struct ipa_ref *ref, |
629 lto_cgraph_encoder_t encoder, | 634 lto_cgraph_encoder_t encoder, |
630 lto_varpool_encoder_t varpool_encoder) | 635 lto_varpool_encoder_t varpool_encoder) |
631 { | 636 { |
632 struct bitpack_d *bp = bitpack_create (); | 637 struct bitpack_d bp; |
633 bp_pack_value (bp, ref->refered_type, 1); | 638 bp = bitpack_create (ob->main_stream); |
634 bp_pack_value (bp, ref->use, 2); | 639 bp_pack_value (&bp, ref->refered_type, 1); |
635 lto_output_bitpack (ob->main_stream, bp); | 640 bp_pack_value (&bp, ref->use, 2); |
636 bitpack_delete (bp); | 641 lto_output_bitpack (&bp); |
637 if (ref->refered_type == IPA_REF_CGRAPH) | 642 if (ref->refered_type == IPA_REF_CGRAPH) |
638 { | 643 { |
639 int nref = lto_cgraph_encoder_lookup (encoder, ipa_ref_node (ref)); | 644 int nref = lto_cgraph_encoder_lookup (encoder, ipa_ref_node (ref)); |
640 gcc_assert (nref != LCC_NOT_FOUND); | 645 gcc_assert (nref != LCC_NOT_FOUND); |
641 lto_output_sleb128_stream (ob->main_stream, nref); | 646 lto_output_sleb128_stream (ob->main_stream, nref); |
654 static void | 659 static void |
655 output_profile_summary (struct lto_simple_output_block *ob) | 660 output_profile_summary (struct lto_simple_output_block *ob) |
656 { | 661 { |
657 if (profile_info) | 662 if (profile_info) |
658 { | 663 { |
659 /* We do not output num, it is not terribly useful. */ | 664 /* We do not output num, sum_all and run_max, they are not used by |
665 GCC profile feedback and they are difficult to merge from multiple | |
666 units. */ | |
660 gcc_assert (profile_info->runs); | 667 gcc_assert (profile_info->runs); |
661 lto_output_uleb128_stream (ob->main_stream, profile_info->runs); | 668 lto_output_uleb128_stream (ob->main_stream, profile_info->runs); |
662 lto_output_sleb128_stream (ob->main_stream, profile_info->sum_all); | 669 lto_output_uleb128_stream (ob->main_stream, profile_info->sum_max); |
663 lto_output_sleb128_stream (ob->main_stream, profile_info->run_max); | |
664 lto_output_sleb128_stream (ob->main_stream, profile_info->sum_max); | |
665 } | 670 } |
666 else | 671 else |
667 lto_output_uleb128_stream (ob->main_stream, 0); | 672 lto_output_uleb128_stream (ob->main_stream, 0); |
668 } | 673 } |
669 | 674 |
812 { | 817 { |
813 struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i); | 818 struct varpool_node *vnode = lto_varpool_encoder_deref (varpool_encoder, i); |
814 if (DECL_INITIAL (vnode->decl) | 819 if (DECL_INITIAL (vnode->decl) |
815 && !lto_varpool_encoder_encode_initializer_p (varpool_encoder, | 820 && !lto_varpool_encoder_encode_initializer_p (varpool_encoder, |
816 vnode) | 821 vnode) |
817 && (DECL_IN_CONSTANT_POOL (vnode->decl) | 822 && const_value_known_p (vnode->decl)) |
818 || TREE_READONLY (vnode->decl))) | |
819 { | 823 { |
820 lto_set_varpool_encoder_encode_initializer (varpool_encoder, vnode); | 824 lto_set_varpool_encoder_encode_initializer (varpool_encoder, vnode); |
821 add_references (encoder, varpool_encoder, &vnode->ref_list); | 825 add_references (encoder, varpool_encoder, &vnode->ref_list); |
822 } | 826 } |
823 } | 827 } |
850 cgraph_node_set_iterator csi; | 854 cgraph_node_set_iterator csi; |
851 int i, n_nodes; | 855 int i, n_nodes; |
852 lto_cgraph_encoder_t encoder; | 856 lto_cgraph_encoder_t encoder; |
853 lto_varpool_encoder_t varpool_encoder; | 857 lto_varpool_encoder_t varpool_encoder; |
854 struct cgraph_asm_node *can; | 858 struct cgraph_asm_node *can; |
859 static bool asm_nodes_output = false; | |
855 | 860 |
856 if (flag_wpa) | 861 if (flag_wpa) |
857 output_cgraph_opt_summary (); | 862 output_cgraph_opt_summary (set); |
858 | 863 |
859 ob = lto_create_simple_output_block (LTO_section_cgraph); | 864 ob = lto_create_simple_output_block (LTO_section_cgraph); |
860 | 865 |
861 output_profile_summary (ob); | 866 output_profile_summary (ob); |
862 | 867 |
885 output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder); | 890 output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder); |
886 } | 891 } |
887 | 892 |
888 lto_output_uleb128_stream (ob->main_stream, 0); | 893 lto_output_uleb128_stream (ob->main_stream, 0); |
889 | 894 |
890 /* Emit toplevel asms. */ | 895 /* Emit toplevel asms. |
891 for (can = cgraph_asm_nodes; can; can = can->next) | 896 When doing WPA we must output every asm just once. Since we do not partition asm |
892 { | 897 nodes at all, output them to first output. This is kind of hack, but should work |
893 int len = TREE_STRING_LENGTH (can->asm_str); | 898 well. */ |
894 lto_output_uleb128_stream (ob->main_stream, len); | 899 if (!asm_nodes_output) |
895 for (i = 0; i < len; ++i) | 900 { |
896 lto_output_1_stream (ob->main_stream, | 901 asm_nodes_output = true; |
897 TREE_STRING_POINTER (can->asm_str)[i]); | 902 for (can = cgraph_asm_nodes; can; can = can->next) |
903 { | |
904 int len = TREE_STRING_LENGTH (can->asm_str); | |
905 lto_output_uleb128_stream (ob->main_stream, len); | |
906 for (i = 0; i < len; ++i) | |
907 lto_output_1_stream (ob->main_stream, | |
908 TREE_STRING_POINTER (can->asm_str)[i]); | |
909 } | |
898 } | 910 } |
899 | 911 |
900 lto_output_uleb128_stream (ob->main_stream, 0); | 912 lto_output_uleb128_stream (ob->main_stream, 0); |
901 | 913 |
902 lto_destroy_simple_output_block (ob); | 914 lto_destroy_simple_output_block (ob); |
918 struct bitpack_d *bp, | 930 struct bitpack_d *bp, |
919 unsigned int stack_size, | 931 unsigned int stack_size, |
920 unsigned int self_time, | 932 unsigned int self_time, |
921 unsigned int time_inlining_benefit, | 933 unsigned int time_inlining_benefit, |
922 unsigned int self_size, | 934 unsigned int self_size, |
923 unsigned int size_inlining_benefit) | 935 unsigned int size_inlining_benefit, |
936 enum ld_plugin_symbol_resolution resolution) | |
924 { | 937 { |
925 node->aux = (void *) tag; | 938 node->aux = (void *) tag; |
926 node->local.inline_summary.estimated_self_stack_size = stack_size; | 939 node->local.inline_summary.estimated_self_stack_size = stack_size; |
927 node->local.inline_summary.self_time = self_time; | 940 node->local.inline_summary.self_time = self_time; |
928 node->local.inline_summary.time_inlining_benefit = time_inlining_benefit; | 941 node->local.inline_summary.time_inlining_benefit = time_inlining_benefit; |
937 node->local.local = bp_unpack_value (bp, 1); | 950 node->local.local = bp_unpack_value (bp, 1); |
938 node->local.externally_visible = bp_unpack_value (bp, 1); | 951 node->local.externally_visible = bp_unpack_value (bp, 1); |
939 node->local.finalized = bp_unpack_value (bp, 1); | 952 node->local.finalized = bp_unpack_value (bp, 1); |
940 node->local.inlinable = bp_unpack_value (bp, 1); | 953 node->local.inlinable = bp_unpack_value (bp, 1); |
941 node->local.versionable = bp_unpack_value (bp, 1); | 954 node->local.versionable = bp_unpack_value (bp, 1); |
955 node->local.can_change_signature = bp_unpack_value (bp, 1); | |
942 node->local.disregard_inline_limits = bp_unpack_value (bp, 1); | 956 node->local.disregard_inline_limits = bp_unpack_value (bp, 1); |
943 node->local.redefined_extern_inline = bp_unpack_value (bp, 1); | 957 node->local.redefined_extern_inline = bp_unpack_value (bp, 1); |
944 node->local.vtable_method = bp_unpack_value (bp, 1); | 958 node->local.vtable_method = bp_unpack_value (bp, 1); |
945 node->needed = bp_unpack_value (bp, 1); | 959 node->needed = bp_unpack_value (bp, 1); |
946 node->address_taken = bp_unpack_value (bp, 1); | 960 node->address_taken = bp_unpack_value (bp, 1); |
947 node->abstract_and_needed = bp_unpack_value (bp, 1); | 961 node->abstract_and_needed = bp_unpack_value (bp, 1); |
948 node->reachable_from_other_partition = bp_unpack_value (bp, 1); | 962 node->reachable_from_other_partition = bp_unpack_value (bp, 1); |
949 node->lowered = bp_unpack_value (bp, 1); | 963 node->lowered = bp_unpack_value (bp, 1); |
950 node->analyzed = tag == LTO_cgraph_analyzed_node; | 964 node->analyzed = tag == LTO_cgraph_analyzed_node; |
951 node->in_other_partition = bp_unpack_value (bp, 1); | 965 node->in_other_partition = bp_unpack_value (bp, 1); |
966 if (node->in_other_partition | |
967 /* Avoid updating decl when we are seeing just inline clone. | |
968 When inlining function that has functions already inlined into it, | |
969 we produce clones of inline clones. | |
970 | |
971 WPA partitioning might put each clone into different unit and | |
972 we might end up streaming inline clone from other partition | |
973 to support clone we are interested in. */ | |
974 && (!node->clone_of | |
975 || node->clone_of->decl != node->decl)) | |
976 { | |
977 DECL_EXTERNAL (node->decl) = 1; | |
978 TREE_STATIC (node->decl) = 0; | |
979 } | |
952 node->alias = bp_unpack_value (bp, 1); | 980 node->alias = bp_unpack_value (bp, 1); |
953 node->finalized_by_frontend = bp_unpack_value (bp, 1); | 981 node->finalized_by_frontend = bp_unpack_value (bp, 1); |
954 node->frequency = (enum node_frequency)bp_unpack_value (bp, 2); | 982 node->frequency = (enum node_frequency)bp_unpack_value (bp, 2); |
983 node->only_called_at_startup = bp_unpack_value (bp, 1); | |
984 node->only_called_at_exit = bp_unpack_value (bp, 1); | |
985 node->resolution = resolution; | |
955 } | 986 } |
956 | 987 |
957 /* Output the part of the cgraph in SET. */ | 988 /* Output the part of the cgraph in SET. */ |
958 | 989 |
959 static void | 990 static void |
987 enum LTO_cgraph_tags tag, | 1018 enum LTO_cgraph_tags tag, |
988 VEC(cgraph_node_ptr, heap) *nodes) | 1019 VEC(cgraph_node_ptr, heap) *nodes) |
989 { | 1020 { |
990 tree fn_decl; | 1021 tree fn_decl; |
991 struct cgraph_node *node; | 1022 struct cgraph_node *node; |
992 struct bitpack_d *bp; | 1023 struct bitpack_d bp; |
993 int stack_size = 0; | 1024 int stack_size = 0; |
994 unsigned decl_index; | 1025 unsigned decl_index; |
995 int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND; | 1026 int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND; |
996 int self_time = 0; | 1027 int self_time = 0; |
997 int self_size = 0; | 1028 int self_size = 0; |
998 int time_inlining_benefit = 0; | 1029 int time_inlining_benefit = 0; |
999 int size_inlining_benefit = 0; | 1030 int size_inlining_benefit = 0; |
1000 unsigned long same_body_count = 0; | 1031 unsigned long same_body_count = 0; |
1001 int clone_ref; | 1032 int clone_ref; |
1033 enum ld_plugin_symbol_resolution resolution; | |
1002 | 1034 |
1003 clone_ref = lto_input_sleb128 (ib); | 1035 clone_ref = lto_input_sleb128 (ib); |
1004 | 1036 |
1005 decl_index = lto_input_uleb128 (ib); | 1037 decl_index = lto_input_uleb128 (ib); |
1006 fn_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index); | 1038 fn_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index); |
1012 } | 1044 } |
1013 else | 1045 else |
1014 node = cgraph_node (fn_decl); | 1046 node = cgraph_node (fn_decl); |
1015 | 1047 |
1016 node->count = lto_input_sleb128 (ib); | 1048 node->count = lto_input_sleb128 (ib); |
1017 bp = lto_input_bitpack (ib); | 1049 node->count_materialization_scale = lto_input_sleb128 (ib); |
1018 | 1050 |
1019 if (tag == LTO_cgraph_analyzed_node) | 1051 if (tag == LTO_cgraph_analyzed_node) |
1020 { | 1052 { |
1021 stack_size = lto_input_sleb128 (ib); | 1053 stack_size = lto_input_sleb128 (ib); |
1022 self_size = lto_input_sleb128 (ib); | 1054 self_size = lto_input_sleb128 (ib); |
1026 | 1058 |
1027 ref = lto_input_sleb128 (ib); | 1059 ref = lto_input_sleb128 (ib); |
1028 } | 1060 } |
1029 | 1061 |
1030 ref2 = lto_input_sleb128 (ib); | 1062 ref2 = lto_input_sleb128 (ib); |
1031 same_body_count = lto_input_uleb128 (ib); | |
1032 | 1063 |
1033 /* Make sure that we have not read this node before. Nodes that | 1064 /* Make sure that we have not read this node before. Nodes that |
1034 have already been read will have their tag stored in the 'aux' | 1065 have already been read will have their tag stored in the 'aux' |
1035 field. Since built-in functions can be referenced in multiple | 1066 field. Since built-in functions can be referenced in multiple |
1036 functions, they are expected to be read more than once. */ | 1067 functions, they are expected to be read more than once. */ |
1037 if (node->aux && !DECL_IS_BUILTIN (node->decl)) | 1068 if (node->aux && !DECL_IS_BUILTIN (node->decl)) |
1038 internal_error ("bytecode stream: found multiple instances of cgraph " | 1069 internal_error ("bytecode stream: found multiple instances of cgraph " |
1039 "node %d", node->uid); | 1070 "node %d", node->uid); |
1040 | 1071 |
1041 input_overwrite_node (file_data, node, tag, bp, stack_size, self_time, | 1072 bp = lto_input_bitpack (ib); |
1073 resolution = (enum ld_plugin_symbol_resolution)lto_input_uleb128 (ib); | |
1074 input_overwrite_node (file_data, node, tag, &bp, stack_size, self_time, | |
1042 time_inlining_benefit, self_size, | 1075 time_inlining_benefit, self_size, |
1043 size_inlining_benefit); | 1076 size_inlining_benefit, resolution); |
1044 bitpack_delete (bp); | |
1045 | 1077 |
1046 /* Store a reference for now, and fix up later to be a pointer. */ | 1078 /* Store a reference for now, and fix up later to be a pointer. */ |
1047 node->global.inlined_to = (cgraph_node_ptr) (intptr_t) ref; | 1079 node->global.inlined_to = (cgraph_node_ptr) (intptr_t) ref; |
1048 | 1080 |
1049 /* Store a reference for now, and fix up later to be a pointer. */ | 1081 /* Store a reference for now, and fix up later to be a pointer. */ |
1050 node->same_comdat_group = (cgraph_node_ptr) (intptr_t) ref2; | 1082 node->same_comdat_group = (cgraph_node_ptr) (intptr_t) ref2; |
1051 | 1083 |
1084 same_body_count = lto_input_uleb128 (ib); | |
1052 while (same_body_count-- > 0) | 1085 while (same_body_count-- > 0) |
1053 { | 1086 { |
1054 tree alias_decl; | 1087 tree alias_decl; |
1055 int type; | 1088 int type; |
1089 struct cgraph_node *alias; | |
1056 decl_index = lto_input_uleb128 (ib); | 1090 decl_index = lto_input_uleb128 (ib); |
1057 alias_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index); | 1091 alias_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index); |
1058 type = lto_input_uleb128 (ib); | 1092 type = lto_input_uleb128 (ib); |
1059 if (!type) | 1093 if (!type) |
1060 { | 1094 { |
1061 tree real_alias; | 1095 tree real_alias; |
1062 decl_index = lto_input_uleb128 (ib); | 1096 decl_index = lto_input_uleb128 (ib); |
1063 real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index); | 1097 real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index); |
1064 cgraph_same_body_alias (alias_decl, real_alias); | 1098 alias = cgraph_same_body_alias (node, alias_decl, real_alias); |
1065 } | 1099 } |
1066 else | 1100 else |
1067 { | 1101 { |
1068 HOST_WIDE_INT fixed_offset = lto_input_uleb128 (ib); | 1102 HOST_WIDE_INT fixed_offset = lto_input_uleb128 (ib); |
1069 HOST_WIDE_INT virtual_value = lto_input_uleb128 (ib); | 1103 HOST_WIDE_INT virtual_value = lto_input_uleb128 (ib); |
1070 tree real_alias; | 1104 tree real_alias; |
1071 decl_index = lto_input_uleb128 (ib); | 1105 decl_index = lto_input_uleb128 (ib); |
1072 real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index); | 1106 real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index); |
1073 cgraph_add_thunk (alias_decl, fn_decl, type & 2, fixed_offset, | 1107 alias = cgraph_add_thunk (node, alias_decl, fn_decl, type & 2, fixed_offset, |
1074 virtual_value, | 1108 virtual_value, |
1075 (type & 4) ? size_int (virtual_value) : NULL_TREE, | 1109 (type & 4) ? size_int (virtual_value) : NULL_TREE, |
1076 real_alias); | 1110 real_alias); |
1077 } | 1111 } |
1112 gcc_assert (alias); | |
1113 alias->resolution = (enum ld_plugin_symbol_resolution)lto_input_uleb128 (ib); | |
1078 } | 1114 } |
1079 return node; | 1115 return node; |
1080 } | 1116 } |
1081 | 1117 |
1082 /* Read a node from input_block IB. TAG is the node's tag just read. | 1118 /* Read a node from input_block IB. TAG is the node's tag just read. |
1087 struct lto_input_block *ib) | 1123 struct lto_input_block *ib) |
1088 { | 1124 { |
1089 int decl_index; | 1125 int decl_index; |
1090 tree var_decl; | 1126 tree var_decl; |
1091 struct varpool_node *node; | 1127 struct varpool_node *node; |
1092 struct bitpack_d *bp; | 1128 struct bitpack_d bp; |
1093 bool aliases_p; | 1129 bool aliases_p; |
1094 int count; | 1130 int count; |
1095 int ref = LCC_NOT_FOUND; | 1131 int ref = LCC_NOT_FOUND; |
1096 | 1132 |
1097 decl_index = lto_input_uleb128 (ib); | 1133 decl_index = lto_input_uleb128 (ib); |
1098 var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index); | 1134 var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index); |
1099 node = varpool_node (var_decl); | 1135 node = varpool_node (var_decl); |
1136 node->lto_file_data = file_data; | |
1100 | 1137 |
1101 bp = lto_input_bitpack (ib); | 1138 bp = lto_input_bitpack (ib); |
1102 node->externally_visible = bp_unpack_value (bp, 1); | 1139 node->externally_visible = bp_unpack_value (&bp, 1); |
1103 node->force_output = bp_unpack_value (bp, 1); | 1140 node->force_output = bp_unpack_value (&bp, 1); |
1104 node->finalized = bp_unpack_value (bp, 1); | 1141 node->finalized = bp_unpack_value (&bp, 1); |
1105 node->alias = bp_unpack_value (bp, 1); | 1142 node->alias = bp_unpack_value (&bp, 1); |
1106 node->analyzed = node->finalized; | 1143 node->analyzed = node->finalized; |
1107 node->used_from_other_partition = bp_unpack_value (bp, 1); | 1144 node->used_from_other_partition = bp_unpack_value (&bp, 1); |
1108 node->in_other_partition = bp_unpack_value (bp, 1); | 1145 node->in_other_partition = bp_unpack_value (&bp, 1); |
1109 aliases_p = bp_unpack_value (bp, 1); | 1146 if (node->in_other_partition) |
1147 { | |
1148 DECL_EXTERNAL (node->decl) = 1; | |
1149 TREE_STATIC (node->decl) = 0; | |
1150 } | |
1151 aliases_p = bp_unpack_value (&bp, 1); | |
1110 if (node->finalized) | 1152 if (node->finalized) |
1111 varpool_mark_needed_node (node); | 1153 varpool_mark_needed_node (node); |
1112 bitpack_delete (bp); | |
1113 ref = lto_input_sleb128 (ib); | 1154 ref = lto_input_sleb128 (ib); |
1114 /* Store a reference for now, and fix up later to be a pointer. */ | 1155 /* Store a reference for now, and fix up later to be a pointer. */ |
1115 node->same_comdat_group = (struct varpool_node *) (intptr_t) ref; | 1156 node->same_comdat_group = (struct varpool_node *) (intptr_t) ref; |
1157 node->resolution = (enum ld_plugin_symbol_resolution)lto_input_uleb128 (ib); | |
1116 if (aliases_p) | 1158 if (aliases_p) |
1117 { | 1159 { |
1118 count = lto_input_uleb128 (ib); | 1160 count = lto_input_uleb128 (ib); |
1119 for (; count > 0; count --) | 1161 for (; count > 0; count --) |
1120 { | 1162 { |
1121 tree decl = lto_file_decl_data_get_var_decl (file_data, | 1163 tree decl = lto_file_decl_data_get_var_decl (file_data, |
1122 lto_input_uleb128 (ib)); | 1164 lto_input_uleb128 (ib)); |
1123 varpool_extra_name_alias (decl, var_decl); | 1165 struct varpool_node *alias; |
1166 alias = varpool_extra_name_alias (decl, var_decl); | |
1167 alias->resolution = (enum ld_plugin_symbol_resolution)lto_input_uleb128 (ib); | |
1124 } | 1168 } |
1125 } | 1169 } |
1126 return node; | 1170 return node; |
1127 } | 1171 } |
1128 | 1172 |
1136 VEC(cgraph_node_ptr, heap) *nodes, | 1180 VEC(cgraph_node_ptr, heap) *nodes, |
1137 VEC(varpool_node_ptr, heap) *varpool_nodes) | 1181 VEC(varpool_node_ptr, heap) *varpool_nodes) |
1138 { | 1182 { |
1139 struct cgraph_node *node = NULL; | 1183 struct cgraph_node *node = NULL; |
1140 struct varpool_node *varpool_node = NULL; | 1184 struct varpool_node *varpool_node = NULL; |
1141 struct bitpack_d *bp; | 1185 struct bitpack_d bp; |
1142 enum ipa_ref_type type; | 1186 enum ipa_ref_type type; |
1143 enum ipa_ref_use use; | 1187 enum ipa_ref_use use; |
1144 | 1188 |
1145 bp = lto_input_bitpack (ib); | 1189 bp = lto_input_bitpack (ib); |
1146 type = (enum ipa_ref_type) bp_unpack_value (bp, 1); | 1190 type = (enum ipa_ref_type) bp_unpack_value (&bp, 1); |
1147 use = (enum ipa_ref_use) bp_unpack_value (bp, 2); | 1191 use = (enum ipa_ref_use) bp_unpack_value (&bp, 2); |
1148 bitpack_delete (bp); | |
1149 if (type == IPA_REF_CGRAPH) | 1192 if (type == IPA_REF_CGRAPH) |
1150 node = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib)); | 1193 node = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib)); |
1151 else | 1194 else |
1152 varpool_node = VEC_index (varpool_node_ptr, varpool_nodes, lto_input_sleb128 (ib)); | 1195 varpool_node = VEC_index (varpool_node_ptr, varpool_nodes, lto_input_sleb128 (ib)); |
1153 ipa_record_reference (refering_node, refering_varpool_node, | 1196 ipa_record_reference (refering_node, refering_varpool_node, |
1168 unsigned int stmt_id; | 1211 unsigned int stmt_id; |
1169 gcov_type count; | 1212 gcov_type count; |
1170 int freq; | 1213 int freq; |
1171 unsigned int nest; | 1214 unsigned int nest; |
1172 cgraph_inline_failed_t inline_failed; | 1215 cgraph_inline_failed_t inline_failed; |
1173 struct bitpack_d *bp; | 1216 struct bitpack_d bp; |
1174 enum ld_plugin_symbol_resolution caller_resolution; | |
1175 int ecf_flags = 0; | 1217 int ecf_flags = 0; |
1176 | 1218 |
1177 caller = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib)); | 1219 caller = VEC_index (cgraph_node_ptr, nodes, lto_input_sleb128 (ib)); |
1178 if (caller == NULL || caller->decl == NULL_TREE) | 1220 if (caller == NULL || caller->decl == NULL_TREE) |
1179 internal_error ("bytecode stream: no caller found while reading edge"); | 1221 internal_error ("bytecode stream: no caller found while reading edge"); |
1188 callee = NULL; | 1230 callee = NULL; |
1189 | 1231 |
1190 count = (gcov_type) lto_input_sleb128 (ib); | 1232 count = (gcov_type) lto_input_sleb128 (ib); |
1191 | 1233 |
1192 bp = lto_input_bitpack (ib); | 1234 bp = lto_input_bitpack (ib); |
1193 stmt_id = (unsigned int) bp_unpack_value (bp, HOST_BITS_PER_INT); | 1235 stmt_id = (unsigned int) bp_unpack_value (&bp, HOST_BITS_PER_INT); |
1194 inline_failed = (cgraph_inline_failed_t) bp_unpack_value (bp, | 1236 inline_failed = (cgraph_inline_failed_t) bp_unpack_value (&bp, |
1195 HOST_BITS_PER_INT); | 1237 HOST_BITS_PER_INT); |
1196 freq = (int) bp_unpack_value (bp, HOST_BITS_PER_INT); | 1238 freq = (int) bp_unpack_value (&bp, HOST_BITS_PER_INT); |
1197 nest = (unsigned) bp_unpack_value (bp, 30); | 1239 nest = (unsigned) bp_unpack_value (&bp, 30); |
1198 | |
1199 /* If the caller was preempted, don't create the edge. | |
1200 ??? Should we ever have edges from a preempted caller? */ | |
1201 caller_resolution = lto_symtab_get_resolution (caller->decl); | |
1202 if (caller_resolution == LDPR_PREEMPTED_REG | |
1203 || caller_resolution == LDPR_PREEMPTED_IR) | |
1204 return; | |
1205 | 1240 |
1206 if (indirect) | 1241 if (indirect) |
1207 edge = cgraph_create_indirect_edge (caller, NULL, 0, count, freq, nest); | 1242 edge = cgraph_create_indirect_edge (caller, NULL, 0, count, freq, nest); |
1208 else | 1243 else |
1209 edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest); | 1244 edge = cgraph_create_edge (caller, callee, NULL, count, freq, nest); |
1210 | 1245 |
1211 edge->indirect_inlining_edge = bp_unpack_value (bp, 1); | 1246 edge->indirect_inlining_edge = bp_unpack_value (&bp, 1); |
1212 edge->lto_stmt_uid = stmt_id; | 1247 edge->lto_stmt_uid = stmt_id; |
1213 edge->inline_failed = inline_failed; | 1248 edge->inline_failed = inline_failed; |
1214 edge->call_stmt_cannot_inline_p = bp_unpack_value (bp, 1); | 1249 edge->call_stmt_cannot_inline_p = bp_unpack_value (&bp, 1); |
1215 edge->can_throw_external = bp_unpack_value (bp, 1); | 1250 edge->can_throw_external = bp_unpack_value (&bp, 1); |
1216 if (indirect) | 1251 if (indirect) |
1217 { | 1252 { |
1218 if (bp_unpack_value (bp, 1)) | 1253 if (bp_unpack_value (&bp, 1)) |
1219 ecf_flags |= ECF_CONST; | 1254 ecf_flags |= ECF_CONST; |
1220 if (bp_unpack_value (bp, 1)) | 1255 if (bp_unpack_value (&bp, 1)) |
1221 ecf_flags |= ECF_PURE; | 1256 ecf_flags |= ECF_PURE; |
1222 if (bp_unpack_value (bp, 1)) | 1257 if (bp_unpack_value (&bp, 1)) |
1223 ecf_flags |= ECF_NORETURN; | 1258 ecf_flags |= ECF_NORETURN; |
1224 if (bp_unpack_value (bp, 1)) | 1259 if (bp_unpack_value (&bp, 1)) |
1225 ecf_flags |= ECF_MALLOC; | 1260 ecf_flags |= ECF_MALLOC; |
1226 if (bp_unpack_value (bp, 1)) | 1261 if (bp_unpack_value (&bp, 1)) |
1227 ecf_flags |= ECF_NOTHROW; | 1262 ecf_flags |= ECF_NOTHROW; |
1228 if (bp_unpack_value (bp, 1)) | 1263 if (bp_unpack_value (&bp, 1)) |
1229 ecf_flags |= ECF_RETURNS_TWICE; | 1264 ecf_flags |= ECF_RETURNS_TWICE; |
1230 edge->indirect_info->ecf_flags = ecf_flags; | 1265 edge->indirect_info->ecf_flags = ecf_flags; |
1231 } | 1266 } |
1232 bitpack_delete (bp); | |
1233 } | 1267 } |
1234 | 1268 |
1235 | 1269 |
1236 /* Read a cgraph from IB using the info in FILE_DATA. */ | 1270 /* Read a cgraph from IB using the info in FILE_DATA. */ |
1237 | 1271 |
1274 cgraph_add_asm_node (build_string (len, str)); | 1308 cgraph_add_asm_node (build_string (len, str)); |
1275 free (str); | 1309 free (str); |
1276 | 1310 |
1277 len = lto_input_uleb128 (ib); | 1311 len = lto_input_uleb128 (ib); |
1278 } | 1312 } |
1279 | 1313 /* AUX pointers should be all non-zero for nodes read from the stream. */ |
1280 for (i = 0; VEC_iterate (cgraph_node_ptr, nodes, i, node); i++) | 1314 #ifdef ENABLE_CHECKING |
1315 FOR_EACH_VEC_ELT (cgraph_node_ptr, nodes, i, node) | |
1316 gcc_assert (node->aux); | |
1317 #endif | |
1318 FOR_EACH_VEC_ELT (cgraph_node_ptr, nodes, i, node) | |
1281 { | 1319 { |
1282 int ref = (int) (intptr_t) node->global.inlined_to; | 1320 int ref = (int) (intptr_t) node->global.inlined_to; |
1321 | |
1322 /* We share declaration of builtins, so we may read same node twice. */ | |
1323 if (!node->aux) | |
1324 continue; | |
1325 node->aux = NULL; | |
1283 | 1326 |
1284 /* Fixup inlined_to from reference to pointer. */ | 1327 /* Fixup inlined_to from reference to pointer. */ |
1285 if (ref != LCC_NOT_FOUND) | 1328 if (ref != LCC_NOT_FOUND) |
1286 node->global.inlined_to = VEC_index (cgraph_node_ptr, nodes, ref); | 1329 node->global.inlined_to = VEC_index (cgraph_node_ptr, nodes, ref); |
1287 else | 1330 else |
1293 if (ref != LCC_NOT_FOUND) | 1336 if (ref != LCC_NOT_FOUND) |
1294 node->same_comdat_group = VEC_index (cgraph_node_ptr, nodes, ref); | 1337 node->same_comdat_group = VEC_index (cgraph_node_ptr, nodes, ref); |
1295 else | 1338 else |
1296 node->same_comdat_group = NULL; | 1339 node->same_comdat_group = NULL; |
1297 } | 1340 } |
1341 FOR_EACH_VEC_ELT (cgraph_node_ptr, nodes, i, node) | |
1342 node->aux = (void *)1; | |
1298 return nodes; | 1343 return nodes; |
1299 } | 1344 } |
1300 | 1345 |
1301 /* Read a varpool from IB using the info in FILE_DATA. */ | 1346 /* Read a varpool from IB using the info in FILE_DATA. */ |
1302 | 1347 |
1314 { | 1359 { |
1315 VEC_safe_push (varpool_node_ptr, heap, varpool, | 1360 VEC_safe_push (varpool_node_ptr, heap, varpool, |
1316 input_varpool_node (file_data, ib)); | 1361 input_varpool_node (file_data, ib)); |
1317 len--; | 1362 len--; |
1318 } | 1363 } |
1319 for (i = 0; VEC_iterate (varpool_node_ptr, varpool, i, node); i++) | 1364 #ifdef ENABLE_CHECKING |
1365 FOR_EACH_VEC_ELT (varpool_node_ptr, varpool, i, node) | |
1366 gcc_assert (!node->aux); | |
1367 #endif | |
1368 FOR_EACH_VEC_ELT (varpool_node_ptr, varpool, i, node) | |
1320 { | 1369 { |
1321 int ref = (int) (intptr_t) node->same_comdat_group; | 1370 int ref = (int) (intptr_t) node->same_comdat_group; |
1371 /* We share declaration of builtins, so we may read same node twice. */ | |
1372 if (node->aux) | |
1373 continue; | |
1374 node->aux = (void *)1; | |
1322 | 1375 |
1323 /* Fixup same_comdat_group from reference to pointer. */ | 1376 /* Fixup same_comdat_group from reference to pointer. */ |
1324 if (ref != LCC_NOT_FOUND) | 1377 if (ref != LCC_NOT_FOUND) |
1325 node->same_comdat_group = VEC_index (varpool_node_ptr, varpool, ref); | 1378 node->same_comdat_group = VEC_index (varpool_node_ptr, varpool, ref); |
1326 else | 1379 else |
1327 node->same_comdat_group = NULL; | 1380 node->same_comdat_group = NULL; |
1328 } | 1381 } |
1382 FOR_EACH_VEC_ELT (varpool_node_ptr, varpool, i, node) | |
1383 node->aux = NULL; | |
1329 return varpool; | 1384 return varpool; |
1330 } | 1385 } |
1331 | 1386 |
1332 /* Input ipa_refs. */ | 1387 /* Input ipa_refs. */ |
1333 | 1388 |
1370 | 1425 |
1371 static struct gcov_ctr_summary lto_gcov_summary; | 1426 static struct gcov_ctr_summary lto_gcov_summary; |
1372 | 1427 |
1373 /* Input profile_info from IB. */ | 1428 /* Input profile_info from IB. */ |
1374 static void | 1429 static void |
1375 input_profile_summary (struct lto_input_block *ib) | 1430 input_profile_summary (struct lto_input_block *ib, |
1431 struct lto_file_decl_data *file_data) | |
1376 { | 1432 { |
1377 unsigned int runs = lto_input_uleb128 (ib); | 1433 unsigned int runs = lto_input_uleb128 (ib); |
1378 if (runs) | 1434 if (runs) |
1379 { | 1435 { |
1380 if (!profile_info) | 1436 file_data->profile_info.runs = runs; |
1381 { | 1437 file_data->profile_info.sum_max = lto_input_uleb128 (ib); |
1382 profile_info = <o_gcov_summary; | 1438 } |
1383 lto_gcov_summary.runs = runs; | 1439 |
1384 lto_gcov_summary.sum_all = lto_input_sleb128 (ib); | 1440 } |
1385 lto_gcov_summary.run_max = lto_input_sleb128 (ib); | 1441 |
1386 lto_gcov_summary.sum_max = lto_input_sleb128 (ib); | 1442 /* Rescale profile summaries to the same number of runs in the whole unit. */ |
1387 } | 1443 |
1388 /* We can support this by scaling all counts to nearest common multiple | 1444 static void |
1389 of all different runs, but it is perhaps not worth the effort. */ | 1445 merge_profile_summaries (struct lto_file_decl_data **file_data_vec) |
1390 else if (profile_info->runs != runs | 1446 { |
1391 || profile_info->sum_all != lto_input_sleb128 (ib) | 1447 struct lto_file_decl_data *file_data; |
1392 || profile_info->run_max != lto_input_sleb128 (ib) | 1448 unsigned int j; |
1393 || profile_info->sum_max != lto_input_sleb128 (ib)) | 1449 gcov_unsigned_t max_runs = 0; |
1394 sorry ("Combining units with different profiles is not supported."); | 1450 struct cgraph_node *node; |
1395 /* We allow some units to have profile and other to not have one. This will | 1451 struct cgraph_edge *edge; |
1396 just make unprofiled units to be size optimized that is sane. */ | 1452 |
1397 } | 1453 /* Find unit with maximal number of runs. If we ever get serious about |
1398 | 1454 roundoff errors, we might also consider computing smallest common |
1455 multiply. */ | |
1456 for (j = 0; (file_data = file_data_vec[j]) != NULL; j++) | |
1457 if (max_runs < file_data->profile_info.runs) | |
1458 max_runs = file_data->profile_info.runs; | |
1459 | |
1460 if (!max_runs) | |
1461 return; | |
1462 | |
1463 /* Simple overflow check. We probably don't need to support that many train | |
1464 runs. Such a large value probably imply data corruption anyway. */ | |
1465 if (max_runs > INT_MAX / REG_BR_PROB_BASE) | |
1466 { | |
1467 sorry ("At most %i profile runs is supported. Perhaps corrupted profile?", | |
1468 INT_MAX / REG_BR_PROB_BASE); | |
1469 return; | |
1470 } | |
1471 | |
1472 profile_info = <o_gcov_summary; | |
1473 lto_gcov_summary.runs = max_runs; | |
1474 lto_gcov_summary.sum_max = 0; | |
1475 | |
1476 /* Rescale all units to the maximal number of runs. | |
1477 sum_max can not be easily merged, as we have no idea what files come from | |
1478 the same run. We do not use the info anyway, so leave it 0. */ | |
1479 for (j = 0; (file_data = file_data_vec[j]) != NULL; j++) | |
1480 if (file_data->profile_info.runs) | |
1481 { | |
1482 int scale = ((REG_BR_PROB_BASE * max_runs | |
1483 + file_data->profile_info.runs / 2) | |
1484 / file_data->profile_info.runs); | |
1485 lto_gcov_summary.sum_max = MAX (lto_gcov_summary.sum_max, | |
1486 (file_data->profile_info.sum_max | |
1487 * scale | |
1488 + REG_BR_PROB_BASE / 2) | |
1489 / REG_BR_PROB_BASE); | |
1490 } | |
1491 | |
1492 /* Watch roundoff errors. */ | |
1493 if (lto_gcov_summary.sum_max < max_runs) | |
1494 lto_gcov_summary.sum_max = max_runs; | |
1495 | |
1496 /* If merging already happent at WPA time, we are done. */ | |
1497 if (flag_ltrans) | |
1498 return; | |
1499 | |
1500 /* Now compute count_materialization_scale of each node. | |
1501 During LTRANS we already have values of count_materialization_scale | |
1502 computed, so just update them. */ | |
1503 for (node = cgraph_nodes; node; node = node->next) | |
1504 if (node->local.lto_file_data->profile_info.runs) | |
1505 { | |
1506 int scale; | |
1507 | |
1508 scale = | |
1509 ((node->count_materialization_scale * max_runs | |
1510 + node->local.lto_file_data->profile_info.runs / 2) | |
1511 / node->local.lto_file_data->profile_info.runs); | |
1512 node->count_materialization_scale = scale; | |
1513 if (scale < 0) | |
1514 fatal_error ("Profile information in %s corrupted", | |
1515 file_data->file_name); | |
1516 | |
1517 if (scale == REG_BR_PROB_BASE) | |
1518 continue; | |
1519 for (edge = node->callees; edge; edge = edge->next_callee) | |
1520 edge->count = ((edge->count * scale + REG_BR_PROB_BASE / 2) | |
1521 / REG_BR_PROB_BASE); | |
1522 node->count = ((node->count * scale + REG_BR_PROB_BASE / 2) | |
1523 / REG_BR_PROB_BASE); | |
1524 } | |
1399 } | 1525 } |
1400 | 1526 |
1401 /* Input and merge the cgraph from each of the .o files passed to | 1527 /* Input and merge the cgraph from each of the .o files passed to |
1402 lto1. */ | 1528 lto1. */ |
1403 | 1529 |
1417 VEC(cgraph_node_ptr, heap) *nodes; | 1543 VEC(cgraph_node_ptr, heap) *nodes; |
1418 VEC(varpool_node_ptr, heap) *varpool; | 1544 VEC(varpool_node_ptr, heap) *varpool; |
1419 | 1545 |
1420 ib = lto_create_simple_input_block (file_data, LTO_section_cgraph, | 1546 ib = lto_create_simple_input_block (file_data, LTO_section_cgraph, |
1421 &data, &len); | 1547 &data, &len); |
1422 input_profile_summary (ib); | 1548 if (!ib) |
1549 fatal_error ("cannot find LTO cgraph in %s", file_data->file_name); | |
1550 input_profile_summary (ib, file_data); | |
1423 file_data->cgraph_node_encoder = lto_cgraph_encoder_new (); | 1551 file_data->cgraph_node_encoder = lto_cgraph_encoder_new (); |
1424 nodes = input_cgraph_1 (file_data, ib); | 1552 nodes = input_cgraph_1 (file_data, ib); |
1425 lto_destroy_simple_input_block (file_data, LTO_section_cgraph, | 1553 lto_destroy_simple_input_block (file_data, LTO_section_cgraph, |
1426 ib, data, len); | 1554 ib, data, len); |
1427 | 1555 |
1428 ib = lto_create_simple_input_block (file_data, LTO_section_varpool, | 1556 ib = lto_create_simple_input_block (file_data, LTO_section_varpool, |
1429 &data, &len); | 1557 &data, &len); |
1558 if (!ib) | |
1559 fatal_error ("cannot find LTO varpool in %s", file_data->file_name); | |
1430 varpool = input_varpool_1 (file_data, ib); | 1560 varpool = input_varpool_1 (file_data, ib); |
1431 lto_destroy_simple_input_block (file_data, LTO_section_varpool, | 1561 lto_destroy_simple_input_block (file_data, LTO_section_varpool, |
1432 ib, data, len); | 1562 ib, data, len); |
1433 | 1563 |
1434 ib = lto_create_simple_input_block (file_data, LTO_section_refs, | 1564 ib = lto_create_simple_input_block (file_data, LTO_section_refs, |
1435 &data, &len); | 1565 &data, &len); |
1566 if (!ib) | |
1567 fatal_error("cannot find LTO section refs in %s", file_data->file_name); | |
1436 input_refs (ib, nodes, varpool); | 1568 input_refs (ib, nodes, varpool); |
1437 lto_destroy_simple_input_block (file_data, LTO_section_refs, | 1569 lto_destroy_simple_input_block (file_data, LTO_section_refs, |
1438 ib, data, len); | 1570 ib, data, len); |
1439 if (flag_ltrans) | 1571 if (flag_ltrans) |
1440 input_cgraph_opt_summary (nodes); | 1572 input_cgraph_opt_summary (nodes); |
1441 VEC_free (cgraph_node_ptr, heap, nodes); | 1573 VEC_free (cgraph_node_ptr, heap, nodes); |
1442 VEC_free (varpool_node_ptr, heap, varpool); | 1574 VEC_free (varpool_node_ptr, heap, varpool); |
1443 } | 1575 } |
1576 merge_profile_summaries (file_data_vec); | |
1577 | |
1444 | 1578 |
1445 /* Clear out the aux field that was used to store enough state to | 1579 /* Clear out the aux field that was used to store enough state to |
1446 tell which nodes should be overwritten. */ | 1580 tell which nodes should be overwritten. */ |
1447 for (node = cgraph_nodes; node; node = node->next) | 1581 for (node = cgraph_nodes; node; node = node->next) |
1448 { | 1582 { |
1457 } | 1591 } |
1458 | 1592 |
1459 /* True when we need optimization summary for NODE. */ | 1593 /* True when we need optimization summary for NODE. */ |
1460 | 1594 |
1461 static int | 1595 static int |
1462 output_cgraph_opt_summary_p (struct cgraph_node *node) | 1596 output_cgraph_opt_summary_p (struct cgraph_node *node, cgraph_node_set set) |
1463 { | 1597 { |
1464 if (!node->clone_of) | 1598 struct cgraph_edge *e; |
1465 return false; | 1599 |
1466 return (node->clone.tree_map | 1600 if (cgraph_node_in_set_p (node, set)) |
1467 || node->clone.args_to_skip | 1601 { |
1468 || node->clone.combined_args_to_skip); | 1602 for (e = node->callees; e; e = e->next_callee) |
1603 if (e->indirect_info | |
1604 && e->indirect_info->thunk_delta != 0) | |
1605 return true; | |
1606 | |
1607 for (e = node->indirect_calls; e; e = e->next_callee) | |
1608 if (e->indirect_info->thunk_delta != 0) | |
1609 return true; | |
1610 } | |
1611 | |
1612 return (node->clone_of | |
1613 && (node->clone.tree_map | |
1614 || node->clone.args_to_skip | |
1615 || node->clone.combined_args_to_skip)); | |
1616 } | |
1617 | |
1618 /* Output optimization summary for EDGE to OB. */ | |
1619 static void | |
1620 output_edge_opt_summary (struct output_block *ob, | |
1621 struct cgraph_edge *edge) | |
1622 { | |
1623 if (edge->indirect_info) | |
1624 lto_output_sleb128_stream (ob->main_stream, | |
1625 edge->indirect_info->thunk_delta); | |
1626 else | |
1627 lto_output_sleb128_stream (ob->main_stream, 0); | |
1469 } | 1628 } |
1470 | 1629 |
1471 /* Output optimization summary for NODE to OB. */ | 1630 /* Output optimization summary for NODE to OB. */ |
1472 | 1631 |
1473 static void | 1632 static void |
1474 output_node_opt_summary (struct output_block *ob, | 1633 output_node_opt_summary (struct output_block *ob, |
1475 struct cgraph_node *node) | 1634 struct cgraph_node *node, |
1635 cgraph_node_set set) | |
1476 { | 1636 { |
1477 unsigned int index; | 1637 unsigned int index; |
1478 bitmap_iterator bi; | 1638 bitmap_iterator bi; |
1479 struct ipa_replace_map *map; | 1639 struct ipa_replace_map *map; |
1480 struct bitpack_d *bp; | 1640 struct bitpack_d bp; |
1481 int i; | 1641 int i; |
1642 struct cgraph_edge *e; | |
1482 | 1643 |
1483 lto_output_uleb128_stream (ob->main_stream, | 1644 lto_output_uleb128_stream (ob->main_stream, |
1484 bitmap_count_bits (node->clone.args_to_skip)); | 1645 bitmap_count_bits (node->clone.args_to_skip)); |
1485 EXECUTE_IF_SET_IN_BITMAP (node->clone.args_to_skip, 0, index, bi) | 1646 EXECUTE_IF_SET_IN_BITMAP (node->clone.args_to_skip, 0, index, bi) |
1486 lto_output_uleb128_stream (ob->main_stream, index); | 1647 lto_output_uleb128_stream (ob->main_stream, index); |
1488 bitmap_count_bits (node->clone.combined_args_to_skip)); | 1649 bitmap_count_bits (node->clone.combined_args_to_skip)); |
1489 EXECUTE_IF_SET_IN_BITMAP (node->clone.combined_args_to_skip, 0, index, bi) | 1650 EXECUTE_IF_SET_IN_BITMAP (node->clone.combined_args_to_skip, 0, index, bi) |
1490 lto_output_uleb128_stream (ob->main_stream, index); | 1651 lto_output_uleb128_stream (ob->main_stream, index); |
1491 lto_output_uleb128_stream (ob->main_stream, | 1652 lto_output_uleb128_stream (ob->main_stream, |
1492 VEC_length (ipa_replace_map_p, node->clone.tree_map)); | 1653 VEC_length (ipa_replace_map_p, node->clone.tree_map)); |
1493 for (i = 0; VEC_iterate (ipa_replace_map_p, node->clone.tree_map, i, map); i++) | 1654 FOR_EACH_VEC_ELT (ipa_replace_map_p, node->clone.tree_map, i, map) |
1494 { | 1655 { |
1495 int parm_num; | 1656 int parm_num; |
1496 tree parm; | 1657 tree parm; |
1497 | 1658 |
1498 for (parm_num = 0, parm = DECL_ARGUMENTS (node->decl); parm; | 1659 for (parm_num = 0, parm = DECL_ARGUMENTS (node->decl); parm; |
1499 parm = TREE_CHAIN (parm), parm_num++) | 1660 parm = DECL_CHAIN (parm), parm_num++) |
1500 if (map->old_tree == parm) | 1661 if (map->old_tree == parm) |
1501 break; | 1662 break; |
1502 /* At the moment we assume all old trees to be PARM_DECLs, because we have no | 1663 /* At the moment we assume all old trees to be PARM_DECLs, because we have no |
1503 mechanism to store function local declarations into summaries. */ | 1664 mechanism to store function local declarations into summaries. */ |
1504 gcc_assert (parm); | 1665 gcc_assert (parm); |
1505 lto_output_uleb128_stream (ob->main_stream, parm_num); | 1666 lto_output_uleb128_stream (ob->main_stream, parm_num); |
1506 lto_output_tree (ob, map->new_tree, true); | 1667 lto_output_tree (ob, map->new_tree, true); |
1507 bp = bitpack_create (); | 1668 bp = bitpack_create (ob->main_stream); |
1508 bp_pack_value (bp, map->replace_p, 1); | 1669 bp_pack_value (&bp, map->replace_p, 1); |
1509 bp_pack_value (bp, map->ref_p, 1); | 1670 bp_pack_value (&bp, map->ref_p, 1); |
1510 lto_output_bitpack (ob->main_stream, bp); | 1671 lto_output_bitpack (&bp); |
1511 bitpack_delete (bp); | 1672 } |
1673 | |
1674 if (cgraph_node_in_set_p (node, set)) | |
1675 { | |
1676 for (e = node->callees; e; e = e->next_callee) | |
1677 output_edge_opt_summary (ob, e); | |
1678 for (e = node->indirect_calls; e; e = e->next_callee) | |
1679 output_edge_opt_summary (ob, e); | |
1512 } | 1680 } |
1513 } | 1681 } |
1514 | 1682 |
1515 /* Output optimization summaries stored in callgraph. | 1683 /* Output optimization summaries stored in callgraph. |
1516 At the moment it is the clone info structure. */ | 1684 At the moment it is the clone info structure. */ |
1517 | 1685 |
1518 static void | 1686 static void |
1519 output_cgraph_opt_summary (void) | 1687 output_cgraph_opt_summary (cgraph_node_set set) |
1520 { | 1688 { |
1521 struct cgraph_node *node; | 1689 struct cgraph_node *node; |
1522 int i, n_nodes; | 1690 int i, n_nodes; |
1523 lto_cgraph_encoder_t encoder; | 1691 lto_cgraph_encoder_t encoder; |
1524 struct output_block *ob = create_output_block (LTO_section_cgraph_opt_sum); | 1692 struct output_block *ob = create_output_block (LTO_section_cgraph_opt_sum); |
1526 | 1694 |
1527 ob->cgraph_node = NULL; | 1695 ob->cgraph_node = NULL; |
1528 encoder = ob->decl_state->cgraph_node_encoder; | 1696 encoder = ob->decl_state->cgraph_node_encoder; |
1529 n_nodes = lto_cgraph_encoder_size (encoder); | 1697 n_nodes = lto_cgraph_encoder_size (encoder); |
1530 for (i = 0; i < n_nodes; i++) | 1698 for (i = 0; i < n_nodes; i++) |
1531 if (output_cgraph_opt_summary_p (lto_cgraph_encoder_deref (encoder, i))) | 1699 if (output_cgraph_opt_summary_p (lto_cgraph_encoder_deref (encoder, i), |
1700 set)) | |
1532 count++; | 1701 count++; |
1533 lto_output_uleb128_stream (ob->main_stream, count); | 1702 lto_output_uleb128_stream (ob->main_stream, count); |
1534 for (i = 0; i < n_nodes; i++) | 1703 for (i = 0; i < n_nodes; i++) |
1535 { | 1704 { |
1536 node = lto_cgraph_encoder_deref (encoder, i); | 1705 node = lto_cgraph_encoder_deref (encoder, i); |
1537 if (output_cgraph_opt_summary_p (node)) | 1706 if (output_cgraph_opt_summary_p (node, set)) |
1538 { | 1707 { |
1539 lto_output_uleb128_stream (ob->main_stream, i); | 1708 lto_output_uleb128_stream (ob->main_stream, i); |
1540 output_node_opt_summary (ob, node); | 1709 output_node_opt_summary (ob, node, set); |
1541 } | 1710 } |
1542 } | 1711 } |
1543 produce_asm (ob, NULL); | 1712 produce_asm (ob, NULL); |
1544 destroy_output_block (ob); | 1713 destroy_output_block (ob); |
1545 } | 1714 } |
1546 | 1715 |
1547 /* Input optimiation summary of NODE. */ | 1716 /* Input optimisation summary of EDGE. */ |
1717 | |
1718 static void | |
1719 input_edge_opt_summary (struct cgraph_edge *edge, | |
1720 struct lto_input_block *ib_main) | |
1721 { | |
1722 HOST_WIDE_INT thunk_delta; | |
1723 thunk_delta = lto_input_sleb128 (ib_main); | |
1724 if (thunk_delta != 0) | |
1725 { | |
1726 gcc_assert (!edge->indirect_info); | |
1727 edge->indirect_info = cgraph_allocate_init_indirect_info (); | |
1728 edge->indirect_info->thunk_delta = thunk_delta; | |
1729 } | |
1730 } | |
1731 | |
1732 /* Input optimisation summary of NODE. */ | |
1548 | 1733 |
1549 static void | 1734 static void |
1550 input_node_opt_summary (struct cgraph_node *node, | 1735 input_node_opt_summary (struct cgraph_node *node, |
1551 struct lto_input_block *ib_main, | 1736 struct lto_input_block *ib_main, |
1552 struct data_in *data_in) | 1737 struct data_in *data_in) |
1553 { | 1738 { |
1554 int i; | 1739 int i; |
1555 int count; | 1740 int count; |
1556 int bit; | 1741 int bit; |
1557 struct bitpack_d *bp; | 1742 struct bitpack_d bp; |
1743 struct cgraph_edge *e; | |
1558 | 1744 |
1559 count = lto_input_uleb128 (ib_main); | 1745 count = lto_input_uleb128 (ib_main); |
1560 if (count) | 1746 if (count) |
1561 node->clone.args_to_skip = BITMAP_GGC_ALLOC (); | 1747 node->clone.args_to_skip = BITMAP_GGC_ALLOC (); |
1562 for (i = 0; i < count; i++) | 1748 for (i = 0; i < count; i++) |
1575 count = lto_input_uleb128 (ib_main); | 1761 count = lto_input_uleb128 (ib_main); |
1576 for (i = 0; i < count; i++) | 1762 for (i = 0; i < count; i++) |
1577 { | 1763 { |
1578 int parm_num; | 1764 int parm_num; |
1579 tree parm; | 1765 tree parm; |
1580 struct ipa_replace_map *map = GGC_NEW (struct ipa_replace_map); | 1766 struct ipa_replace_map *map = ggc_alloc_ipa_replace_map (); |
1581 | 1767 |
1582 VEC_safe_push (ipa_replace_map_p, gc, node->clone.tree_map, map); | 1768 VEC_safe_push (ipa_replace_map_p, gc, node->clone.tree_map, map); |
1583 for (parm_num = 0, parm = DECL_ARGUMENTS (node->decl); parm_num; | 1769 for (parm_num = 0, parm = DECL_ARGUMENTS (node->decl); parm_num; |
1584 parm = TREE_CHAIN (parm)) | 1770 parm = DECL_CHAIN (parm)) |
1585 parm_num --; | 1771 parm_num --; |
1586 map->parm_num = lto_input_uleb128 (ib_main); | 1772 map->parm_num = lto_input_uleb128 (ib_main); |
1587 map->old_tree = NULL; | 1773 map->old_tree = NULL; |
1588 map->new_tree = lto_input_tree (ib_main, data_in); | 1774 map->new_tree = lto_input_tree (ib_main, data_in); |
1589 bp = lto_input_bitpack (ib_main); | 1775 bp = lto_input_bitpack (ib_main); |
1590 map->replace_p = bp_unpack_value (bp, 1); | 1776 map->replace_p = bp_unpack_value (&bp, 1); |
1591 map->ref_p = bp_unpack_value (bp, 1); | 1777 map->ref_p = bp_unpack_value (&bp, 1); |
1592 bitpack_delete (bp); | 1778 } |
1593 } | 1779 for (e = node->callees; e; e = e->next_callee) |
1780 input_edge_opt_summary (e, ib_main); | |
1781 for (e = node->indirect_calls; e; e = e->next_callee) | |
1782 input_edge_opt_summary (e, ib_main); | |
1594 } | 1783 } |
1595 | 1784 |
1596 /* Read section in file FILE_DATA of length LEN with data DATA. */ | 1785 /* Read section in file FILE_DATA of length LEN with data DATA. */ |
1597 | 1786 |
1598 static void | 1787 static void |
1622 { | 1811 { |
1623 int ref = lto_input_uleb128 (&ib_main); | 1812 int ref = lto_input_uleb128 (&ib_main); |
1624 input_node_opt_summary (VEC_index (cgraph_node_ptr, nodes, ref), | 1813 input_node_opt_summary (VEC_index (cgraph_node_ptr, nodes, ref), |
1625 &ib_main, data_in); | 1814 &ib_main, data_in); |
1626 } | 1815 } |
1627 lto_free_section_data (file_data, LTO_section_jump_functions, NULL, data, | 1816 lto_free_section_data (file_data, LTO_section_cgraph_opt_sum, NULL, data, |
1628 len); | 1817 len); |
1629 lto_data_in_delete (data_in); | 1818 lto_data_in_delete (data_in); |
1630 } | 1819 } |
1631 | 1820 |
1632 /* Input optimization summary of cgraph. */ | 1821 /* Input optimization summary of cgraph. */ |