Mercurial > hg > CbC > CbC_gcc
comparison gcc/passes.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | d34655255c78 1830386684a0 |
comparison
equal
deleted
inserted
replaced
111:04ced10e8804 | 131:84e7813d76e9 |
---|---|
1 /* Top level of GCC compilers (cc1, cc1plus, etc.) | 1 /* Top level of GCC compilers (cc1, cc1plus, etc.) |
2 Copyright (C) 1987-2017 Free Software Foundation, Inc. | 2 Copyright (C) 1987-2018 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 6 GCC is free software; you can redistribute it and/or modify it under |
7 the terms of the GNU General Public License as published by the Free | 7 the terms of the GNU General Public License as published by the Free |
115 | 115 |
116 void | 116 void |
117 pass_manager::execute_early_local_passes () | 117 pass_manager::execute_early_local_passes () |
118 { | 118 { |
119 execute_pass_list (cfun, pass_build_ssa_passes_1->sub); | 119 execute_pass_list (cfun, pass_build_ssa_passes_1->sub); |
120 if (flag_check_pointer_bounds) | |
121 execute_pass_list (cfun, pass_chkp_instrumentation_passes_1->sub); | |
122 execute_pass_list (cfun, pass_local_optimization_passes_1->sub); | 120 execute_pass_list (cfun, pass_local_optimization_passes_1->sub); |
123 } | 121 } |
124 | 122 |
125 unsigned int | 123 unsigned int |
126 pass_manager::execute_pass_mode_switching () | 124 pass_manager::execute_pass_mode_switching () |
430 return execute_build_ssa_passes (); | 428 return execute_build_ssa_passes (); |
431 } | 429 } |
432 | 430 |
433 }; // class pass_build_ssa_passes | 431 }; // class pass_build_ssa_passes |
434 | 432 |
435 const pass_data pass_data_chkp_instrumentation_passes = | |
436 { | |
437 SIMPLE_IPA_PASS, /* type */ | |
438 "chkp_passes", /* name */ | |
439 OPTGROUP_NONE, /* optinfo_flags */ | |
440 TV_NONE, /* tv_id */ | |
441 0, /* properties_required */ | |
442 0, /* properties_provided */ | |
443 0, /* properties_destroyed */ | |
444 0, /* todo_flags_start */ | |
445 0, /* todo_flags_finish */ | |
446 }; | |
447 | |
448 class pass_chkp_instrumentation_passes : public simple_ipa_opt_pass | |
449 { | |
450 public: | |
451 pass_chkp_instrumentation_passes (gcc::context *ctxt) | |
452 : simple_ipa_opt_pass (pass_data_chkp_instrumentation_passes, ctxt) | |
453 {} | |
454 | |
455 /* opt_pass methods: */ | |
456 virtual bool gate (function *) | |
457 { | |
458 /* Don't bother doing anything if the program has errors. */ | |
459 return (flag_check_pointer_bounds | |
460 && !seen_error () && !in_lto_p); | |
461 } | |
462 | |
463 }; // class pass_chkp_instrumentation_passes | |
464 | |
465 const pass_data pass_data_local_optimization_passes = | 433 const pass_data pass_data_local_optimization_passes = |
466 { | 434 { |
467 SIMPLE_IPA_PASS, /* type */ | 435 SIMPLE_IPA_PASS, /* type */ |
468 "opt_local_passes", /* name */ | 436 "opt_local_passes", /* name */ |
469 OPTGROUP_NONE, /* optinfo_flags */ | 437 OPTGROUP_NONE, /* optinfo_flags */ |
498 { | 466 { |
499 return new pass_build_ssa_passes (ctxt); | 467 return new pass_build_ssa_passes (ctxt); |
500 } | 468 } |
501 | 469 |
502 simple_ipa_opt_pass * | 470 simple_ipa_opt_pass * |
503 make_pass_chkp_instrumentation_passes (gcc::context *ctxt) | |
504 { | |
505 return new pass_chkp_instrumentation_passes (ctxt); | |
506 } | |
507 | |
508 simple_ipa_opt_pass * | |
509 make_pass_local_optimization_passes (gcc::context *ctxt) | 471 make_pass_local_optimization_passes (gcc::context *ctxt) |
510 { | 472 { |
511 return new pass_local_optimization_passes (ctxt); | 473 return new pass_local_optimization_passes (ctxt); |
512 } | 474 } |
513 | 475 |
782 | 744 |
783 /* Buffer big enough to format a 32-bit UINT_MAX into. */ | 745 /* Buffer big enough to format a 32-bit UINT_MAX into. */ |
784 char num[11]; | 746 char num[11]; |
785 dump_kind dkind; | 747 dump_kind dkind; |
786 int id; | 748 int id; |
787 int optgroup_flags = OPTGROUP_NONE; | 749 optgroup_flags_t optgroup_flags = OPTGROUP_NONE; |
788 gcc::dump_manager *dumps = m_ctxt->get_dumps (); | 750 gcc::dump_manager *dumps = m_ctxt->get_dumps (); |
789 | 751 |
790 /* See below in next_pass_1. */ | 752 /* See below in next_pass_1. */ |
791 num[0] = '\0'; | 753 num[0] = '\0'; |
792 if (pass->static_pass_number != -1) | 754 if (pass->static_pass_number != -1) |
1206 | 1168 |
1207 slot = tab[pass->static_pass_number]; | 1169 slot = tab[pass->static_pass_number]; |
1208 if (!slot) | 1170 if (!slot) |
1209 return false; | 1171 return false; |
1210 | 1172 |
1211 cgraph_uid = func ? cgraph_node::get (func)->uid : 0; | 1173 cgraph_uid = func ? cgraph_node::get (func)->get_uid () : 0; |
1212 if (func && DECL_ASSEMBLER_NAME_SET_P (func)) | 1174 if (func && DECL_ASSEMBLER_NAME_SET_P (func)) |
1213 aname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func)); | 1175 aname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (func)); |
1214 | 1176 |
1215 range = slot; | 1177 range = slot; |
1216 while (range) | 1178 while (range) |
1440 | 1402 |
1441 void | 1403 void |
1442 pass_manager::register_pass (struct register_pass_info *pass_info) | 1404 pass_manager::register_pass (struct register_pass_info *pass_info) |
1443 { | 1405 { |
1444 bool all_instances, success; | 1406 bool all_instances, success; |
1445 gcc::dump_manager *dumps = m_ctxt->get_dumps (); | |
1446 | 1407 |
1447 /* The checks below could fail in buggy plugins. Existing GCC | 1408 /* The checks below could fail in buggy plugins. Existing GCC |
1448 passes should never fail these checks, so we mention plugin in | 1409 passes should never fail these checks, so we mention plugin in |
1449 the messages. */ | 1410 the messages. */ |
1450 if (!pass_info->pass) | 1411 if (!pass_info->pass) |
1478 "pass %qs not found but is referenced by new pass %qs", | 1439 "pass %qs not found but is referenced by new pass %qs", |
1479 pass_info->reference_pass_name, pass_info->pass->name); | 1440 pass_info->reference_pass_name, pass_info->pass->name); |
1480 | 1441 |
1481 /* OK, we have successfully inserted the new pass. We need to register | 1442 /* OK, we have successfully inserted the new pass. We need to register |
1482 the dump files for the newly added pass and its duplicates (if any). | 1443 the dump files for the newly added pass and its duplicates (if any). |
1483 Because the registration of plugin/backend passes happens after the | 1444 While doing so, we also delete the pass_list_node |
1484 command-line options are parsed, the options that specify single | |
1485 pass dumping (e.g. -fdump-tree-PASSNAME) cannot be used for new | |
1486 passes. Therefore we currently can only enable dumping of | |
1487 new passes when the 'dump-all' flags (e.g. -fdump-tree-all) | |
1488 are specified. While doing so, we also delete the pass_list_node | |
1489 objects created during pass positioning. */ | 1445 objects created during pass positioning. */ |
1446 gcc::dump_manager *dumps = m_ctxt->get_dumps (); | |
1490 while (added_pass_nodes) | 1447 while (added_pass_nodes) |
1491 { | 1448 { |
1492 struct pass_list_node *next_node = added_pass_nodes->next; | 1449 struct pass_list_node *next_node = added_pass_nodes->next; |
1493 enum tree_dump_index tdi; | 1450 |
1494 register_one_dump_file (added_pass_nodes->pass); | 1451 /* Handle -fdump-* and -fopt-info. */ |
1495 if (added_pass_nodes->pass->type == SIMPLE_IPA_PASS | 1452 dumps->register_pass (added_pass_nodes->pass); |
1496 || added_pass_nodes->pass->type == IPA_PASS) | 1453 |
1497 tdi = TDI_ipa_all; | |
1498 else if (added_pass_nodes->pass->type == GIMPLE_PASS) | |
1499 tdi = TDI_tree_all; | |
1500 else | |
1501 tdi = TDI_rtl_all; | |
1502 /* Check if dump-all flag is specified. */ | |
1503 if (dumps->get_dump_file_info (tdi)->pstate) | |
1504 { | |
1505 dumps->get_dump_file_info (added_pass_nodes->pass->static_pass_number) | |
1506 ->pstate = dumps->get_dump_file_info (tdi)->pstate; | |
1507 dumps->get_dump_file_info (added_pass_nodes->pass->static_pass_number) | |
1508 ->pflags = dumps->get_dump_file_info (tdi)->pflags; | |
1509 } | |
1510 XDELETE (added_pass_nodes); | 1454 XDELETE (added_pass_nodes); |
1511 added_pass_nodes = next_node; | 1455 added_pass_nodes = next_node; |
1512 } | 1456 } |
1513 } | 1457 } |
1514 | 1458 |
1582 #define POP_INSERT_PASSES() \ | 1526 #define POP_INSERT_PASSES() \ |
1583 } | 1527 } |
1584 | 1528 |
1585 #define NEXT_PASS(PASS, NUM) \ | 1529 #define NEXT_PASS(PASS, NUM) \ |
1586 do { \ | 1530 do { \ |
1587 gcc_assert (NULL == PASS ## _ ## NUM); \ | 1531 gcc_assert (PASS ## _ ## NUM == NULL); \ |
1588 if ((NUM) == 1) \ | 1532 if ((NUM) == 1) \ |
1589 PASS ## _1 = make_##PASS (m_ctxt); \ | 1533 PASS ## _1 = make_##PASS (m_ctxt); \ |
1590 else \ | 1534 else \ |
1591 { \ | 1535 { \ |
1592 gcc_assert (PASS ## _1); \ | 1536 gcc_assert (PASS ## _1); \ |
1671 keep the array visible to garbage collector to avoid reading collected | 1615 keep the array visible to garbage collector to avoid reading collected |
1672 out nodes. */ | 1616 out nodes. */ |
1673 static int nnodes; | 1617 static int nnodes; |
1674 static GTY ((length ("nnodes"))) cgraph_node **order; | 1618 static GTY ((length ("nnodes"))) cgraph_node **order; |
1675 | 1619 |
1620 #define uid_hash_t hash_set<int_hash <int, 0, -1> > | |
1621 | |
1676 /* Hook called when NODE is removed and therefore should be | 1622 /* Hook called when NODE is removed and therefore should be |
1677 excluded from order vector. DATA is an array of integers. | 1623 excluded from order vector. DATA is a hash set with removed nodes. */ |
1678 DATA[0] holds max index it may be accessed by. For cgraph | 1624 |
1679 node DATA[node->uid + 1] holds index of this node in order | |
1680 vector. */ | |
1681 static void | 1625 static void |
1682 remove_cgraph_node_from_order (cgraph_node *node, void *data) | 1626 remove_cgraph_node_from_order (cgraph_node *node, void *data) |
1683 { | 1627 { |
1684 int *order_idx = (int *)data; | 1628 uid_hash_t *removed_nodes = (uid_hash_t *)data; |
1685 | 1629 removed_nodes->add (node->get_uid ()); |
1686 if (node->uid >= order_idx[0]) | |
1687 return; | |
1688 | |
1689 int idx = order_idx[node->uid + 1]; | |
1690 if (idx >= 0 && idx < nnodes && order[idx] == node) | |
1691 order[idx] = NULL; | |
1692 } | 1630 } |
1693 | 1631 |
1694 /* If we are in IPA mode (i.e., current_function_decl is NULL), call | 1632 /* If we are in IPA mode (i.e., current_function_decl is NULL), call |
1695 function CALLBACK for every function in the call graph. Otherwise, | 1633 function CALLBACK for every function in the call graph. Otherwise, |
1696 call CALLBACK on the current function. | 1634 call CALLBACK on the current function. |
1703 if (current_function_decl) | 1641 if (current_function_decl) |
1704 callback (cfun, data); | 1642 callback (cfun, data); |
1705 else | 1643 else |
1706 { | 1644 { |
1707 cgraph_node_hook_list *hook; | 1645 cgraph_node_hook_list *hook; |
1708 int *order_idx; | 1646 uid_hash_t removed_nodes; |
1709 gcc_assert (!order); | 1647 gcc_assert (!order); |
1710 order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count); | 1648 order = ggc_vec_alloc<cgraph_node *> (symtab->cgraph_count); |
1711 | 1649 |
1712 order_idx = XALLOCAVEC (int, symtab->cgraph_max_uid + 1); | |
1713 memset (order_idx + 1, -1, sizeof (int) * symtab->cgraph_max_uid); | |
1714 order_idx[0] = symtab->cgraph_max_uid; | |
1715 | |
1716 nnodes = ipa_reverse_postorder (order); | 1650 nnodes = ipa_reverse_postorder (order); |
1717 for (i = nnodes - 1; i >= 0; i--) | 1651 for (i = nnodes - 1; i >= 0; i--) |
1718 { | 1652 order[i]->process = 1; |
1719 order[i]->process = 1; | |
1720 order_idx[order[i]->uid + 1] = i; | |
1721 } | |
1722 hook = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order, | 1653 hook = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order, |
1723 order_idx); | 1654 &removed_nodes); |
1724 for (i = nnodes - 1; i >= 0; i--) | 1655 for (i = nnodes - 1; i >= 0; i--) |
1725 { | 1656 { |
1657 cgraph_node *node = order[i]; | |
1658 | |
1726 /* Function could be inlined and removed as unreachable. */ | 1659 /* Function could be inlined and removed as unreachable. */ |
1727 if (!order[i]) | 1660 if (node == NULL || removed_nodes.contains (node->get_uid ())) |
1728 continue; | 1661 continue; |
1729 | |
1730 struct cgraph_node *node = order[i]; | |
1731 | 1662 |
1732 /* Allow possibly removed nodes to be garbage collected. */ | 1663 /* Allow possibly removed nodes to be garbage collected. */ |
1733 order[i] = NULL; | 1664 order[i] = NULL; |
1734 node->process = 0; | 1665 node->process = 0; |
1735 if (node->has_gimple_body_p ()) | 1666 if (node->has_gimple_body_p ()) |
2690 struct cgraph_node **order; | 2621 struct cgraph_node **order; |
2691 | 2622 |
2692 if ((!flag_generate_lto && !flag_generate_offload) || seen_error ()) | 2623 if ((!flag_generate_lto && !flag_generate_offload) || seen_error ()) |
2693 return; | 2624 return; |
2694 | 2625 |
2626 gcc_assert (!dump_file); | |
2627 streamer_dump_file = dump_begin (TDI_lto_stream_out, NULL); | |
2628 | |
2695 select_what_to_stream (); | 2629 select_what_to_stream (); |
2696 | 2630 |
2697 encoder = lto_symtab_encoder_new (false); | 2631 encoder = lto_symtab_encoder_new (false); |
2698 | 2632 |
2699 /* Create the callgraph set in the same order used in | 2633 /* Create the callgraph set in the same order used in |
2706 | 2640 |
2707 for (i = order_pos - 1; i >= 0; i--) | 2641 for (i = order_pos - 1; i >= 0; i--) |
2708 { | 2642 { |
2709 struct cgraph_node *node = order[i]; | 2643 struct cgraph_node *node = order[i]; |
2710 | 2644 |
2711 if (node->has_gimple_body_p ()) | 2645 if (gimple_has_body_p (node->decl)) |
2712 { | 2646 { |
2713 /* When streaming out references to statements as part of some IPA | 2647 /* When streaming out references to statements as part of some IPA |
2714 pass summary, the statements need to have uids assigned and the | 2648 pass summary, the statements need to have uids assigned and the |
2715 following does that for all the IPA passes here. Naturally, this | 2649 following does that for all the IPA passes here. Naturally, this |
2716 ordering then matches the one IPA-passes get in their stmt_fixup | 2650 ordering then matches the one IPA-passes get in their stmt_fixup |
2732 lto_set_symtab_encoder_in_partition (encoder, vnode); | 2666 lto_set_symtab_encoder_in_partition (encoder, vnode); |
2733 | 2667 |
2734 ipa_write_summaries_1 (compute_ltrans_boundary (encoder)); | 2668 ipa_write_summaries_1 (compute_ltrans_boundary (encoder)); |
2735 | 2669 |
2736 free (order); | 2670 free (order); |
2671 if (streamer_dump_file) | |
2672 { | |
2673 dump_end (TDI_lto_stream_out, streamer_dump_file); | |
2674 streamer_dump_file = NULL; | |
2675 } | |
2737 } | 2676 } |
2738 | 2677 |
2739 /* Same as execute_pass_list but assume that subpasses of IPA passes | 2678 /* Same as execute_pass_list but assume that subpasses of IPA passes |
2740 are local passes. If SET is not NULL, write out optimization summaries of | 2679 are local passes. If SET is not NULL, write out optimization summaries of |
2741 only those node in SET. */ | 2680 only those node in SET. */ |