Mercurial > hg > CbC > CbC_gcc
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 } |