comparison gcc/cgraphunit.c @ 63:b7f97abdc517 gcc-4.6-20100522

update gcc from gcc-4.5.0 to gcc-4.6
author ryoma <e075725@ie.u-ryukyu.ac.jp>
date Mon, 24 May 2010 12:47:05 +0900
parents 77e2b8dfacca
children f6334be47118
comparison
equal deleted inserted replaced
56:3c8a44c06a95 63:b7f97abdc517
1 /* Callgraph based interprocedural optimizations. 1 /* Callgraph based interprocedural optimizations.
2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 2 Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 Contributed by Jan Hubicka 4 Contributed by Jan Hubicka
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
121 #include "ggc.h" 121 #include "ggc.h"
122 #include "debug.h" 122 #include "debug.h"
123 #include "target.h" 123 #include "target.h"
124 #include "cgraph.h" 124 #include "cgraph.h"
125 #include "diagnostic.h" 125 #include "diagnostic.h"
126 #include "tree-pretty-print.h"
127 #include "gimple-pretty-print.h"
126 #include "timevar.h" 128 #include "timevar.h"
127 #include "params.h" 129 #include "params.h"
128 #include "fibheap.h" 130 #include "fibheap.h"
129 #include "intl.h" 131 #include "intl.h"
130 #include "function.h" 132 #include "function.h"
380 { 382 {
381 bool output = false; 383 bool output = false;
382 tree fndecl; 384 tree fndecl;
383 struct cgraph_node *node; 385 struct cgraph_node *node;
384 386
387 varpool_analyze_pending_decls ();
385 /* Note that this queue may grow as its being processed, as the new 388 /* Note that this queue may grow as its being processed, as the new
386 functions may generate new ones. */ 389 functions may generate new ones. */
387 while (cgraph_new_nodes) 390 while (cgraph_new_nodes)
388 { 391 {
389 node = cgraph_new_nodes; 392 node = cgraph_new_nodes;
435 default: 438 default:
436 gcc_unreachable (); 439 gcc_unreachable ();
437 break; 440 break;
438 } 441 }
439 cgraph_call_function_insertion_hooks (node); 442 cgraph_call_function_insertion_hooks (node);
443 varpool_analyze_pending_decls ();
440 } 444 }
441 return output; 445 return output;
442 } 446 }
443 447
444 /* As an GCC extension we allow redefinition of the function. The 448 /* As an GCC extension we allow redefinition of the function. The
605 if (node->global.inlined_to && node->needed) 609 if (node->global.inlined_to && node->needed)
606 { 610 {
607 error ("Inline clone is needed"); 611 error ("Inline clone is needed");
608 error_found = true; 612 error_found = true;
609 } 613 }
614 for (e = node->indirect_calls; e; e = e->next_callee)
615 {
616 if (e->aux)
617 {
618 error ("aux field set for indirect edge from %s",
619 identifier_to_locale (cgraph_node_name (e->caller)));
620 error_found = true;
621 }
622 if (!e->indirect_unknown_callee
623 || !e->indirect_info)
624 {
625 error ("An indirect edge from %s is not marked as indirect or has "
626 "associated indirect_info, the corresponding statement is: ",
627 identifier_to_locale (cgraph_node_name (e->caller)));
628 debug_gimple_stmt (e->call_stmt);
629 error_found = true;
630 }
631 }
610 for (e = node->callers; e; e = e->next_caller) 632 for (e = node->callers; e; e = e->next_caller)
611 { 633 {
612 if (e->count < 0) 634 if (e->count < 0)
613 { 635 {
614 error ("caller edge count is negative"); 636 error ("caller edge count is negative");
712 if (node->prev_sibling_clone && node->prev_sibling_clone->next_sibling_clone != node) 734 if (node->prev_sibling_clone && node->prev_sibling_clone->next_sibling_clone != node)
713 { 735 {
714 error ("double linked list of clones corrupted"); 736 error ("double linked list of clones corrupted");
715 error_found = true; 737 error_found = true;
716 } 738 }
739 if (node->same_comdat_group)
740 {
741 struct cgraph_node *n = node->same_comdat_group;
742
743 if (!DECL_ONE_ONLY (node->decl))
744 {
745 error ("non-DECL_ONE_ONLY node in a same_comdat_group list");
746 error_found = true;
747 }
748 if (n == node)
749 {
750 error ("node is alone in a comdat group");
751 error_found = true;
752 }
753 do
754 {
755 if (!n->same_comdat_group)
756 {
757 error ("same_comdat_group is not a circular list");
758 error_found = true;
759 break;
760 }
761 n = n->same_comdat_group;
762 }
763 while (n != node);
764 }
717 765
718 if (node->analyzed && gimple_has_body_p (node->decl) 766 if (node->analyzed && gimple_has_body_p (node->decl)
719 && !TREE_ASM_WRITTEN (node->decl) 767 && !TREE_ASM_WRITTEN (node->decl)
720 && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to) 768 && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to)
721 && !flag_wpa) 769 && !flag_wpa)
731 for (gsi = gsi_start_bb (this_block); 779 for (gsi = gsi_start_bb (this_block);
732 !gsi_end_p (gsi); 780 !gsi_end_p (gsi);
733 gsi_next (&gsi)) 781 gsi_next (&gsi))
734 { 782 {
735 gimple stmt = gsi_stmt (gsi); 783 gimple stmt = gsi_stmt (gsi);
736 tree decl; 784 if (is_gimple_call (stmt))
737 if (is_gimple_call (stmt) && (decl = gimple_call_fndecl (stmt)))
738 { 785 {
739 struct cgraph_edge *e = cgraph_edge (node, stmt); 786 struct cgraph_edge *e = cgraph_edge (node, stmt);
787 tree decl = gimple_call_fndecl (stmt);
740 if (e) 788 if (e)
741 { 789 {
742 if (e->aux) 790 if (e->aux)
743 { 791 {
744 error ("shared call_stmt:"); 792 error ("shared call_stmt:");
745 debug_gimple_stmt (stmt); 793 debug_gimple_stmt (stmt);
746 error_found = true; 794 error_found = true;
747 } 795 }
748 if (e->callee->same_body_alias) 796 if (!e->indirect_unknown_callee)
749 { 797 {
750 error ("edge points to same body alias:"); 798 if (e->callee->same_body_alias)
751 debug_tree (e->callee->decl); 799 {
800 error ("edge points to same body alias:");
801 debug_tree (e->callee->decl);
802 error_found = true;
803 }
804 else if (!node->global.inlined_to
805 && !e->callee->global.inlined_to
806 && decl
807 && !clone_of_p (cgraph_node (decl),
808 e->callee))
809 {
810 error ("edge points to wrong declaration:");
811 debug_tree (e->callee->decl);
812 fprintf (stderr," Instead of:");
813 debug_tree (decl);
814 error_found = true;
815 }
816 }
817 else if (decl)
818 {
819 error ("an indirect edge with unknown callee "
820 "corresponding to a call_stmt with "
821 "a known declaration:");
752 error_found = true; 822 error_found = true;
753 } 823 debug_gimple_stmt (e->call_stmt);
754 else if (!clone_of_p (cgraph_node (decl), e->callee)
755 && !e->callee->global.inlined_to)
756 {
757 error ("edge points to wrong declaration:");
758 debug_tree (e->callee->decl);
759 fprintf (stderr," Instead of:");
760 debug_tree (decl);
761 error_found = true;
762 } 824 }
763 e->aux = (void *)1; 825 e->aux = (void *)1;
764 } 826 }
765 else 827 else if (decl)
766 { 828 {
767 error ("missing callgraph edge for call stmt:"); 829 error ("missing callgraph edge for call stmt:");
768 debug_gimple_stmt (stmt); 830 debug_gimple_stmt (stmt);
769 error_found = true; 831 error_found = true;
770 } 832 }
776 /* No CFG available?! */ 838 /* No CFG available?! */
777 gcc_unreachable (); 839 gcc_unreachable ();
778 840
779 for (e = node->callees; e; e = e->next_callee) 841 for (e = node->callees; e; e = e->next_callee)
780 { 842 {
781 if (!e->aux && !e->indirect_call) 843 if (!e->aux)
782 { 844 {
783 error ("edge %s->%s has no corresponding call_stmt", 845 error ("edge %s->%s has no corresponding call_stmt",
784 identifier_to_locale (cgraph_node_name (e->caller)), 846 identifier_to_locale (cgraph_node_name (e->caller)),
785 identifier_to_locale (cgraph_node_name (e->callee))); 847 identifier_to_locale (cgraph_node_name (e->callee)));
786 debug_gimple_stmt (e->call_stmt); 848 debug_gimple_stmt (e->call_stmt);
787 error_found = true; 849 error_found = true;
788 } 850 }
789 e->aux = 0; 851 e->aux = 0;
790 } 852 }
853 for (e = node->indirect_calls; e; e = e->next_callee)
854 {
855 if (!e->aux)
856 {
857 error ("an indirect edge from %s has no corresponding call_stmt",
858 identifier_to_locale (cgraph_node_name (e->caller)));
859 debug_gimple_stmt (e->call_stmt);
860 error_found = true;
861 }
862 e->aux = 0;
863 }
791 } 864 }
792 if (error_found) 865 if (error_found)
793 { 866 {
794 dump_cgraph_node (stderr, node); 867 dump_cgraph_node (stderr, node);
795 internal_error ("verify_cgraph_node failed"); 868 internal_error ("verify_cgraph_node failed");
833 tree save = current_function_decl; 906 tree save = current_function_decl;
834 tree decl = node->decl; 907 tree decl = node->decl;
835 908
836 current_function_decl = decl; 909 current_function_decl = decl;
837 push_cfun (DECL_STRUCT_FUNCTION (decl)); 910 push_cfun (DECL_STRUCT_FUNCTION (decl));
911
912 assign_assembler_name_if_neeeded (node->decl);
838 913
839 /* Make sure to gimplify bodies only once. During analyzing a 914 /* Make sure to gimplify bodies only once. During analyzing a
840 function we lower it, which will require gimplified nested 915 function we lower it, which will require gimplified nested
841 functions, so we can end up here with an already gimplified 916 functions, so we can end up here with an already gimplified
842 body. */ 917 body. */
883 struct varpool_node *vnode; 958 struct varpool_node *vnode;
884 959
885 for (node = cgraph_nodes; node != first; node = node->next) 960 for (node = cgraph_nodes; node != first; node = node->next)
886 { 961 {
887 tree decl = node->decl; 962 tree decl = node->decl;
888 if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) 963 if (DECL_PRESERVE_P (decl))
889 { 964 cgraph_mark_needed_node (node);
890 mark_decl_referenced (decl);
891 if (node->local.finalized)
892 cgraph_mark_needed_node (node);
893 }
894 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) 965 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
895 { 966 {
896 if (! TREE_PUBLIC (node->decl)) 967 if (! TREE_PUBLIC (node->decl))
897 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes, 968 warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
898 "%<externally_visible%>" 969 "%<externally_visible%>"
902 } 973 }
903 } 974 }
904 for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next) 975 for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next)
905 { 976 {
906 tree decl = vnode->decl; 977 tree decl = vnode->decl;
907 if (lookup_attribute ("used", DECL_ATTRIBUTES (decl))) 978 if (DECL_PRESERVE_P (decl))
908 { 979 {
909 mark_decl_referenced (decl);
910 vnode->force_output = true; 980 vnode->force_output = true;
911 if (vnode->finalized) 981 if (vnode->finalized)
912 varpool_mark_needed_node (vnode); 982 varpool_mark_needed_node (vnode);
913 } 983 }
914 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl))) 984 if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
1125 /* We need to output all local functions that are used and not 1195 /* We need to output all local functions that are used and not
1126 always inlined, as well as those that are reachable from 1196 always inlined, as well as those that are reachable from
1127 outside the current compilation unit. */ 1197 outside the current compilation unit. */
1128 if (node->analyzed 1198 if (node->analyzed
1129 && !node->global.inlined_to 1199 && !node->global.inlined_to
1130 && (node->needed 1200 && (node->needed || node->reachable_from_other_partition
1201 || node->address_taken
1131 || (e && node->reachable)) 1202 || (e && node->reachable))
1132 && !TREE_ASM_WRITTEN (decl) 1203 && !TREE_ASM_WRITTEN (decl)
1133 && !DECL_EXTERNAL (decl)) 1204 && !DECL_EXTERNAL (decl))
1134 { 1205 {
1135 node->process = 1; 1206 node->process = 1;
1152 { 1223 {
1153 /* We should've reclaimed all functions that are not needed. */ 1224 /* We should've reclaimed all functions that are not needed. */
1154 #ifdef ENABLE_CHECKING 1225 #ifdef ENABLE_CHECKING
1155 if (!node->global.inlined_to 1226 if (!node->global.inlined_to
1156 && gimple_has_body_p (decl) 1227 && gimple_has_body_p (decl)
1228 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1229 are inside partition, we can end up not removing the body since we no longer
1230 have analyzed node pointing to it. */
1231 && !node->in_other_partition
1157 && !DECL_EXTERNAL (decl)) 1232 && !DECL_EXTERNAL (decl))
1158 { 1233 {
1159 dump_cgraph_node (stderr, node); 1234 dump_cgraph_node (stderr, node);
1160 internal_error ("failed to reclaim unneeded function"); 1235 internal_error ("failed to reclaim unneeded function");
1161 } 1236 }
1162 #endif 1237 #endif
1163 gcc_assert (node->global.inlined_to 1238 gcc_assert (node->global.inlined_to
1164 || !gimple_has_body_p (decl) 1239 || !gimple_has_body_p (decl)
1240 || node->in_other_partition
1165 || DECL_EXTERNAL (decl)); 1241 || DECL_EXTERNAL (decl));
1166 1242
1167 } 1243 }
1168 1244
1169 } 1245 }
1173 if (node->same_comdat_group && !node->process) 1249 if (node->same_comdat_group && !node->process)
1174 { 1250 {
1175 tree decl = node->decl; 1251 tree decl = node->decl;
1176 if (!node->global.inlined_to 1252 if (!node->global.inlined_to
1177 && gimple_has_body_p (decl) 1253 && gimple_has_body_p (decl)
1254 /* FIXME: in ltrans unit when offline copy is outside partition but inline copies
1255 are inside partition, we can end up not removing the body since we no longer
1256 have analyzed node pointing to it. */
1257 && !node->in_other_partition
1178 && !DECL_EXTERNAL (decl)) 1258 && !DECL_EXTERNAL (decl))
1179 { 1259 {
1180 dump_cgraph_node (stderr, node); 1260 dump_cgraph_node (stderr, node);
1181 internal_error ("failed to reclaim unneeded function"); 1261 internal_error ("failed to reclaim unneeded function");
1182 } 1262 }
1228 HOST_WIDE_INT fixed_offset, tree virtual_offset) 1308 HOST_WIDE_INT fixed_offset, tree virtual_offset)
1229 { 1309 {
1230 gimple stmt; 1310 gimple stmt;
1231 tree ret; 1311 tree ret;
1232 1312
1233 if (this_adjusting) 1313 if (this_adjusting
1314 && fixed_offset != 0)
1234 { 1315 {
1235 stmt = gimple_build_assign (ptr, 1316 stmt = gimple_build_assign (ptr,
1236 fold_build2_loc (input_location, 1317 fold_build2_loc (input_location,
1237 POINTER_PLUS_EXPR, 1318 POINTER_PLUS_EXPR,
1238 TREE_TYPE (ptr), ptr, 1319 TREE_TYPE (ptr), ptr,
1313 ptr = fold_build2_loc (input_location, 1394 ptr = fold_build2_loc (input_location,
1314 POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr, 1395 POINTER_PLUS_EXPR, TREE_TYPE (ptr), ptr,
1315 offsettmp); 1396 offsettmp);
1316 } 1397 }
1317 1398
1318 if (!this_adjusting) 1399 if (!this_adjusting
1400 && fixed_offset != 0)
1319 /* Adjust the pointer by the constant. */ 1401 /* Adjust the pointer by the constant. */
1320 { 1402 {
1321 tree ptrtmp; 1403 tree ptrtmp;
1322 1404
1323 if (TREE_CODE (ptr) == VAR_DECL) 1405 if (TREE_CODE (ptr) == VAR_DECL)
1463 find_referenced_vars_in (call); 1545 find_referenced_vars_in (call);
1464 update_stmt (call); 1546 update_stmt (call);
1465 1547
1466 if (restmp && !this_adjusting) 1548 if (restmp && !this_adjusting)
1467 { 1549 {
1468 tree true_label = NULL_TREE, false_label = NULL_TREE; 1550 tree true_label = NULL_TREE;
1469 1551
1470 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE) 1552 if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
1471 { 1553 {
1472 gimple stmt; 1554 gimple stmt;
1473 /* If the return type is a pointer, we need to 1555 /* If the return type is a pointer, we need to
1477 then_bb = create_basic_block (NULL, (void *) 0, bb); 1559 then_bb = create_basic_block (NULL, (void *) 0, bb);
1478 return_bb = create_basic_block (NULL, (void *) 0, then_bb); 1560 return_bb = create_basic_block (NULL, (void *) 0, then_bb);
1479 else_bb = create_basic_block (NULL, (void *) 0, else_bb); 1561 else_bb = create_basic_block (NULL, (void *) 0, else_bb);
1480 remove_edge (single_succ_edge (bb)); 1562 remove_edge (single_succ_edge (bb));
1481 true_label = gimple_block_label (then_bb); 1563 true_label = gimple_block_label (then_bb);
1482 false_label = gimple_block_label (else_bb);
1483 stmt = gimple_build_cond (NE_EXPR, restmp, 1564 stmt = gimple_build_cond (NE_EXPR, restmp,
1484 fold_convert (TREE_TYPE (restmp), 1565 fold_convert (TREE_TYPE (restmp),
1485 integer_zero_node), 1566 integer_zero_node),
1486 NULL_TREE, NULL_TREE); 1567 NULL_TREE, NULL_TREE);
1487 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT); 1568 gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
1516 update_ssa (TODO_update_ssa); 1597 update_ssa (TODO_update_ssa);
1517 1598
1518 cgraph_remove_same_body_alias (node); 1599 cgraph_remove_same_body_alias (node);
1519 /* Since we want to emit the thunk, we explicitly mark its name as 1600 /* Since we want to emit the thunk, we explicitly mark its name as
1520 referenced. */ 1601 referenced. */
1521 mark_decl_referenced (thunk_fndecl);
1522 cgraph_add_new_function (thunk_fndecl, true); 1602 cgraph_add_new_function (thunk_fndecl, true);
1523 bitmap_obstack_release (NULL); 1603 bitmap_obstack_release (NULL);
1524 } 1604 }
1525 current_function_decl = NULL; 1605 current_function_decl = NULL;
1526 } 1606 }
1658 1738
1659 static void 1739 static void
1660 cgraph_output_in_order (void) 1740 cgraph_output_in_order (void)
1661 { 1741 {
1662 int max; 1742 int max;
1663 size_t size;
1664 struct cgraph_order_sort *nodes; 1743 struct cgraph_order_sort *nodes;
1665 int i; 1744 int i;
1666 struct cgraph_node *pf; 1745 struct cgraph_node *pf;
1667 struct varpool_node *pv; 1746 struct varpool_node *pv;
1668 struct cgraph_asm_node *pa; 1747 struct cgraph_asm_node *pa;
1669 1748
1670 max = cgraph_order; 1749 max = cgraph_order;
1671 size = max * sizeof (struct cgraph_order_sort); 1750 nodes = XCNEWVEC (struct cgraph_order_sort, max);
1672 nodes = (struct cgraph_order_sort *) alloca (size);
1673 memset (nodes, 0, size);
1674 1751
1675 varpool_analyze_pending_decls (); 1752 varpool_analyze_pending_decls ();
1676 1753
1677 for (pf = cgraph_nodes; pf; pf = pf->next) 1754 for (pf = cgraph_nodes; pf; pf = pf->next)
1678 { 1755 {
1735 gcc_unreachable (); 1812 gcc_unreachable ();
1736 } 1813 }
1737 } 1814 }
1738 1815
1739 cgraph_asm_nodes = NULL; 1816 cgraph_asm_nodes = NULL;
1817 free (nodes);
1740 } 1818 }
1741 1819
1742 /* Return true when function body of DECL still needs to be kept around 1820 /* Return true when function body of DECL still needs to be kept around
1743 for later re-use. */ 1821 for later re-use. */
1744 bool 1822 bool
1783 cgraph_process_new_functions (); 1861 cgraph_process_new_functions ();
1784 1862
1785 execute_ipa_summary_passes 1863 execute_ipa_summary_passes
1786 ((struct ipa_opt_pass_d *) all_regular_ipa_passes); 1864 ((struct ipa_opt_pass_d *) all_regular_ipa_passes);
1787 } 1865 }
1866
1867 /* Some targets need to handle LTO assembler output specially. */
1868 if (flag_generate_lto)
1869 targetm.asm_out.lto_start ();
1870
1788 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes); 1871 execute_ipa_summary_passes ((struct ipa_opt_pass_d *) all_lto_gen_passes);
1789 1872
1790 if (!in_lto_p) 1873 if (!in_lto_p)
1791 ipa_write_summaries (); 1874 ipa_write_summaries ();
1875
1876 if (flag_generate_lto)
1877 targetm.asm_out.lto_end ();
1792 1878
1793 if (!flag_ltrans) 1879 if (!flag_ltrans)
1794 execute_ipa_pass_list (all_regular_ipa_passes); 1880 execute_ipa_pass_list (all_regular_ipa_passes);
1795 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL); 1881 invoke_plugin_callbacks (PLUGIN_ALL_IPA_PASSES_END, NULL);
1796 1882
1940 TREE_STATIC (decl) = 1; 2026 TREE_STATIC (decl) = 1;
1941 TREE_USED (decl) = 1; 2027 TREE_USED (decl) = 1;
1942 DECL_ARTIFICIAL (decl) = 1; 2028 DECL_ARTIFICIAL (decl) = 1;
1943 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1; 2029 DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (decl) = 1;
1944 DECL_SAVED_TREE (decl) = body; 2030 DECL_SAVED_TREE (decl) = body;
1945 TREE_PUBLIC (decl) = ! targetm.have_ctors_dtors; 2031 if (!targetm.have_ctors_dtors)
2032 {
2033 TREE_PUBLIC (decl) = 1;
2034 DECL_PRESERVE_P (decl) = 1;
2035 }
1946 DECL_UNINLINABLE (decl) = 1; 2036 DECL_UNINLINABLE (decl) = 1;
1947 2037
1948 DECL_INITIAL (decl) = make_node (BLOCK); 2038 DECL_INITIAL (decl) = make_node (BLOCK);
1949 TREE_USED (DECL_INITIAL (decl)) = 1; 2039 TREE_USED (DECL_INITIAL (decl)) = 1;
1950 2040
2010 cgraph_copy_node_for_versioning (struct cgraph_node *old_version, 2100 cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
2011 tree new_decl, 2101 tree new_decl,
2012 VEC(cgraph_edge_p,heap) *redirect_callers) 2102 VEC(cgraph_edge_p,heap) *redirect_callers)
2013 { 2103 {
2014 struct cgraph_node *new_version; 2104 struct cgraph_node *new_version;
2015 struct cgraph_edge *e, *new_e; 2105 struct cgraph_edge *e;
2016 struct cgraph_edge *next_callee; 2106 struct cgraph_edge *next_callee;
2017 unsigned i; 2107 unsigned i;
2018 2108
2019 gcc_assert (old_version); 2109 gcc_assert (old_version);
2020 2110
2029 2119
2030 /* Clone the old node callees. Recursive calls are 2120 /* Clone the old node callees. Recursive calls are
2031 also cloned. */ 2121 also cloned. */
2032 for (e = old_version->callees;e; e=e->next_callee) 2122 for (e = old_version->callees;e; e=e->next_callee)
2033 { 2123 {
2034 new_e = cgraph_clone_edge (e, new_version, e->call_stmt, 2124 cgraph_clone_edge (e, new_version, e->call_stmt,
2035 e->lto_stmt_uid, 0, e->frequency, 2125 e->lto_stmt_uid, REG_BR_PROB_BASE,
2036 e->loop_nest, true); 2126 CGRAPH_FREQ_BASE,
2037 new_e->count = e->count; 2127 e->loop_nest, true);
2038 } 2128 }
2039 /* Fix recursive calls. 2129 /* Fix recursive calls.
2040 If OLD_VERSION has a recursive call after the 2130 If OLD_VERSION has a recursive call after the
2041 previous edge cloning, the new version will have an edge 2131 previous edge cloning, the new version will have an edge
2042 pointing to the old version, which is wrong; 2132 pointing to the old version, which is wrong;
2107 /* Update the new version's properties. 2197 /* Update the new version's properties.
2108 Make The new version visible only within this translation unit. Make sure 2198 Make The new version visible only within this translation unit. Make sure
2109 that is not weak also. 2199 that is not weak also.
2110 ??? We cannot use COMDAT linkage because there is no 2200 ??? We cannot use COMDAT linkage because there is no
2111 ABI support for this. */ 2201 ABI support for this. */
2112 DECL_EXTERNAL (new_version_node->decl) = 0; 2202 cgraph_make_decl_local (new_version_node->decl);
2113 DECL_COMDAT_GROUP (new_version_node->decl) = NULL_TREE;
2114 TREE_PUBLIC (new_version_node->decl) = 0;
2115 DECL_COMDAT (new_version_node->decl) = 0;
2116 DECL_WEAK (new_version_node->decl) = 0;
2117 DECL_VIRTUAL_P (new_version_node->decl) = 0; 2203 DECL_VIRTUAL_P (new_version_node->decl) = 0;
2118 new_version_node->local.externally_visible = 0; 2204 new_version_node->local.externally_visible = 0;
2119 new_version_node->local.local = 1; 2205 new_version_node->local.local = 1;
2120 new_version_node->lowered = true; 2206 new_version_node->lowered = true;
2121 2207
2221 cgraph_remove_node (node->clone_of); 2307 cgraph_remove_node (node->clone_of);
2222 node->clone_of = NULL; 2308 node->clone_of = NULL;
2223 bitmap_obstack_release (NULL); 2309 bitmap_obstack_release (NULL);
2224 } 2310 }
2225 2311
2312 /* If necessary, change the function declaration in the call statement
2313 associated with E so that it corresponds to the edge callee. */
2314
2315 gimple
2316 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
2317 {
2318 tree decl = gimple_call_fndecl (e->call_stmt);
2319 gimple new_stmt;
2320 gimple_stmt_iterator gsi;
2321
2322 if (!decl || decl == e->callee->decl
2323 /* Don't update call from same body alias to the real function. */
2324 || cgraph_get_node (decl) == cgraph_get_node (e->callee->decl))
2325 return e->call_stmt;
2326
2327 if (cgraph_dump_file)
2328 {
2329 fprintf (cgraph_dump_file, "updating call of %s/%i -> %s/%i: ",
2330 cgraph_node_name (e->caller), e->caller->uid,
2331 cgraph_node_name (e->callee), e->callee->uid);
2332 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2333 }
2334
2335 if (e->callee->clone.combined_args_to_skip)
2336 new_stmt = gimple_call_copy_skip_args (e->call_stmt,
2337 e->callee->clone.combined_args_to_skip);
2338 else
2339 new_stmt = e->call_stmt;
2340 if (gimple_vdef (new_stmt)
2341 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2342 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2343 gimple_call_set_fndecl (new_stmt, e->callee->decl);
2344
2345 gsi = gsi_for_stmt (e->call_stmt);
2346 gsi_replace (&gsi, new_stmt, true);
2347 update_stmt (new_stmt);
2348
2349 /* Update EH information too, just in case. */
2350 maybe_clean_or_replace_eh_stmt (e->call_stmt, new_stmt);
2351
2352 cgraph_set_call_stmt_including_clones (e->caller, e->call_stmt, new_stmt);
2353
2354 if (cgraph_dump_file)
2355 {
2356 fprintf (cgraph_dump_file, " updated to:");
2357 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2358 }
2359 return new_stmt;
2360 }
2361
2226 /* Once all functions from compilation unit are in memory, produce all clones 2362 /* Once all functions from compilation unit are in memory, produce all clones
2227 and update all calls. 2363 and update all calls. We might also do this on demand if we don't want to
2228 We might also do this on demand if we don't want to bring all functions to 2364 bring all functions to memory prior compilation, but current WHOPR
2229 memory prior compilation, but current WHOPR implementation does that and it is 2365 implementation does that and it is is bit easier to keep everything right in
2230 is bit easier to keep everything right in this order. */ 2366 this order. */
2231 void 2367 void
2232 cgraph_materialize_all_clones (void) 2368 cgraph_materialize_all_clones (void)
2233 { 2369 {
2234 struct cgraph_node *node; 2370 struct cgraph_node *node;
2235 bool stabilized = false; 2371 bool stabilized = false;
2289 fprintf (cgraph_dump_file, " combined_args_to_skip:"); 2425 fprintf (cgraph_dump_file, " combined_args_to_skip:");
2290 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip); 2426 dump_bitmap (cgraph_dump_file, node->clone.combined_args_to_skip);
2291 } 2427 }
2292 } 2428 }
2293 cgraph_materialize_clone (node); 2429 cgraph_materialize_clone (node);
2430 stabilized = false;
2294 } 2431 }
2295 else
2296 stabilized = false;
2297 } 2432 }
2298 } 2433 }
2299 } 2434 }
2300 for (node = cgraph_nodes; node; node = node->next) 2435 for (node = cgraph_nodes; node; node = node->next)
2301 if (!node->analyzed && node->callees) 2436 if (!node->analyzed && node->callees)
2302 cgraph_node_remove_callees (node); 2437 cgraph_node_remove_callees (node);
2303 if (cgraph_dump_file) 2438 if (cgraph_dump_file)
2304 fprintf (cgraph_dump_file, "Updating call sites\n"); 2439 fprintf (cgraph_dump_file, "Updating call sites\n");
2305 for (node = cgraph_nodes; node; node = node->next) 2440 for (node = cgraph_nodes; node; node = node->next)
2306 if (node->analyzed && gimple_has_body_p (node->decl) 2441 if (node->analyzed && !node->clone_of
2307 && (!node->clone_of || node->clone_of->decl != node->decl)) 2442 && gimple_has_body_p (node->decl))
2308 { 2443 {
2309 struct cgraph_edge *e; 2444 struct cgraph_edge *e;
2310 2445
2311 current_function_decl = node->decl; 2446 current_function_decl = node->decl;
2312 push_cfun (DECL_STRUCT_FUNCTION (node->decl)); 2447 push_cfun (DECL_STRUCT_FUNCTION (node->decl));
2313 for (e = node->callees; e; e = e->next_callee) 2448 for (e = node->callees; e; e = e->next_callee)
2314 { 2449 cgraph_redirect_edge_call_stmt_to_callee (e);
2315 tree decl = gimple_call_fndecl (e->call_stmt); 2450 gcc_assert (!need_ssa_update_p (cfun));
2316 /* When function gets inlined, indirect inlining might've invented
2317 new edge for orginally indirect stmt. Since we are not
2318 preserving clones in the original form, we must not update here
2319 since other inline clones don't need to contain call to the same
2320 call. Inliner will do the substitution for us later. */
2321 if (decl && decl != e->callee->decl)
2322 {
2323 gimple new_stmt;
2324 gimple_stmt_iterator gsi;
2325
2326 if (e->callee->same_body)
2327 {
2328 struct cgraph_node *alias;
2329
2330 for (alias = e->callee->same_body;
2331 alias;
2332 alias = alias->next)
2333 if (decl == alias->decl)
2334 break;
2335 /* Don't update call from same body alias to the real
2336 function. */
2337 if (alias)
2338 continue;
2339 }
2340
2341 if (cgraph_dump_file)
2342 {
2343 fprintf (cgraph_dump_file, "updating call of %s in %s:",
2344 cgraph_node_name (node),
2345 cgraph_node_name (e->callee));
2346 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2347 }
2348
2349 if (e->callee->clone.combined_args_to_skip)
2350 new_stmt = gimple_call_copy_skip_args (e->call_stmt,
2351 e->callee->clone.combined_args_to_skip);
2352 else
2353 new_stmt = e->call_stmt;
2354 if (gimple_vdef (new_stmt)
2355 && TREE_CODE (gimple_vdef (new_stmt)) == SSA_NAME)
2356 SSA_NAME_DEF_STMT (gimple_vdef (new_stmt)) = new_stmt;
2357 gimple_call_set_fndecl (new_stmt, e->callee->decl);
2358
2359 gsi = gsi_for_stmt (e->call_stmt);
2360 gsi_replace (&gsi, new_stmt, true);
2361
2362 /* Update EH information too, just in case. */
2363 maybe_clean_or_replace_eh_stmt (e->call_stmt, new_stmt);
2364
2365 cgraph_set_call_stmt_including_clones (node, e->call_stmt, new_stmt);
2366
2367 if (cgraph_dump_file)
2368 {
2369 fprintf (cgraph_dump_file, " updated to:");
2370 print_gimple_stmt (cgraph_dump_file, e->call_stmt, 0, dump_flags);
2371 }
2372 }
2373 }
2374 pop_cfun (); 2451 pop_cfun ();
2375 current_function_decl = NULL; 2452 current_function_decl = NULL;
2376 #ifdef ENABLE_CHECKING 2453 #ifdef ENABLE_CHECKING
2377 verify_cgraph_node (node); 2454 verify_cgraph_node (node);
2378 #endif 2455 #endif
2379 } 2456 }
2457 if (cgraph_dump_file)
2458 fprintf (cgraph_dump_file, "Materialization Call site updates done.\n");
2459 /* All changes to parameters have been performed. In order not to
2460 incorrectly repeat them, we simply dispose of the bitmaps that drive the
2461 changes. */
2462 for (node = cgraph_nodes; node; node = node->next)
2463 node->clone.combined_args_to_skip = NULL;
2380 #ifdef ENABLE_CHECKING 2464 #ifdef ENABLE_CHECKING
2381 verify_cgraph (); 2465 verify_cgraph ();
2382 #endif 2466 #endif
2383 cgraph_remove_unreachable_nodes (false, cgraph_dump_file); 2467 cgraph_remove_unreachable_nodes (false, cgraph_dump_file);
2384 } 2468 }