Mercurial > hg > CbC > CbC_gcc
comparison gcc/lto-cgraph.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
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 (C) 2009-2017 Free Software Foundation, Inc. | 4 Copyright (C) 2009-2018 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 |
35 #include "profile.h" | 35 #include "profile.h" |
36 #include "context.h" | 36 #include "context.h" |
37 #include "pass_manager.h" | 37 #include "pass_manager.h" |
38 #include "ipa-utils.h" | 38 #include "ipa-utils.h" |
39 #include "omp-offload.h" | 39 #include "omp-offload.h" |
40 #include "ipa-chkp.h" | |
41 #include "stringpool.h" | 40 #include "stringpool.h" |
42 #include "attribs.h" | 41 #include "attribs.h" |
43 | 42 |
44 /* True when asm nodes has been output. */ | 43 /* True when asm nodes has been output. */ |
45 bool asm_nodes_output = false; | 44 bool asm_nodes_output = false; |
264 uid = (!gimple_has_body_p (edge->caller->decl) || edge->caller->thunk.thunk_p | 263 uid = (!gimple_has_body_p (edge->caller->decl) || edge->caller->thunk.thunk_p |
265 ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt) + 1); | 264 ? edge->lto_stmt_uid : gimple_uid (edge->call_stmt) + 1); |
266 bp_pack_enum (&bp, cgraph_inline_failed_t, | 265 bp_pack_enum (&bp, cgraph_inline_failed_t, |
267 CIF_N_REASONS, edge->inline_failed); | 266 CIF_N_REASONS, edge->inline_failed); |
268 bp_pack_var_len_unsigned (&bp, uid); | 267 bp_pack_var_len_unsigned (&bp, uid); |
269 bp_pack_var_len_unsigned (&bp, edge->frequency); | |
270 bp_pack_value (&bp, edge->indirect_inlining_edge, 1); | 268 bp_pack_value (&bp, edge->indirect_inlining_edge, 1); |
271 bp_pack_value (&bp, edge->speculative, 1); | 269 bp_pack_value (&bp, edge->speculative, 1); |
272 bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1); | 270 bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1); |
273 gcc_assert (!edge->call_stmt_cannot_inline_p | 271 gcc_assert (!edge->call_stmt_cannot_inline_p |
274 || edge->inline_failed != CIF_BODY_NOT_AVAILABLE); | 272 || edge->inline_failed != CIF_BODY_NOT_AVAILABLE); |
539 bp_pack_value (&bp, node->icf_merged, 1); | 537 bp_pack_value (&bp, node->icf_merged, 1); |
540 bp_pack_value (&bp, node->nonfreeing_fn, 1); | 538 bp_pack_value (&bp, node->nonfreeing_fn, 1); |
541 bp_pack_value (&bp, node->thunk.thunk_p, 1); | 539 bp_pack_value (&bp, node->thunk.thunk_p, 1); |
542 bp_pack_value (&bp, node->parallelized_function, 1); | 540 bp_pack_value (&bp, node->parallelized_function, 1); |
543 bp_pack_enum (&bp, ld_plugin_symbol_resolution, | 541 bp_pack_enum (&bp, ld_plugin_symbol_resolution, |
544 LDPR_NUM_KNOWN, node->resolution); | 542 LDPR_NUM_KNOWN, |
545 bp_pack_value (&bp, node->instrumentation_clone, 1); | 543 /* When doing incremental link, we will get new resolution |
544 info next time we process the file. */ | |
545 flag_incremental_link ? LDPR_UNKNOWN : node->resolution); | |
546 bp_pack_value (&bp, node->split_part, 1); | 546 bp_pack_value (&bp, node->split_part, 1); |
547 streamer_write_bitpack (&bp); | 547 streamer_write_bitpack (&bp); |
548 streamer_write_data_stream (ob->main_stream, section, strlen (section) + 1); | 548 streamer_write_data_stream (ob->main_stream, section, strlen (section) + 1); |
549 | 549 |
550 if (node->thunk.thunk_p) | 550 if (node->thunk.thunk_p) |
554 1 + (node->thunk.this_adjusting != 0) * 2 | 554 1 + (node->thunk.this_adjusting != 0) * 2 |
555 + (node->thunk.virtual_offset_p != 0) * 4 | 555 + (node->thunk.virtual_offset_p != 0) * 4 |
556 + (node->thunk.add_pointer_bounds_args != 0) * 8); | 556 + (node->thunk.add_pointer_bounds_args != 0) * 8); |
557 streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset); | 557 streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset); |
558 streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value); | 558 streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value); |
559 streamer_write_uhwi_stream (ob->main_stream, node->thunk.indirect_offset); | |
559 } | 560 } |
560 streamer_write_hwi_stream (ob->main_stream, node->profile_id); | 561 streamer_write_hwi_stream (ob->main_stream, node->profile_id); |
561 if (DECL_STATIC_CONSTRUCTOR (node->decl)) | 562 if (DECL_STATIC_CONSTRUCTOR (node->decl)) |
562 streamer_write_hwi_stream (ob->main_stream, node->get_init_priority ()); | 563 streamer_write_hwi_stream (ob->main_stream, node->get_init_priority ()); |
563 if (DECL_STATIC_DESTRUCTOR (node->decl)) | 564 if (DECL_STATIC_DESTRUCTOR (node->decl)) |
564 streamer_write_hwi_stream (ob->main_stream, node->get_fini_priority ()); | 565 streamer_write_hwi_stream (ob->main_stream, node->get_fini_priority ()); |
565 | |
566 if (node->instrumentation_clone) | |
567 lto_output_fn_decl_index (ob->decl_state, ob->main_stream, node->orig_decl); | |
568 } | 566 } |
569 | 567 |
570 /* Output the varpool NODE to OB. | 568 /* Output the varpool NODE to OB. |
571 If NODE is not in SET, then NODE is a boundary. */ | 569 If NODE is not in SET, then NODE is a boundary. */ |
572 | 570 |
694 /* Stream out profile_summary to OB. */ | 692 /* Stream out profile_summary to OB. */ |
695 | 693 |
696 static void | 694 static void |
697 output_profile_summary (struct lto_simple_output_block *ob) | 695 output_profile_summary (struct lto_simple_output_block *ob) |
698 { | 696 { |
699 unsigned h_ix; | |
700 struct bitpack_d bp; | |
701 | |
702 if (profile_info) | 697 if (profile_info) |
703 { | 698 { |
704 /* We do not output num and run_max, they are not used by | 699 /* We do not output num and run_max, they are not used by |
705 GCC profile feedback and they are difficult to merge from multiple | 700 GCC profile feedback and they are difficult to merge from multiple |
706 units. */ | 701 units. */ |
707 gcc_assert (profile_info->runs); | 702 unsigned runs = (profile_info->runs); |
708 streamer_write_uhwi_stream (ob->main_stream, profile_info->runs); | 703 streamer_write_uhwi_stream (ob->main_stream, runs); |
709 streamer_write_gcov_count_stream (ob->main_stream, profile_info->sum_max); | 704 |
710 | |
711 /* sum_all is needed for computing the working set with the | |
712 histogram. */ | |
713 streamer_write_gcov_count_stream (ob->main_stream, profile_info->sum_all); | |
714 | |
715 /* Create and output a bitpack of non-zero histogram entries indices. */ | |
716 bp = bitpack_create (ob->main_stream); | |
717 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) | |
718 bp_pack_value (&bp, profile_info->histogram[h_ix].num_counters > 0, 1); | |
719 streamer_write_bitpack (&bp); | |
720 /* Now stream out only those non-zero entries. */ | |
721 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) | |
722 { | |
723 if (!profile_info->histogram[h_ix].num_counters) | |
724 continue; | |
725 streamer_write_gcov_count_stream (ob->main_stream, | |
726 profile_info->histogram[h_ix].num_counters); | |
727 streamer_write_gcov_count_stream (ob->main_stream, | |
728 profile_info->histogram[h_ix].min_value); | |
729 streamer_write_gcov_count_stream (ob->main_stream, | |
730 profile_info->histogram[h_ix].cum_value); | |
731 } | |
732 /* IPA-profile computes hot bb threshold based on cumulated | 705 /* IPA-profile computes hot bb threshold based on cumulated |
733 whole program profile. We need to stream it down to ltrans. */ | 706 whole program profile. We need to stream it down to ltrans. */ |
734 if (flag_wpa) | 707 if (flag_wpa) |
735 streamer_write_gcov_count_stream (ob->main_stream, | 708 streamer_write_gcov_count_stream (ob->main_stream, |
736 get_hot_bb_threshold ()); | 709 get_hot_bb_threshold ()); |
771 | 744 |
772 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++) | 745 for (int i = 0; i < lto_symtab_encoder_size (encoder); i++) |
773 { | 746 { |
774 symtab_node *node = lto_symtab_encoder_deref (encoder, i); | 747 symtab_node *node = lto_symtab_encoder_deref (encoder, i); |
775 | 748 |
776 /* IPA_REF_ALIAS and IPA_REF_CHKP references are always preserved | 749 /* IPA_REF_ALIAS references are always preserved |
777 in the boundary. Alias node can't have other references and | 750 in the boundary. Alias node can't have other references and |
778 can be always handled as if it's not in the boundary. */ | 751 can be always handled as if it's not in the boundary. */ |
779 if (!node->alias && !lto_symtab_encoder_in_partition_p (encoder, node)) | 752 if (!node->alias && !lto_symtab_encoder_in_partition_p (encoder, node)) |
780 { | 753 continue; |
781 cgraph_node *cnode = dyn_cast <cgraph_node *> (node); | |
782 /* Output IPA_REF_CHKP reference. */ | |
783 if (cnode | |
784 && cnode->instrumented_version | |
785 && !cnode->instrumentation_clone) | |
786 { | |
787 for (int i = 0; node->iterate_reference (i, ref); i++) | |
788 if (ref->use == IPA_REF_CHKP) | |
789 { | |
790 if (lto_symtab_encoder_lookup (encoder, ref->referred) | |
791 != LCC_NOT_FOUND) | |
792 { | |
793 int nref = lto_symtab_encoder_lookup (encoder, node); | |
794 streamer_write_gcov_count_stream (ob->main_stream, 1); | |
795 streamer_write_uhwi_stream (ob->main_stream, nref); | |
796 lto_output_ref (ob, ref, encoder); | |
797 } | |
798 break; | |
799 } | |
800 } | |
801 continue; | |
802 } | |
803 | 754 |
804 count = node->ref_list.nreferences (); | 755 count = node->ref_list.nreferences (); |
805 if (count) | 756 if (count) |
806 { | 757 { |
807 streamer_write_gcov_count_stream (ob->main_stream, count); | 758 streamer_write_gcov_count_stream (ob->main_stream, count); |
909 if (!lto_symtab_encoder_encode_initializer_p (encoder, | 860 if (!lto_symtab_encoder_encode_initializer_p (encoder, |
910 vnode) | 861 vnode) |
911 && (((vnode->ctor_useable_for_folding_p () | 862 && (((vnode->ctor_useable_for_folding_p () |
912 && (!DECL_VIRTUAL_P (vnode->decl) | 863 && (!DECL_VIRTUAL_P (vnode->decl) |
913 || !flag_wpa | 864 || !flag_wpa |
914 || flag_ltrans_devirtualize)) | 865 || flag_ltrans_devirtualize))))) |
915 || POINTER_BOUNDS_P (vnode->decl)))) | |
916 { | 866 { |
917 lto_set_symtab_encoder_encode_initializer (encoder, vnode); | 867 lto_set_symtab_encoder_encode_initializer (encoder, vnode); |
918 create_references (encoder, vnode); | 868 create_references (encoder, vnode); |
919 } | 869 } |
920 } | 870 } |
1200 node->nonfreeing_fn = bp_unpack_value (bp, 1); | 1150 node->nonfreeing_fn = bp_unpack_value (bp, 1); |
1201 node->thunk.thunk_p = bp_unpack_value (bp, 1); | 1151 node->thunk.thunk_p = bp_unpack_value (bp, 1); |
1202 node->parallelized_function = bp_unpack_value (bp, 1); | 1152 node->parallelized_function = bp_unpack_value (bp, 1); |
1203 node->resolution = bp_unpack_enum (bp, ld_plugin_symbol_resolution, | 1153 node->resolution = bp_unpack_enum (bp, ld_plugin_symbol_resolution, |
1204 LDPR_NUM_KNOWN); | 1154 LDPR_NUM_KNOWN); |
1205 node->instrumentation_clone = bp_unpack_value (bp, 1); | |
1206 node->split_part = bp_unpack_value (bp, 1); | 1155 node->split_part = bp_unpack_value (bp, 1); |
1207 gcc_assert (flag_ltrans | 1156 gcc_assert (flag_ltrans |
1208 || (!node->in_other_partition | 1157 || (!node->in_other_partition |
1209 && !node->used_from_other_partition)); | 1158 && !node->used_from_other_partition)); |
1210 } | 1159 } |
1246 fn_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index); | 1195 fn_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index); |
1247 | 1196 |
1248 if (clone_ref != LCC_NOT_FOUND) | 1197 if (clone_ref != LCC_NOT_FOUND) |
1249 { | 1198 { |
1250 node = dyn_cast<cgraph_node *> (nodes[clone_ref])->create_clone (fn_decl, | 1199 node = dyn_cast<cgraph_node *> (nodes[clone_ref])->create_clone (fn_decl, |
1251 profile_count::uninitialized (), CGRAPH_FREQ_BASE, false, | 1200 profile_count::uninitialized (), false, |
1252 vNULL, false, NULL, NULL); | 1201 vNULL, false, NULL, NULL); |
1253 } | 1202 } |
1254 else | 1203 else |
1255 { | 1204 { |
1256 /* Declaration of functions can be already merged with a declaration | 1205 /* Declaration of functions can be already merged with a declaration |
1257 from other input file. We keep cgraph unmerged until after streaming | 1206 from other input file. We keep cgraph unmerged until after streaming |
1258 of ipa passes is done. Alays forcingly create a fresh node. */ | 1207 of ipa passes is done. Alays forcingly create a fresh node. */ |
1259 node = symtab->create_empty (); | 1208 node = symtab->create_empty (); |
1260 node->decl = fn_decl; | 1209 node->decl = fn_decl; |
1210 if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl))) | |
1211 node->ifunc_resolver = 1; | |
1261 node->register_symbol (); | 1212 node->register_symbol (); |
1262 } | 1213 } |
1263 | 1214 |
1264 node->order = order; | 1215 node->order = order; |
1265 if (order >= symtab->order) | 1216 if (order >= symtab->order) |
1289 | 1240 |
1290 /* Make sure that we have not read this node before. Nodes that | 1241 /* Make sure that we have not read this node before. Nodes that |
1291 have already been read will have their tag stored in the 'aux' | 1242 have already been read will have their tag stored in the 'aux' |
1292 field. Since built-in functions can be referenced in multiple | 1243 field. Since built-in functions can be referenced in multiple |
1293 functions, they are expected to be read more than once. */ | 1244 functions, they are expected to be read more than once. */ |
1294 if (node->aux && !DECL_BUILT_IN (node->decl)) | 1245 if (node->aux && !fndecl_built_in_p (node->decl)) |
1295 internal_error ("bytecode stream: found multiple instances of cgraph " | 1246 internal_error ("bytecode stream: found multiple instances of cgraph " |
1296 "node with uid %d", node->uid); | 1247 "node with uid %d", node->get_uid ()); |
1297 | 1248 |
1298 node->tp_first_run = streamer_read_uhwi (ib); | 1249 node->tp_first_run = streamer_read_uhwi (ib); |
1299 | 1250 |
1300 bp = streamer_read_bitpack (ib); | 1251 bp = streamer_read_bitpack (ib); |
1301 | 1252 |
1319 if (node->thunk.thunk_p) | 1270 if (node->thunk.thunk_p) |
1320 { | 1271 { |
1321 int type = streamer_read_uhwi (ib); | 1272 int type = streamer_read_uhwi (ib); |
1322 HOST_WIDE_INT fixed_offset = streamer_read_uhwi (ib); | 1273 HOST_WIDE_INT fixed_offset = streamer_read_uhwi (ib); |
1323 HOST_WIDE_INT virtual_value = streamer_read_uhwi (ib); | 1274 HOST_WIDE_INT virtual_value = streamer_read_uhwi (ib); |
1275 HOST_WIDE_INT indirect_offset = streamer_read_uhwi (ib); | |
1324 | 1276 |
1325 node->thunk.fixed_offset = fixed_offset; | 1277 node->thunk.fixed_offset = fixed_offset; |
1278 node->thunk.virtual_value = virtual_value; | |
1279 node->thunk.indirect_offset = indirect_offset; | |
1326 node->thunk.this_adjusting = (type & 2); | 1280 node->thunk.this_adjusting = (type & 2); |
1327 node->thunk.virtual_value = virtual_value; | |
1328 node->thunk.virtual_offset_p = (type & 4); | 1281 node->thunk.virtual_offset_p = (type & 4); |
1329 node->thunk.add_pointer_bounds_args = (type & 8); | 1282 node->thunk.add_pointer_bounds_args = (type & 8); |
1330 } | 1283 } |
1331 if (node->alias && !node->analyzed && node->weakref) | 1284 if (node->alias && !node->analyzed && node->weakref) |
1332 node->alias_target = get_alias_symbol (node->decl); | 1285 node->alias_target = get_alias_symbol (node->decl); |
1333 node->profile_id = streamer_read_hwi (ib); | 1286 node->profile_id = streamer_read_hwi (ib); |
1334 if (DECL_STATIC_CONSTRUCTOR (node->decl)) | 1287 if (DECL_STATIC_CONSTRUCTOR (node->decl)) |
1335 node->set_init_priority (streamer_read_hwi (ib)); | 1288 node->set_init_priority (streamer_read_hwi (ib)); |
1336 if (DECL_STATIC_DESTRUCTOR (node->decl)) | 1289 if (DECL_STATIC_DESTRUCTOR (node->decl)) |
1337 node->set_fini_priority (streamer_read_hwi (ib)); | 1290 node->set_fini_priority (streamer_read_hwi (ib)); |
1338 | |
1339 if (node->instrumentation_clone) | |
1340 { | |
1341 decl_index = streamer_read_uhwi (ib); | |
1342 fn_decl = lto_file_decl_data_get_fn_decl (file_data, decl_index); | |
1343 node->orig_decl = fn_decl; | |
1344 } | |
1345 | 1291 |
1346 return node; | 1292 return node; |
1347 } | 1293 } |
1348 | 1294 |
1349 /* Read a node from input_block IB. TAG is the node's tag just read. | 1295 /* Read a node from input_block IB. TAG is the node's tag just read. |
1462 { | 1408 { |
1463 struct cgraph_node *caller, *callee; | 1409 struct cgraph_node *caller, *callee; |
1464 struct cgraph_edge *edge; | 1410 struct cgraph_edge *edge; |
1465 unsigned int stmt_id; | 1411 unsigned int stmt_id; |
1466 profile_count count; | 1412 profile_count count; |
1467 int freq; | |
1468 cgraph_inline_failed_t inline_failed; | 1413 cgraph_inline_failed_t inline_failed; |
1469 struct bitpack_d bp; | 1414 struct bitpack_d bp; |
1470 int ecf_flags = 0; | 1415 int ecf_flags = 0; |
1471 | 1416 |
1472 caller = dyn_cast<cgraph_node *> (nodes[streamer_read_hwi (ib)]); | 1417 caller = dyn_cast<cgraph_node *> (nodes[streamer_read_hwi (ib)]); |
1485 count = profile_count::stream_in (ib); | 1430 count = profile_count::stream_in (ib); |
1486 | 1431 |
1487 bp = streamer_read_bitpack (ib); | 1432 bp = streamer_read_bitpack (ib); |
1488 inline_failed = bp_unpack_enum (&bp, cgraph_inline_failed_t, CIF_N_REASONS); | 1433 inline_failed = bp_unpack_enum (&bp, cgraph_inline_failed_t, CIF_N_REASONS); |
1489 stmt_id = bp_unpack_var_len_unsigned (&bp); | 1434 stmt_id = bp_unpack_var_len_unsigned (&bp); |
1490 freq = (int) bp_unpack_var_len_unsigned (&bp); | |
1491 | 1435 |
1492 if (indirect) | 1436 if (indirect) |
1493 edge = caller->create_indirect_edge (NULL, 0, count, freq); | 1437 edge = caller->create_indirect_edge (NULL, 0, count); |
1494 else | 1438 else |
1495 edge = caller->create_edge (callee, NULL, count, freq); | 1439 edge = caller->create_edge (callee, NULL, count); |
1496 | 1440 |
1497 edge->indirect_inlining_edge = bp_unpack_value (&bp, 1); | 1441 edge->indirect_inlining_edge = bp_unpack_value (&bp, 1); |
1498 edge->speculative = bp_unpack_value (&bp, 1); | 1442 edge->speculative = bp_unpack_value (&bp, 1); |
1499 edge->lto_stmt_uid = stmt_id; | 1443 edge->lto_stmt_uid = stmt_id; |
1500 edge->inline_failed = inline_failed; | 1444 edge->inline_failed = inline_failed; |
1584 if (ref != LCC_NOT_FOUND) | 1528 if (ref != LCC_NOT_FOUND) |
1585 dyn_cast<cgraph_node *> (node)->global.inlined_to | 1529 dyn_cast<cgraph_node *> (node)->global.inlined_to |
1586 = dyn_cast<cgraph_node *> (nodes[ref]); | 1530 = dyn_cast<cgraph_node *> (nodes[ref]); |
1587 else | 1531 else |
1588 cnode->global.inlined_to = NULL; | 1532 cnode->global.inlined_to = NULL; |
1589 | |
1590 /* Compute instrumented_version. */ | |
1591 if (cnode->instrumentation_clone) | |
1592 { | |
1593 gcc_assert (cnode->orig_decl); | |
1594 | |
1595 cnode->instrumented_version = cgraph_node::get (cnode->orig_decl); | |
1596 if (cnode->instrumented_version) | |
1597 { | |
1598 /* We may have multiple nodes for a single function which | |
1599 will be merged later. To have a proper merge we need | |
1600 to keep instrumentation_version reference between nodes | |
1601 consistent: each instrumented_version reference should | |
1602 have proper reverse reference. Thus don't break existing | |
1603 instrumented_version reference if it already exists. */ | |
1604 if (cnode->instrumented_version->instrumented_version) | |
1605 cnode->instrumented_version = NULL; | |
1606 else | |
1607 cnode->instrumented_version->instrumented_version = cnode; | |
1608 } | |
1609 | |
1610 /* Restore decl names reference except for wrapper functions. */ | |
1611 if (!chkp_wrap_function (cnode->orig_decl)) | |
1612 { | |
1613 tree name = DECL_ASSEMBLER_NAME (cnode->decl); | |
1614 IDENTIFIER_TRANSPARENT_ALIAS (name) = 1; | |
1615 TREE_CHAIN (name) = DECL_ASSEMBLER_NAME (cnode->orig_decl); | |
1616 } | |
1617 } | |
1618 } | 1533 } |
1619 | 1534 |
1620 ref = (int) (intptr_t) node->same_comdat_group; | 1535 ref = (int) (intptr_t) node->same_comdat_group; |
1621 | 1536 |
1622 /* Fixup same_comdat_group from reference to pointer. */ | 1537 /* Fixup same_comdat_group from reference to pointer. */ |
1652 count--; | 1567 count--; |
1653 } | 1568 } |
1654 } | 1569 } |
1655 } | 1570 } |
1656 | 1571 |
1657 | |
1658 static struct gcov_ctr_summary lto_gcov_summary; | |
1659 | |
1660 /* Input profile_info from IB. */ | 1572 /* Input profile_info from IB. */ |
1661 static void | 1573 static void |
1662 input_profile_summary (struct lto_input_block *ib, | 1574 input_profile_summary (struct lto_input_block *ib, |
1663 struct lto_file_decl_data *file_data) | 1575 struct lto_file_decl_data *file_data) |
1664 { | 1576 { |
1665 unsigned h_ix; | |
1666 struct bitpack_d bp; | |
1667 unsigned int runs = streamer_read_uhwi (ib); | 1577 unsigned int runs = streamer_read_uhwi (ib); |
1668 if (runs) | 1578 if (runs) |
1669 { | 1579 { |
1670 file_data->profile_info.runs = runs; | 1580 file_data->profile_info.runs = runs; |
1671 file_data->profile_info.sum_max = streamer_read_gcov_count (ib); | 1581 |
1672 file_data->profile_info.sum_all = streamer_read_gcov_count (ib); | |
1673 | |
1674 memset (file_data->profile_info.histogram, 0, | |
1675 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); | |
1676 /* Input the bitpack of non-zero histogram indices. */ | |
1677 bp = streamer_read_bitpack (ib); | |
1678 /* Read in and unpack the full bitpack, flagging non-zero | |
1679 histogram entries by setting the num_counters non-zero. */ | |
1680 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) | |
1681 { | |
1682 file_data->profile_info.histogram[h_ix].num_counters | |
1683 = bp_unpack_value (&bp, 1); | |
1684 } | |
1685 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) | |
1686 { | |
1687 if (!file_data->profile_info.histogram[h_ix].num_counters) | |
1688 continue; | |
1689 | |
1690 file_data->profile_info.histogram[h_ix].num_counters | |
1691 = streamer_read_gcov_count (ib); | |
1692 file_data->profile_info.histogram[h_ix].min_value | |
1693 = streamer_read_gcov_count (ib); | |
1694 file_data->profile_info.histogram[h_ix].cum_value | |
1695 = streamer_read_gcov_count (ib); | |
1696 } | |
1697 /* IPA-profile computes hot bb threshold based on cumulated | 1582 /* IPA-profile computes hot bb threshold based on cumulated |
1698 whole program profile. We need to stream it down to ltrans. */ | 1583 whole program profile. We need to stream it down to ltrans. */ |
1699 if (flag_ltrans) | 1584 if (flag_ltrans) |
1700 set_hot_bb_threshold (streamer_read_gcov_count (ib)); | 1585 set_hot_bb_threshold (streamer_read_gcov_count (ib)); |
1701 } | 1586 } |
1706 | 1591 |
1707 static void | 1592 static void |
1708 merge_profile_summaries (struct lto_file_decl_data **file_data_vec) | 1593 merge_profile_summaries (struct lto_file_decl_data **file_data_vec) |
1709 { | 1594 { |
1710 struct lto_file_decl_data *file_data; | 1595 struct lto_file_decl_data *file_data; |
1711 unsigned int j, h_ix; | 1596 unsigned int j; |
1712 gcov_unsigned_t max_runs = 0; | 1597 gcov_unsigned_t max_runs = 0; |
1713 struct cgraph_node *node; | 1598 struct cgraph_node *node; |
1714 struct cgraph_edge *edge; | 1599 struct cgraph_edge *edge; |
1715 gcov_type saved_sum_all = 0; | |
1716 gcov_ctr_summary *saved_profile_info = 0; | |
1717 int saved_scale = 0; | |
1718 | 1600 |
1719 /* Find unit with maximal number of runs. If we ever get serious about | 1601 /* Find unit with maximal number of runs. If we ever get serious about |
1720 roundoff errors, we might also consider computing smallest common | 1602 roundoff errors, we might also consider computing smallest common |
1721 multiply. */ | 1603 multiply. */ |
1722 for (j = 0; (file_data = file_data_vec[j]) != NULL; j++) | 1604 for (j = 0; (file_data = file_data_vec[j]) != NULL; j++) |
1733 sorry ("At most %i profile runs is supported. Perhaps corrupted profile?", | 1615 sorry ("At most %i profile runs is supported. Perhaps corrupted profile?", |
1734 INT_MAX / REG_BR_PROB_BASE); | 1616 INT_MAX / REG_BR_PROB_BASE); |
1735 return; | 1617 return; |
1736 } | 1618 } |
1737 | 1619 |
1738 profile_info = <o_gcov_summary; | 1620 profile_info = XCNEW (gcov_summary); |
1739 lto_gcov_summary.runs = max_runs; | 1621 profile_info->runs = max_runs; |
1740 lto_gcov_summary.sum_max = 0; | |
1741 memset (lto_gcov_summary.histogram, 0, | |
1742 sizeof (gcov_bucket_type) * GCOV_HISTOGRAM_SIZE); | |
1743 | |
1744 /* Rescale all units to the maximal number of runs. | |
1745 sum_max can not be easily merged, as we have no idea what files come from | |
1746 the same run. We do not use the info anyway, so leave it 0. */ | |
1747 for (j = 0; (file_data = file_data_vec[j]) != NULL; j++) | |
1748 if (file_data->profile_info.runs) | |
1749 { | |
1750 int scale = GCOV_COMPUTE_SCALE (max_runs, | |
1751 file_data->profile_info.runs); | |
1752 lto_gcov_summary.sum_max | |
1753 = MAX (lto_gcov_summary.sum_max, | |
1754 apply_scale (file_data->profile_info.sum_max, scale)); | |
1755 lto_gcov_summary.sum_all | |
1756 = MAX (lto_gcov_summary.sum_all, | |
1757 apply_scale (file_data->profile_info.sum_all, scale)); | |
1758 /* Save a pointer to the profile_info with the largest | |
1759 scaled sum_all and the scale for use in merging the | |
1760 histogram. */ | |
1761 if (!saved_profile_info | |
1762 || lto_gcov_summary.sum_all > saved_sum_all) | |
1763 { | |
1764 saved_profile_info = &file_data->profile_info; | |
1765 saved_sum_all = lto_gcov_summary.sum_all; | |
1766 saved_scale = scale; | |
1767 } | |
1768 } | |
1769 | |
1770 gcc_assert (saved_profile_info); | |
1771 | |
1772 /* Scale up the histogram from the profile that had the largest | |
1773 scaled sum_all above. */ | |
1774 for (h_ix = 0; h_ix < GCOV_HISTOGRAM_SIZE; h_ix++) | |
1775 { | |
1776 /* Scale up the min value as we did the corresponding sum_all | |
1777 above. Use that to find the new histogram index. */ | |
1778 gcov_type scaled_min | |
1779 = apply_scale (saved_profile_info->histogram[h_ix].min_value, | |
1780 saved_scale); | |
1781 /* The new index may be shared with another scaled histogram entry, | |
1782 so we need to account for a non-zero histogram entry at new_ix. */ | |
1783 unsigned new_ix = gcov_histo_index (scaled_min); | |
1784 lto_gcov_summary.histogram[new_ix].min_value | |
1785 = (lto_gcov_summary.histogram[new_ix].num_counters | |
1786 ? MIN (lto_gcov_summary.histogram[new_ix].min_value, scaled_min) | |
1787 : scaled_min); | |
1788 /* Some of the scaled counter values would ostensibly need to be placed | |
1789 into different (larger) histogram buckets, but we keep things simple | |
1790 here and place the scaled cumulative counter value in the bucket | |
1791 corresponding to the scaled minimum counter value. */ | |
1792 lto_gcov_summary.histogram[new_ix].cum_value | |
1793 += apply_scale (saved_profile_info->histogram[h_ix].cum_value, | |
1794 saved_scale); | |
1795 lto_gcov_summary.histogram[new_ix].num_counters | |
1796 += saved_profile_info->histogram[h_ix].num_counters; | |
1797 } | |
1798 | |
1799 /* Watch roundoff errors. */ | |
1800 if (lto_gcov_summary.sum_max < max_runs) | |
1801 lto_gcov_summary.sum_max = max_runs; | |
1802 | 1622 |
1803 /* If merging already happent at WPA time, we are done. */ | 1623 /* If merging already happent at WPA time, we are done. */ |
1804 if (flag_ltrans) | 1624 if (flag_ltrans) |
1805 return; | 1625 return; |
1806 | 1626 |
1821 file_data->file_name); | 1641 file_data->file_name); |
1822 | 1642 |
1823 if (scale == REG_BR_PROB_BASE) | 1643 if (scale == REG_BR_PROB_BASE) |
1824 continue; | 1644 continue; |
1825 for (edge = node->callees; edge; edge = edge->next_callee) | 1645 for (edge = node->callees; edge; edge = edge->next_callee) |
1826 edge->count = edge->count.apply_scale (scale, REG_BR_PROB_BASE); | 1646 if (edge->count.ipa ().nonzero_p ()) |
1827 node->count = node->count.apply_scale (scale, REG_BR_PROB_BASE); | 1647 edge->count = edge->count.apply_scale (scale, REG_BR_PROB_BASE); |
1648 for (edge = node->indirect_calls; edge; edge = edge->next_callee) | |
1649 if (edge->count.ipa ().nonzero_p ()) | |
1650 edge->count = edge->count.apply_scale (scale, REG_BR_PROB_BASE); | |
1651 if (node->count.ipa ().nonzero_p ()) | |
1652 node->count = node->count.apply_scale (scale, REG_BR_PROB_BASE); | |
1828 } | 1653 } |
1829 } | 1654 } |
1830 | 1655 |
1831 /* Input and merge the symtab from each of the .o files passed to | 1656 /* Input and merge the symtab from each of the .o files passed to |
1832 lto1. */ | 1657 lto1. */ |
1869 input_cgraph_opt_summary (nodes); | 1694 input_cgraph_opt_summary (nodes); |
1870 nodes.release (); | 1695 nodes.release (); |
1871 } | 1696 } |
1872 | 1697 |
1873 merge_profile_summaries (file_data_vec); | 1698 merge_profile_summaries (file_data_vec); |
1874 | |
1875 if (!flag_auto_profile) | |
1876 get_working_sets (); | |
1877 | |
1878 | 1699 |
1879 /* Clear out the aux field that was used to store enough state to | 1700 /* Clear out the aux field that was used to store enough state to |
1880 tell which nodes should be overwritten. */ | 1701 tell which nodes should be overwritten. */ |
1881 FOR_EACH_FUNCTION (node) | 1702 FOR_EACH_FUNCTION (node) |
1882 { | 1703 { |
1954 /* True when we need optimization summary for NODE. */ | 1775 /* True when we need optimization summary for NODE. */ |
1955 | 1776 |
1956 static int | 1777 static int |
1957 output_cgraph_opt_summary_p (struct cgraph_node *node) | 1778 output_cgraph_opt_summary_p (struct cgraph_node *node) |
1958 { | 1779 { |
1959 return (node->clone_of | 1780 return ((node->clone_of || node->former_clone_of) |
1960 && (node->clone.tree_map | 1781 && (node->clone.tree_map |
1961 || node->clone.args_to_skip | 1782 || node->clone.args_to_skip |
1962 || node->clone.combined_args_to_skip)); | 1783 || node->clone.combined_args_to_skip)); |
1963 } | 1784 } |
1964 | 1785 |