Mercurial > hg > CbC > CbC_gcc
comparison gcc/cgraphunit.c @ 132:d34655255c78
update gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 10:21:07 +0900 |
parents | 84e7813d76e9 |
children | 1830386684a0 |
comparison
equal
deleted
inserted
replaced
130:e108057fa461 | 132:d34655255c78 |
---|---|
1 /* Driver of optimization process | 1 /* Driver of optimization process |
2 Copyright (C) 2003-2017 Free Software Foundation, Inc. | 2 Copyright (C) 2003-2018 Free Software Foundation, Inc. |
3 Contributed by Jan Hubicka | 3 Contributed by Jan Hubicka |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
200 #include "cfgloop.h" | 200 #include "cfgloop.h" |
201 #include "context.h" | 201 #include "context.h" |
202 #include "pass_manager.h" | 202 #include "pass_manager.h" |
203 #include "tree-nested.h" | 203 #include "tree-nested.h" |
204 #include "dbgcnt.h" | 204 #include "dbgcnt.h" |
205 #include "tree-chkp.h" | |
206 #include "lto-section-names.h" | 205 #include "lto-section-names.h" |
207 #include "stringpool.h" | 206 #include "stringpool.h" |
208 #include "attribs.h" | 207 #include "attribs.h" |
209 | 208 |
210 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a | 209 /* Queue of cgraph nodes scheduled to be added into cgraph. This is a |
618 | 617 |
619 if (thunk.thunk_p) | 618 if (thunk.thunk_p) |
620 { | 619 { |
621 cgraph_node *t = cgraph_node::get (thunk.alias); | 620 cgraph_node *t = cgraph_node::get (thunk.alias); |
622 | 621 |
623 create_edge (t, NULL, t->count, CGRAPH_FREQ_BASE); | 622 create_edge (t, NULL, t->count); |
624 callees->can_throw_external = !TREE_NOTHROW (t->decl); | 623 callees->can_throw_external = !TREE_NOTHROW (t->decl); |
625 /* Target code in expand_thunk may need the thunk's target | 624 /* Target code in expand_thunk may need the thunk's target |
626 to be analyzed, so recurse here. */ | 625 to be analyzed, so recurse here. */ |
627 if (!t->analyzed) | 626 if (!t->analyzed && t->definition) |
628 t->analyze (); | 627 t->analyze (); |
629 if (t->alias) | 628 if (t->alias) |
630 { | 629 { |
631 t = t->get_alias_target (); | 630 t = t->get_alias_target (); |
632 if (!t->analyzed) | 631 if (!t->analyzed && t->definition) |
633 t->analyze (); | 632 t->analyze (); |
634 } | 633 } |
635 if (!expand_thunk (false, false)) | 634 bool ret = expand_thunk (false, false); |
636 { | |
637 thunk.alias = NULL; | |
638 return; | |
639 } | |
640 thunk.alias = NULL; | 635 thunk.alias = NULL; |
636 if (!ret) | |
637 return; | |
641 } | 638 } |
642 if (alias) | 639 if (alias) |
643 resolve_alias (cgraph_node::get (alias_target), transparent_alias); | 640 resolve_alias (cgraph_node::get (alias_target), transparent_alias); |
644 else if (dispatcher_function) | 641 else if (dispatcher_function) |
645 { | 642 { |
785 " because function is defined"); | 782 " because function is defined"); |
786 DECL_WEAK (decl) = 0; | 783 DECL_WEAK (decl) = 0; |
787 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref", | 784 DECL_ATTRIBUTES (decl) = remove_attribute ("weakref", |
788 DECL_ATTRIBUTES (decl)); | 785 DECL_ATTRIBUTES (decl)); |
789 } | 786 } |
787 else if (lookup_attribute ("alias", DECL_ATTRIBUTES (decl)) | |
788 && node->definition | |
789 && !node->alias) | |
790 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes, | |
791 "%<alias%> attribute ignored" | |
792 " because function is defined"); | |
790 | 793 |
791 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl)) | 794 if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (decl)) |
792 && !DECL_DECLARED_INLINE_P (decl) | 795 && !DECL_DECLARED_INLINE_P (decl) |
793 /* redefining extern inline function makes it DECL_UNINLINABLE. */ | 796 /* redefining extern inline function makes it DECL_UNINLINABLE. */ |
794 && !DECL_UNINLINABLE (decl)) | 797 && !DECL_UNINLINABLE (decl)) |
863 finished. */ | 866 finished. */ |
864 if (symtab->state == FINISHED | 867 if (symtab->state == FINISHED |
865 || (node->no_reorder | 868 || (node->no_reorder |
866 && symtab->state == EXPANSION)) | 869 && symtab->state == EXPANSION)) |
867 node->assemble_decl (); | 870 node->assemble_decl (); |
868 | |
869 if (DECL_INITIAL (decl)) | |
870 chkp_register_var_initializer (decl); | |
871 } | 871 } |
872 | 872 |
873 /* EDGE is an polymorphic call. Mark all possible targets as reachable | 873 /* EDGE is an polymorphic call. Mark all possible targets as reachable |
874 and if there is only one target, perform trivial devirtualization. | 874 and if there is only one target, perform trivial devirtualization. |
875 REACHABLE_CALL_TARGETS collects target lists we already walked to | 875 REACHABLE_CALL_TARGETS collects target lists we already walked to |
930 edge->call_stmt, 0, | 930 edge->call_stmt, 0, |
931 TDF_SLIM); | 931 TDF_SLIM); |
932 } | 932 } |
933 if (dump_enabled_p ()) | 933 if (dump_enabled_p ()) |
934 { | 934 { |
935 location_t locus = gimple_location_safe (edge->call_stmt); | 935 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, edge->call_stmt, |
936 dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, locus, | |
937 "devirtualizing call in %s to %s\n", | 936 "devirtualizing call in %s to %s\n", |
938 edge->caller->name (), target->name ()); | 937 edge->caller->name (), target->name ()); |
939 } | 938 } |
940 | 939 |
941 edge->make_direct (target); | 940 edge->make_direct (target); |
942 edge->redirect_call_stmt_to_callee (); | 941 edge->redirect_call_stmt_to_callee (); |
943 | |
944 /* Call to __builtin_unreachable shouldn't be instrumented. */ | |
945 if (!targets.length ()) | |
946 gimple_call_set_with_bounds (edge->call_stmt, false); | |
947 | 942 |
948 if (symtab->dump_file) | 943 if (symtab->dump_file) |
949 { | 944 { |
950 fprintf (symtab->dump_file, | 945 fprintf (symtab->dump_file, |
951 "Devirtualized as: "); | 946 "Devirtualized as: "); |
1305 maybe_diag_incompatible_alias (tree alias, tree target) | 1300 maybe_diag_incompatible_alias (tree alias, tree target) |
1306 { | 1301 { |
1307 tree altype = TREE_TYPE (alias); | 1302 tree altype = TREE_TYPE (alias); |
1308 tree targtype = TREE_TYPE (target); | 1303 tree targtype = TREE_TYPE (target); |
1309 | 1304 |
1310 bool ifunc = lookup_attribute ("ifunc", DECL_ATTRIBUTES (alias)); | 1305 bool ifunc = cgraph_node::get (alias)->ifunc_resolver; |
1311 tree funcptr = altype; | 1306 tree funcptr = altype; |
1312 | 1307 |
1313 if (ifunc) | 1308 if (ifunc) |
1314 { | 1309 { |
1315 /* Handle attribute ifunc first. */ | 1310 /* Handle attribute ifunc first. */ |
1365 without knowing the exact type, as libstdc++ does. */ | 1360 without knowing the exact type, as libstdc++ does. */ |
1366 if (ifunc) | 1361 if (ifunc) |
1367 { | 1362 { |
1368 funcptr = build_pointer_type (funcptr); | 1363 funcptr = build_pointer_type (funcptr); |
1369 | 1364 |
1365 auto_diagnostic_group d; | |
1370 if (warning_at (DECL_SOURCE_LOCATION (target), | 1366 if (warning_at (DECL_SOURCE_LOCATION (target), |
1371 OPT_Wattribute_alias, | 1367 OPT_Wattribute_alias, |
1372 "%<ifunc%> resolver for %qD should return %qT", | 1368 "%<ifunc%> resolver for %qD should return %qT", |
1373 alias, funcptr)) | 1369 alias, funcptr)) |
1374 inform (DECL_SOURCE_LOCATION (alias), | 1370 inform (DECL_SOURCE_LOCATION (alias), |
1375 "resolver indirect function declared here"); | 1371 "resolver indirect function declared here"); |
1376 } | 1372 } |
1377 else if (warning_at (DECL_SOURCE_LOCATION (alias), | 1373 else |
1378 OPT_Wattribute_alias, | 1374 { |
1379 "%qD alias between functions of incompatible " | 1375 auto_diagnostic_group d; |
1380 "types %qT and %qT", alias, altype, targtype)) | 1376 if (warning_at (DECL_SOURCE_LOCATION (alias), |
1381 inform (DECL_SOURCE_LOCATION (target), | 1377 OPT_Wattribute_alias, |
1382 "aliased declaration here"); | 1378 "%qD alias between functions of incompatible " |
1379 "types %qT and %qT", alias, altype, targtype)) | |
1380 inform (DECL_SOURCE_LOCATION (target), | |
1381 "aliased declaration here"); | |
1382 } | |
1383 } | 1383 } |
1384 } | 1384 } |
1385 | 1385 |
1386 /* Translate the ugly representation of aliases as alias pairs into nice | 1386 /* Translate the ugly representation of aliases as alias pairs into nice |
1387 representation in callgraph. We don't handle all cases yet, | 1387 representation in callgraph. We don't handle all cases yet, |
1599 init_loops_structure (cfun, loops_for_fn (cfun), 1); | 1599 init_loops_structure (cfun, loops_for_fn (cfun), 1); |
1600 loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES; | 1600 loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES; |
1601 | 1601 |
1602 /* Create BB for body of the function and connect it properly. */ | 1602 /* Create BB for body of the function and connect it properly. */ |
1603 ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = count; | 1603 ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = count; |
1604 ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency = BB_FREQ_MAX; | |
1605 EXIT_BLOCK_PTR_FOR_FN (cfun)->count = count; | 1604 EXIT_BLOCK_PTR_FOR_FN (cfun)->count = count; |
1606 EXIT_BLOCK_PTR_FOR_FN (cfun)->frequency = BB_FREQ_MAX; | |
1607 bb = create_basic_block (NULL, ENTRY_BLOCK_PTR_FOR_FN (cfun)); | 1605 bb = create_basic_block (NULL, ENTRY_BLOCK_PTR_FOR_FN (cfun)); |
1608 bb->count = count; | 1606 bb->count = count; |
1609 bb->frequency = BB_FREQ_MAX; | |
1610 e = make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU); | 1607 e = make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU); |
1611 e->probability = profile_probability::always (); | 1608 e->probability = profile_probability::always (); |
1612 e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0); | 1609 e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0); |
1613 e->probability = profile_probability::always (); | 1610 e->probability = profile_probability::always (); |
1614 add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father); | 1611 add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father); |
1615 | 1612 |
1616 return bb; | 1613 return bb; |
1617 } | 1614 } |
1618 | 1615 |
1619 /* Adjust PTR by the constant FIXED_OFFSET, and by the vtable | 1616 /* Adjust PTR by the constant FIXED_OFFSET, by the vtable offset indicated by |
1620 offset indicated by VIRTUAL_OFFSET, if that is | 1617 VIRTUAL_OFFSET, and by the indirect offset indicated by INDIRECT_OFFSET, if |
1621 non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and | 1618 it is non-null. THIS_ADJUSTING is nonzero for a this adjusting thunk and zero |
1622 zero for a result adjusting thunk. */ | 1619 for a result adjusting thunk. */ |
1623 | 1620 |
1624 tree | 1621 tree |
1625 thunk_adjust (gimple_stmt_iterator * bsi, | 1622 thunk_adjust (gimple_stmt_iterator * bsi, |
1626 tree ptr, bool this_adjusting, | 1623 tree ptr, bool this_adjusting, |
1627 HOST_WIDE_INT fixed_offset, tree virtual_offset) | 1624 HOST_WIDE_INT fixed_offset, tree virtual_offset, |
1625 HOST_WIDE_INT indirect_offset) | |
1628 { | 1626 { |
1629 gassign *stmt; | 1627 gassign *stmt; |
1630 tree ret; | 1628 tree ret; |
1631 | 1629 |
1632 if (this_adjusting | 1630 if (this_adjusting |
1637 ptr, | 1635 ptr, |
1638 fixed_offset)); | 1636 fixed_offset)); |
1639 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); | 1637 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); |
1640 } | 1638 } |
1641 | 1639 |
1640 if (!vtable_entry_type && (virtual_offset || indirect_offset != 0)) | |
1641 { | |
1642 tree vfunc_type = make_node (FUNCTION_TYPE); | |
1643 TREE_TYPE (vfunc_type) = integer_type_node; | |
1644 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE; | |
1645 layout_type (vfunc_type); | |
1646 | |
1647 vtable_entry_type = build_pointer_type (vfunc_type); | |
1648 } | |
1649 | |
1642 /* If there's a virtual offset, look up that value in the vtable and | 1650 /* If there's a virtual offset, look up that value in the vtable and |
1643 adjust the pointer again. */ | 1651 adjust the pointer again. */ |
1644 if (virtual_offset) | 1652 if (virtual_offset) |
1645 { | 1653 { |
1646 tree vtabletmp; | 1654 tree vtabletmp; |
1647 tree vtabletmp2; | 1655 tree vtabletmp2; |
1648 tree vtabletmp3; | 1656 tree vtabletmp3; |
1649 | |
1650 if (!vtable_entry_type) | |
1651 { | |
1652 tree vfunc_type = make_node (FUNCTION_TYPE); | |
1653 TREE_TYPE (vfunc_type) = integer_type_node; | |
1654 TYPE_ARG_TYPES (vfunc_type) = NULL_TREE; | |
1655 layout_type (vfunc_type); | |
1656 | |
1657 vtable_entry_type = build_pointer_type (vfunc_type); | |
1658 } | |
1659 | 1657 |
1660 vtabletmp = | 1658 vtabletmp = |
1661 create_tmp_reg (build_pointer_type | 1659 create_tmp_reg (build_pointer_type |
1662 (build_pointer_type (vtable_entry_type)), "vptr"); | 1660 (build_pointer_type (vtable_entry_type)), "vptr"); |
1663 | 1661 |
1688 build_simple_mem_ref (vtabletmp2)); | 1686 build_simple_mem_ref (vtabletmp2)); |
1689 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); | 1687 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); |
1690 | 1688 |
1691 /* Adjust the `this' pointer. */ | 1689 /* Adjust the `this' pointer. */ |
1692 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3); | 1690 ptr = fold_build_pointer_plus_loc (input_location, ptr, vtabletmp3); |
1691 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false, | |
1692 GSI_CONTINUE_LINKING); | |
1693 } | |
1694 | |
1695 /* Likewise for an offset that is stored in the object that contains the | |
1696 vtable. */ | |
1697 if (indirect_offset != 0) | |
1698 { | |
1699 tree offset_ptr, offset_tree; | |
1700 | |
1701 /* Get the address of the offset. */ | |
1702 offset_ptr | |
1703 = create_tmp_reg (build_pointer_type | |
1704 (build_pointer_type (vtable_entry_type)), | |
1705 "offset_ptr"); | |
1706 stmt = gimple_build_assign (offset_ptr, | |
1707 build1 (NOP_EXPR, TREE_TYPE (offset_ptr), | |
1708 ptr)); | |
1709 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); | |
1710 | |
1711 stmt = gimple_build_assign | |
1712 (offset_ptr, | |
1713 fold_build_pointer_plus_hwi_loc (input_location, offset_ptr, | |
1714 indirect_offset)); | |
1715 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); | |
1716 | |
1717 /* Get the offset itself. */ | |
1718 offset_tree = create_tmp_reg (TREE_TYPE (TREE_TYPE (offset_ptr)), | |
1719 "offset"); | |
1720 stmt = gimple_build_assign (offset_tree, | |
1721 build_simple_mem_ref (offset_ptr)); | |
1722 gsi_insert_after (bsi, stmt, GSI_NEW_STMT); | |
1723 | |
1724 /* Adjust the `this' pointer. */ | |
1725 ptr = fold_build_pointer_plus_loc (input_location, ptr, offset_tree); | |
1693 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false, | 1726 ptr = force_gimple_operand_gsi (bsi, ptr, true, NULL_TREE, false, |
1694 GSI_CONTINUE_LINKING); | 1727 GSI_CONTINUE_LINKING); |
1695 } | 1728 } |
1696 | 1729 |
1697 if (!this_adjusting | 1730 if (!this_adjusting |
1730 cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) | 1763 cgraph_node::expand_thunk (bool output_asm_thunks, bool force_gimple_thunk) |
1731 { | 1764 { |
1732 bool this_adjusting = thunk.this_adjusting; | 1765 bool this_adjusting = thunk.this_adjusting; |
1733 HOST_WIDE_INT fixed_offset = thunk.fixed_offset; | 1766 HOST_WIDE_INT fixed_offset = thunk.fixed_offset; |
1734 HOST_WIDE_INT virtual_value = thunk.virtual_value; | 1767 HOST_WIDE_INT virtual_value = thunk.virtual_value; |
1768 HOST_WIDE_INT indirect_offset = thunk.indirect_offset; | |
1735 tree virtual_offset = NULL; | 1769 tree virtual_offset = NULL; |
1736 tree alias = callees->callee->decl; | 1770 tree alias = callees->callee->decl; |
1737 tree thunk_fndecl = decl; | 1771 tree thunk_fndecl = decl; |
1738 tree a; | 1772 tree a; |
1739 | 1773 |
1740 /* Instrumentation thunk is the same function with | 1774 /* Instrumentation thunk is the same function with |
1741 a different signature. Never need to expand it. */ | 1775 a different signature. Never need to expand it. */ |
1742 if (thunk.add_pointer_bounds_args) | 1776 if (thunk.add_pointer_bounds_args) |
1743 return false; | 1777 return false; |
1744 | 1778 |
1745 if (!force_gimple_thunk && this_adjusting | 1779 if (!force_gimple_thunk |
1780 && this_adjusting | |
1781 && indirect_offset == 0 | |
1782 && !DECL_EXTERNAL (alias) | |
1783 && !DECL_STATIC_CHAIN (alias) | |
1746 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, | 1784 && targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset, |
1747 virtual_value, alias)) | 1785 virtual_value, alias)) |
1748 { | 1786 { |
1749 const char *fnname; | 1787 const char *fnname; |
1750 tree fn_block; | 1788 tree fn_block; |
1813 int nargs = 0; | 1851 int nargs = 0; |
1814 tree arg; | 1852 tree arg; |
1815 int i; | 1853 int i; |
1816 tree resdecl; | 1854 tree resdecl; |
1817 tree restmp = NULL; | 1855 tree restmp = NULL; |
1818 tree resbnd = NULL; | |
1819 | 1856 |
1820 gcall *call; | 1857 gcall *call; |
1821 greturn *ret; | 1858 greturn *ret; |
1822 bool alias_is_noreturn = TREE_THIS_VOLATILE (alias); | 1859 bool alias_is_noreturn = TREE_THIS_VOLATILE (alias); |
1823 | 1860 |
1824 /* We may be called from expand_thunk that releses body except for | 1861 /* We may be called from expand_thunk that releses body except for |
1825 DECL_ARGUMENTS. In this case force_gimple_thunk is true. */ | 1862 DECL_ARGUMENTS. In this case force_gimple_thunk is true. */ |
1826 if (in_lto_p && !force_gimple_thunk) | 1863 if (in_lto_p && !force_gimple_thunk) |
1827 get_untransformed_body (); | 1864 get_untransformed_body (); |
1865 | |
1866 /* We need to force DECL_IGNORED_P when the thunk is created | |
1867 after early debug was run. */ | |
1868 if (force_gimple_thunk) | |
1869 DECL_IGNORED_P (thunk_fndecl) = 1; | |
1870 | |
1828 a = DECL_ARGUMENTS (thunk_fndecl); | 1871 a = DECL_ARGUMENTS (thunk_fndecl); |
1829 | 1872 |
1830 current_function_decl = thunk_fndecl; | 1873 current_function_decl = thunk_fndecl; |
1831 | 1874 |
1832 /* Ensure thunks are emitted in their correct sections. */ | 1875 /* Ensure thunks are emitted in their correct sections. */ |
1833 resolve_unique_section (thunk_fndecl, 0, | 1876 resolve_unique_section (thunk_fndecl, 0, |
1834 flag_function_sections); | 1877 flag_function_sections); |
1835 | 1878 |
1836 DECL_IGNORED_P (thunk_fndecl) = 1; | |
1837 bitmap_obstack_initialize (NULL); | 1879 bitmap_obstack_initialize (NULL); |
1838 | 1880 |
1839 if (thunk.virtual_offset_p) | 1881 if (thunk.virtual_offset_p) |
1840 virtual_offset = size_int (virtual_value); | 1882 virtual_offset = size_int (virtual_value); |
1841 | 1883 |
1844 if (DECL_RESULT (thunk_fndecl) == NULL_TREE) | 1886 if (DECL_RESULT (thunk_fndecl) == NULL_TREE) |
1845 { | 1887 { |
1846 resdecl = build_decl (input_location, RESULT_DECL, 0, restype); | 1888 resdecl = build_decl (input_location, RESULT_DECL, 0, restype); |
1847 DECL_ARTIFICIAL (resdecl) = 1; | 1889 DECL_ARTIFICIAL (resdecl) = 1; |
1848 DECL_IGNORED_P (resdecl) = 1; | 1890 DECL_IGNORED_P (resdecl) = 1; |
1891 DECL_CONTEXT (resdecl) = thunk_fndecl; | |
1849 DECL_RESULT (thunk_fndecl) = resdecl; | 1892 DECL_RESULT (thunk_fndecl) = resdecl; |
1850 DECL_CONTEXT (DECL_RESULT (thunk_fndecl)) = thunk_fndecl; | |
1851 } | 1893 } |
1852 else | 1894 else |
1853 resdecl = DECL_RESULT (thunk_fndecl); | 1895 resdecl = DECL_RESULT (thunk_fndecl); |
1854 | 1896 |
1897 profile_count cfg_count = count; | |
1898 if (!cfg_count.initialized_p ()) | |
1899 cfg_count = profile_count::from_gcov_type (BB_FREQ_MAX).guessed_local (); | |
1900 | |
1855 bb = then_bb = else_bb = return_bb | 1901 bb = then_bb = else_bb = return_bb |
1856 = init_lowered_empty_function (thunk_fndecl, true, count); | 1902 = init_lowered_empty_function (thunk_fndecl, true, cfg_count); |
1857 | 1903 |
1858 bsi = gsi_start_bb (bb); | 1904 bsi = gsi_start_bb (bb); |
1859 | 1905 |
1860 /* Build call to the function being thunked. */ | 1906 /* Build call to the function being thunked. */ |
1861 if (!VOID_TYPE_P (restype) | 1907 if (!VOID_TYPE_P (restype) |
1878 if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl))) | 1924 if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl))) |
1879 { | 1925 { |
1880 restmp = resdecl; | 1926 restmp = resdecl; |
1881 | 1927 |
1882 if (VAR_P (restmp)) | 1928 if (VAR_P (restmp)) |
1883 add_local_decl (cfun, restmp); | 1929 { |
1884 BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp; | 1930 add_local_decl (cfun, restmp); |
1931 BLOCK_VARS (DECL_INITIAL (current_function_decl)) | |
1932 = restmp; | |
1933 } | |
1885 } | 1934 } |
1886 else | 1935 else |
1887 restmp = create_tmp_var (restype, "retval"); | 1936 restmp = create_tmp_var (restype, "retval"); |
1888 } | 1937 } |
1889 else | 1938 else |
1896 i = 0; | 1945 i = 0; |
1897 arg = a; | 1946 arg = a; |
1898 if (this_adjusting) | 1947 if (this_adjusting) |
1899 { | 1948 { |
1900 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset, | 1949 vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset, |
1901 virtual_offset)); | 1950 virtual_offset, indirect_offset)); |
1902 arg = DECL_CHAIN (a); | 1951 arg = DECL_CHAIN (a); |
1903 i = 1; | 1952 i = 1; |
1904 } | 1953 } |
1905 | 1954 |
1906 if (nargs) | 1955 if (nargs) |
1921 vargs.quick_push (tmp); | 1970 vargs.quick_push (tmp); |
1922 } | 1971 } |
1923 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs); | 1972 call = gimple_build_call_vec (build_fold_addr_expr_loc (0, alias), vargs); |
1924 callees->call_stmt = call; | 1973 callees->call_stmt = call; |
1925 gimple_call_set_from_thunk (call, true); | 1974 gimple_call_set_from_thunk (call, true); |
1926 gimple_call_set_with_bounds (call, instrumentation_clone); | 1975 if (DECL_STATIC_CHAIN (alias)) |
1976 { | |
1977 tree p = DECL_STRUCT_FUNCTION (alias)->static_chain_decl; | |
1978 tree type = TREE_TYPE (p); | |
1979 tree decl = build_decl (DECL_SOURCE_LOCATION (thunk_fndecl), | |
1980 PARM_DECL, create_tmp_var_name ("CHAIN"), | |
1981 type); | |
1982 DECL_ARTIFICIAL (decl) = 1; | |
1983 DECL_IGNORED_P (decl) = 1; | |
1984 TREE_USED (decl) = 1; | |
1985 DECL_CONTEXT (decl) = thunk_fndecl; | |
1986 DECL_ARG_TYPE (decl) = type; | |
1987 TREE_READONLY (decl) = 1; | |
1988 | |
1989 struct function *sf = DECL_STRUCT_FUNCTION (thunk_fndecl); | |
1990 sf->static_chain_decl = decl; | |
1991 | |
1992 gimple_call_set_chain (call, decl); | |
1993 } | |
1927 | 1994 |
1928 /* Return slot optimization is always possible and in fact requred to | 1995 /* Return slot optimization is always possible and in fact requred to |
1929 return values with DECL_BY_REFERENCE. */ | 1996 return values with DECL_BY_REFERENCE. */ |
1930 if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl)) | 1997 if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl)) |
1931 && (!is_gimple_reg_type (TREE_TYPE (resdecl)) | 1998 && (!is_gimple_reg_type (TREE_TYPE (resdecl)) |
1939 TREE_TYPE (TREE_TYPE (alias)))); | 2006 TREE_TYPE (TREE_TYPE (alias)))); |
1940 } | 2007 } |
1941 gsi_insert_after (&bsi, call, GSI_NEW_STMT); | 2008 gsi_insert_after (&bsi, call, GSI_NEW_STMT); |
1942 if (!alias_is_noreturn) | 2009 if (!alias_is_noreturn) |
1943 { | 2010 { |
1944 if (instrumentation_clone | |
1945 && !DECL_BY_REFERENCE (resdecl) | |
1946 && restmp | |
1947 && BOUNDED_P (restmp)) | |
1948 { | |
1949 resbnd = chkp_insert_retbnd_call (NULL, restmp, &bsi); | |
1950 create_edge (get_create (gimple_call_fndecl (gsi_stmt (bsi))), | |
1951 as_a <gcall *> (gsi_stmt (bsi)), | |
1952 callees->count, callees->frequency); | |
1953 } | |
1954 | |
1955 if (restmp && !this_adjusting | 2011 if (restmp && !this_adjusting |
1956 && (fixed_offset || virtual_offset)) | 2012 && (fixed_offset || virtual_offset)) |
1957 { | 2013 { |
1958 tree true_label = NULL_TREE; | 2014 tree true_label = NULL_TREE; |
1959 | 2015 |
1964 /* If the return type is a pointer, we need to | 2020 /* If the return type is a pointer, we need to |
1965 protect against NULL. We know there will be an | 2021 protect against NULL. We know there will be an |
1966 adjustment, because that's why we're emitting a | 2022 adjustment, because that's why we're emitting a |
1967 thunk. */ | 2023 thunk. */ |
1968 then_bb = create_basic_block (NULL, bb); | 2024 then_bb = create_basic_block (NULL, bb); |
1969 then_bb->count = count - count.apply_scale (1, 16); | 2025 then_bb->count = cfg_count - cfg_count.apply_scale (1, 16); |
1970 then_bb->frequency = BB_FREQ_MAX - BB_FREQ_MAX / 16; | |
1971 return_bb = create_basic_block (NULL, then_bb); | 2026 return_bb = create_basic_block (NULL, then_bb); |
1972 return_bb->count = count; | 2027 return_bb->count = cfg_count; |
1973 return_bb->frequency = BB_FREQ_MAX; | |
1974 else_bb = create_basic_block (NULL, else_bb); | 2028 else_bb = create_basic_block (NULL, else_bb); |
1975 then_bb->count = count.apply_scale (1, 16); | 2029 else_bb->count = cfg_count.apply_scale (1, 16); |
1976 then_bb->frequency = BB_FREQ_MAX / 16; | |
1977 add_bb_to_loop (then_bb, bb->loop_father); | 2030 add_bb_to_loop (then_bb, bb->loop_father); |
1978 add_bb_to_loop (return_bb, bb->loop_father); | 2031 add_bb_to_loop (return_bb, bb->loop_father); |
1979 add_bb_to_loop (else_bb, bb->loop_father); | 2032 add_bb_to_loop (else_bb, bb->loop_father); |
1980 remove_edge (single_succ_edge (bb)); | 2033 remove_edge (single_succ_edge (bb)); |
1981 true_label = gimple_block_label (then_bb); | 2034 true_label = gimple_block_label (then_bb); |
1996 e->probability = profile_probability::always (); | 2049 e->probability = profile_probability::always (); |
1997 bsi = gsi_last_bb (then_bb); | 2050 bsi = gsi_last_bb (then_bb); |
1998 } | 2051 } |
1999 | 2052 |
2000 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0, | 2053 restmp = thunk_adjust (&bsi, restmp, /*this_adjusting=*/0, |
2001 fixed_offset, virtual_offset); | 2054 fixed_offset, virtual_offset, |
2055 indirect_offset); | |
2002 if (true_label) | 2056 if (true_label) |
2003 { | 2057 { |
2004 gimple *stmt; | 2058 gimple *stmt; |
2005 bsi = gsi_last_bb (else_bb); | 2059 bsi = gsi_last_bb (else_bb); |
2006 stmt = gimple_build_assign (restmp, | 2060 stmt = gimple_build_assign (restmp, |
2015 /* Build return value. */ | 2069 /* Build return value. */ |
2016 if (!DECL_BY_REFERENCE (resdecl)) | 2070 if (!DECL_BY_REFERENCE (resdecl)) |
2017 ret = gimple_build_return (restmp); | 2071 ret = gimple_build_return (restmp); |
2018 else | 2072 else |
2019 ret = gimple_build_return (resdecl); | 2073 ret = gimple_build_return (resdecl); |
2020 gimple_return_set_retbnd (ret, resbnd); | |
2021 | 2074 |
2022 gsi_insert_after (&bsi, ret, GSI_NEW_STMT); | 2075 gsi_insert_after (&bsi, ret, GSI_NEW_STMT); |
2023 } | 2076 } |
2024 else | 2077 else |
2025 { | 2078 { |
2026 gimple_call_set_tail (call, true); | 2079 gimple_call_set_tail (call, true); |
2027 remove_edge (single_succ_edge (bb)); | 2080 remove_edge (single_succ_edge (bb)); |
2028 } | 2081 } |
2029 | 2082 |
2030 cfun->gimple_df->in_ssa_p = true; | 2083 cfun->gimple_df->in_ssa_p = true; |
2084 update_max_bb_count (); | |
2031 profile_status_for_fn (cfun) | 2085 profile_status_for_fn (cfun) |
2032 = count.initialized_p () ? PROFILE_READ : PROFILE_GUESSED; | 2086 = cfg_count.initialized_p () && cfg_count.ipa_p () |
2087 ? PROFILE_READ : PROFILE_GUESSED; | |
2033 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */ | 2088 /* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */ |
2034 TREE_ASM_WRITTEN (thunk_fndecl) = false; | 2089 TREE_ASM_WRITTEN (thunk_fndecl) = false; |
2035 delete_unreachable_blocks (); | 2090 delete_unreachable_blocks (); |
2036 update_ssa (TODO_update_ssa); | 2091 update_ssa (TODO_update_ssa); |
2037 checking_verify_flow_info (); | 2092 checking_verify_flow_info (); |
2147 bitmap_obstack_release (NULL); | 2202 bitmap_obstack_release (NULL); |
2148 | 2203 |
2149 /* If requested, warn about function definitions where the function will | 2204 /* If requested, warn about function definitions where the function will |
2150 return a value (usually of some struct or union type) which itself will | 2205 return a value (usually of some struct or union type) which itself will |
2151 take up a lot of stack space. */ | 2206 take up a lot of stack space. */ |
2152 if (warn_larger_than && !DECL_EXTERNAL (decl) && TREE_TYPE (decl)) | 2207 if (!DECL_EXTERNAL (decl) && TREE_TYPE (decl)) |
2153 { | 2208 { |
2154 tree ret_type = TREE_TYPE (TREE_TYPE (decl)); | 2209 tree ret_type = TREE_TYPE (TREE_TYPE (decl)); |
2155 | 2210 |
2156 if (ret_type && TYPE_SIZE_UNIT (ret_type) | 2211 if (ret_type && TYPE_SIZE_UNIT (ret_type) |
2157 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST | 2212 && TREE_CODE (TYPE_SIZE_UNIT (ret_type)) == INTEGER_CST |
2158 && 0 < compare_tree_int (TYPE_SIZE_UNIT (ret_type), | 2213 && compare_tree_int (TYPE_SIZE_UNIT (ret_type), |
2159 larger_than_size)) | 2214 warn_larger_than_size) > 0) |
2160 { | 2215 { |
2161 unsigned int size_as_int | 2216 unsigned int size_as_int |
2162 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type)); | 2217 = TREE_INT_CST_LOW (TYPE_SIZE_UNIT (ret_type)); |
2163 | 2218 |
2164 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0) | 2219 if (compare_tree_int (TYPE_SIZE_UNIT (ret_type), size_as_int) == 0) |
2165 warning (OPT_Wlarger_than_, "size of return value of %q+D is %u bytes", | 2220 warning (OPT_Wlarger_than_, |
2221 "size of return value of %q+D is %u bytes", | |
2166 decl, size_as_int); | 2222 decl, size_as_int); |
2167 else | 2223 else |
2168 warning (OPT_Wlarger_than_, "size of return value of %q+D is larger than %wd bytes", | 2224 warning (OPT_Wlarger_than_, |
2169 decl, larger_than_size); | 2225 "size of return value of %q+D is larger than %wu bytes", |
2226 decl, warn_larger_than_size); | |
2170 } | 2227 } |
2171 } | 2228 } |
2172 | 2229 |
2173 gimple_set_body (decl, NULL); | 2230 gimple_set_body (decl, NULL); |
2174 if (DECL_STRUCT_FUNCTION (decl) == 0 | 2231 if (DECL_STRUCT_FUNCTION (decl) == 0 |
2450 | 2507 |
2451 /* Some targets need to handle LTO assembler output specially. */ | 2508 /* Some targets need to handle LTO assembler output specially. */ |
2452 if (flag_generate_lto || flag_generate_offload) | 2509 if (flag_generate_lto || flag_generate_offload) |
2453 targetm.asm_out.lto_start (); | 2510 targetm.asm_out.lto_start (); |
2454 | 2511 |
2455 if (!in_lto_p) | 2512 if (!in_lto_p |
2456 { | 2513 || flag_incremental_link == INCREMENTAL_LINK_LTO) |
2514 { | |
2515 if (!quiet_flag) | |
2516 fprintf (stderr, "Streaming LTO\n"); | |
2457 if (g->have_offload) | 2517 if (g->have_offload) |
2458 { | 2518 { |
2459 section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX; | 2519 section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX; |
2460 lto_stream_offload_p = true; | 2520 lto_stream_offload_p = true; |
2461 ipa_write_summaries (); | 2521 ipa_write_summaries (); |
2470 } | 2530 } |
2471 | 2531 |
2472 if (flag_generate_lto || flag_generate_offload) | 2532 if (flag_generate_lto || flag_generate_offload) |
2473 targetm.asm_out.lto_end (); | 2533 targetm.asm_out.lto_end (); |
2474 | 2534 |
2475 if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects)) | 2535 if (!flag_ltrans |
2536 && ((in_lto_p && flag_incremental_link != INCREMENTAL_LINK_LTO) | |
2537 || !flag_lto || flag_fat_lto_objects)) | |
2476 execute_ipa_pass_list (passes->all_regular_ipa_passes); | 2538 execute_ipa_pass_list (passes->all_regular_ipa_passes); |
2477 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL); | 2539 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL); |
2478 | 2540 |
2479 bitmap_obstack_release (NULL); | 2541 bitmap_obstack_release (NULL); |
2480 } | 2542 } |
2496 | 2558 |
2497 void | 2559 void |
2498 symbol_table::output_weakrefs (void) | 2560 symbol_table::output_weakrefs (void) |
2499 { | 2561 { |
2500 symtab_node *node; | 2562 symtab_node *node; |
2501 cgraph_node *cnode; | |
2502 FOR_EACH_SYMBOL (node) | 2563 FOR_EACH_SYMBOL (node) |
2503 if (node->alias | 2564 if (node->alias |
2504 && !TREE_ASM_WRITTEN (node->decl) | 2565 && !TREE_ASM_WRITTEN (node->decl) |
2505 && (!(cnode = dyn_cast <cgraph_node *> (node)) | |
2506 || !cnode->instrumented_version | |
2507 || !TREE_ASM_WRITTEN (cnode->instrumented_version->decl)) | |
2508 && node->weakref) | 2566 && node->weakref) |
2509 { | 2567 { |
2510 tree target; | 2568 tree target; |
2511 | 2569 |
2512 /* Weakrefs are special by not requiring target definition in current | 2570 /* Weakrefs are special by not requiring target definition in current |
2557 if (!seen_error ()) | 2615 if (!seen_error ()) |
2558 ipa_passes (); | 2616 ipa_passes (); |
2559 | 2617 |
2560 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */ | 2618 /* Do nothing else if any IPA pass found errors or if we are just streaming LTO. */ |
2561 if (seen_error () | 2619 if (seen_error () |
2562 || (!in_lto_p && flag_lto && !flag_fat_lto_objects)) | 2620 || ((!in_lto_p || flag_incremental_link == INCREMENTAL_LINK_LTO) |
2621 && flag_lto && !flag_fat_lto_objects)) | |
2563 { | 2622 { |
2564 timevar_pop (TV_CGRAPHOPT); | 2623 timevar_pop (TV_CGRAPHOPT); |
2565 return; | 2624 return; |
2566 } | 2625 } |
2567 | 2626 |
2577 dump_memory_report (false); | 2636 dump_memory_report (false); |
2578 } | 2637 } |
2579 timevar_pop (TV_CGRAPHOPT); | 2638 timevar_pop (TV_CGRAPHOPT); |
2580 | 2639 |
2581 /* Output everything. */ | 2640 /* Output everything. */ |
2641 switch_to_section (text_section); | |
2582 (*debug_hooks->assembly_start) (); | 2642 (*debug_hooks->assembly_start) (); |
2583 if (!quiet_flag) | 2643 if (!quiet_flag) |
2584 fprintf (stderr, "Assembling functions:\n"); | 2644 fprintf (stderr, "Assembling functions:\n"); |
2585 symtab_node::checking_verify_symtab_nodes (); | 2645 symtab_node::checking_verify_symtab_nodes (); |
2586 | 2646 |
2652 if (error_found) | 2712 if (error_found) |
2653 internal_error ("nodes with unreleased memory found"); | 2713 internal_error ("nodes with unreleased memory found"); |
2654 } | 2714 } |
2655 } | 2715 } |
2656 | 2716 |
2717 /* Earlydebug dump file, flags, and number. */ | |
2718 | |
2719 static int debuginfo_early_dump_nr; | |
2720 static FILE *debuginfo_early_dump_file; | |
2721 static dump_flags_t debuginfo_early_dump_flags; | |
2722 | |
2723 /* Debug dump file, flags, and number. */ | |
2724 | |
2725 static int debuginfo_dump_nr; | |
2726 static FILE *debuginfo_dump_file; | |
2727 static dump_flags_t debuginfo_dump_flags; | |
2728 | |
2729 /* Register the debug and earlydebug dump files. */ | |
2730 | |
2731 void | |
2732 debuginfo_early_init (void) | |
2733 { | |
2734 gcc::dump_manager *dumps = g->get_dumps (); | |
2735 debuginfo_early_dump_nr = dumps->dump_register (".earlydebug", "earlydebug", | |
2736 "earlydebug", DK_tree, | |
2737 OPTGROUP_NONE, | |
2738 false); | |
2739 debuginfo_dump_nr = dumps->dump_register (".debug", "debug", | |
2740 "debug", DK_tree, | |
2741 OPTGROUP_NONE, | |
2742 false); | |
2743 } | |
2744 | |
2745 /* Initialize the debug and earlydebug dump files. */ | |
2746 | |
2747 void | |
2748 debuginfo_init (void) | |
2749 { | |
2750 gcc::dump_manager *dumps = g->get_dumps (); | |
2751 debuginfo_dump_file = dump_begin (debuginfo_dump_nr, NULL); | |
2752 debuginfo_dump_flags = dumps->get_dump_file_info (debuginfo_dump_nr)->pflags; | |
2753 debuginfo_early_dump_file = dump_begin (debuginfo_early_dump_nr, NULL); | |
2754 debuginfo_early_dump_flags | |
2755 = dumps->get_dump_file_info (debuginfo_early_dump_nr)->pflags; | |
2756 } | |
2757 | |
2758 /* Finalize the debug and earlydebug dump files. */ | |
2759 | |
2760 void | |
2761 debuginfo_fini (void) | |
2762 { | |
2763 if (debuginfo_dump_file) | |
2764 dump_end (debuginfo_dump_nr, debuginfo_dump_file); | |
2765 if (debuginfo_early_dump_file) | |
2766 dump_end (debuginfo_early_dump_nr, debuginfo_early_dump_file); | |
2767 } | |
2768 | |
2769 /* Set dump_file to the debug dump file. */ | |
2770 | |
2771 void | |
2772 debuginfo_start (void) | |
2773 { | |
2774 set_dump_file (debuginfo_dump_file); | |
2775 } | |
2776 | |
2777 /* Undo setting dump_file to the debug dump file. */ | |
2778 | |
2779 void | |
2780 debuginfo_stop (void) | |
2781 { | |
2782 set_dump_file (NULL); | |
2783 } | |
2784 | |
2785 /* Set dump_file to the earlydebug dump file. */ | |
2786 | |
2787 void | |
2788 debuginfo_early_start (void) | |
2789 { | |
2790 set_dump_file (debuginfo_early_dump_file); | |
2791 } | |
2792 | |
2793 /* Undo setting dump_file to the earlydebug dump file. */ | |
2794 | |
2795 void | |
2796 debuginfo_early_stop (void) | |
2797 { | |
2798 set_dump_file (NULL); | |
2799 } | |
2657 | 2800 |
2658 /* Analyze the whole compilation unit once it is parsed completely. */ | 2801 /* Analyze the whole compilation unit once it is parsed completely. */ |
2659 | 2802 |
2660 void | 2803 void |
2661 symbol_table::finalize_compilation_unit (void) | 2804 symbol_table::finalize_compilation_unit (void) |
2707 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (cnode) | 2850 FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (cnode) |
2708 (*debug_hooks->early_global_decl) (cnode->decl); | 2851 (*debug_hooks->early_global_decl) (cnode->decl); |
2709 | 2852 |
2710 /* Clean up anything that needs cleaning up after initial debug | 2853 /* Clean up anything that needs cleaning up after initial debug |
2711 generation. */ | 2854 generation. */ |
2855 debuginfo_early_start (); | |
2712 (*debug_hooks->early_finish) (main_input_filename); | 2856 (*debug_hooks->early_finish) (main_input_filename); |
2857 debuginfo_early_stop (); | |
2713 } | 2858 } |
2714 | 2859 |
2715 /* Finally drive the pass manager. */ | 2860 /* Finally drive the pass manager. */ |
2716 compile (); | 2861 compile (); |
2717 | 2862 |
2757 /* Turn alias into thunk and expand it into GIMPLE representation. */ | 2902 /* Turn alias into thunk and expand it into GIMPLE representation. */ |
2758 definition = true; | 2903 definition = true; |
2759 | 2904 |
2760 memset (&thunk, 0, sizeof (cgraph_thunk_info)); | 2905 memset (&thunk, 0, sizeof (cgraph_thunk_info)); |
2761 thunk.thunk_p = true; | 2906 thunk.thunk_p = true; |
2762 create_edge (target, NULL, count, CGRAPH_FREQ_BASE); | 2907 create_edge (target, NULL, count); |
2763 callees->can_throw_external = !TREE_NOTHROW (target->decl); | 2908 callees->can_throw_external = !TREE_NOTHROW (target->decl); |
2764 | 2909 |
2765 tree arguments = DECL_ARGUMENTS (decl); | 2910 tree arguments = DECL_ARGUMENTS (decl); |
2766 | 2911 |
2767 while (arguments) | 2912 while (arguments) |