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. */