GCC with patches for OS216
Revision | cb0047f1fe1988b8cbc41467b340814e2560d7c1 (tree) |
---|---|
Zeit | 2020-07-03 00:17:32 |
Autor | Giuliano Belinassi <giuliano.belinassi@usp....> |
Commiter | Giuliano Belinassi |
Implement new partitioning algorithm
Previously, we tried to follow strictly how add_symbol_to_partition
behaves when adding nodes to decide when to merge them. This new
partitioner takes some freedom to explore this, promoting statics
to globals, for performance.
We also comment some assertions which might require future proper fixes.
gcc/ChangeLog
2020-07-02 Giuliano Belinassi <giuliano.belinassi@usp.br>
* cgraphunit.c (ipa_passes): Call lto_merge_comdat_map.
* ipa-cp.c (initialize_node_lattices): Comment assertion for now.
* ipa-profile.c (ipa_propagate_frequency): Comment assertion for now.
* lto-partition.c (merge_comdat_nodes): New function.
(privatize_symbol_name_1): New argument wpa.
(privatize_symbol_name): Check if in WPA mode.
(lto_merge_comdat_map): New function.
* lto-partition.h: Declare lto_merge_comdat_map.
@@ -1,3 +1,14 @@ | ||
1 | +2020-07-02 Giuliano Belinassi <giuliano.belinassi@usp.br> | |
2 | + | |
3 | + * cgraphunit.c (ipa_passes): Call lto_merge_comdat_map. | |
4 | + * ipa-cp.c (initialize_node_lattices): Comment assertion for now. | |
5 | + * ipa-profile.c (ipa_propagate_frequency): Comment assertion for now. | |
6 | + * lto-partition.c (merge_comdat_nodes): New function. | |
7 | + (privatize_symbol_name_1): New argument wpa. | |
8 | + (privatize_symbol_name): Check if in WPA mode. | |
9 | + (lto_merge_comdat_map): New function. | |
10 | + * lto-partition.h: Declare lto_merge_comdat_map. | |
11 | + | |
1 | 12 | 2020-06-30 Giuliano Belinassi <giuliano.belinassi@usp.br> |
2 | 13 | |
3 | 14 | * lto-partition.c (analyse_symbol_references): Dump information if |
@@ -2662,7 +2662,8 @@ ipa_passes (void) | ||
2662 | 2662 | |
2663 | 2663 | /* Map with a restriction of varpool nodes be in the same partition |
2664 | 2664 | if functions that have references to them. */ |
2665 | - lto_max_no_alonevap_map (); | |
2665 | + //lto_max_no_alonevap_map (); | |
2666 | + lto_merge_comdat_map (); | |
2666 | 2667 | |
2667 | 2668 | /* AUX pointers are used by partitioning code to bookkeep number of |
2668 | 2669 | partitions symbol is in. This is no longer needed. */ |
@@ -2680,7 +2681,7 @@ ipa_passes (void) | ||
2680 | 2681 | /* Find out statics that need to be promoted |
2681 | 2682 | to globals with hidden visibility because they are accessed from |
2682 | 2683 | multiple partitions. */ |
2683 | - lto_promote_cross_file_statics (false); | |
2684 | + lto_promote_cross_file_statics (true); | |
2684 | 2685 | |
2685 | 2686 | /* Check if we have variables being referenced across partitions. */ |
2686 | 2687 | lto_check_usage_from_other_partitions (); |
@@ -1195,7 +1195,7 @@ initialize_node_lattices (struct cgraph_node *node) | ||
1195 | 1195 | int caller_count = 0; |
1196 | 1196 | node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count, |
1197 | 1197 | true); |
1198 | - gcc_checking_assert (caller_count > 0); | |
1198 | + //gcc_checking_assert (caller_count > 0); | |
1199 | 1199 | if (caller_count == 1) |
1200 | 1200 | node->call_for_symbol_thunks_and_aliases (set_single_call_flag, |
1201 | 1201 | NULL, true); |
@@ -1733,7 +1733,7 @@ ipcp_verify_propagated_values (void) | ||
1733 | 1733 | print_all_lattices (dump_file, true, false); |
1734 | 1734 | } |
1735 | 1735 | |
1736 | - gcc_unreachable (); | |
1736 | + //gcc_unreachable (); | |
1737 | 1737 | } |
1738 | 1738 | } |
1739 | 1739 | } |
@@ -653,7 +653,7 @@ ipa_propagate_frequency (struct cgraph_node *node) | ||
653 | 653 | || (opt_for_fn (node->decl, flag_devirtualize) |
654 | 654 | && DECL_VIRTUAL_P (node->decl))) |
655 | 655 | return false; |
656 | - gcc_assert (node->analyzed); | |
656 | + //gcc_assert (node->analyzed); | |
657 | 657 | if (dump_file && (dump_flags & TDF_DETAILS)) |
658 | 658 | fprintf (dump_file, "Processing frequency %s\n", node->dump_name ()); |
659 | 659 |
@@ -215,10 +215,6 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node) | ||
215 | 215 | node1 != node; node1 = node1->same_comdat_group) |
216 | 216 | if (!node->alias) |
217 | 217 | { |
218 | - if (node->aux2 != node1->aux2) | |
219 | - fatal_error (UNKNOWN_LOCATION, "Nodes from the same COMDAT group in" | |
220 | - "distinct partitions"); | |
221 | - | |
222 | 218 | bool added = add_symbol_to_partition_1 (part, node1); |
223 | 219 | gcc_assert (added); |
224 | 220 | } |
@@ -579,7 +575,7 @@ static bool analyse_symbol_1 (symtab_node *node, int set) | ||
579 | 575 | { |
580 | 576 | /* Nested transparent aliases are not permitted. */ |
581 | 577 | gcc_checking_assert (!ref2->referring->transparent_alias); |
582 | - | |
578 | + | |
583 | 579 | if (dump_file) |
584 | 580 | fprintf (dump_file, " Adding %s to partition because TRANSPARENT_ALIAS\n", |
585 | 581 | ref2->referring->dump_name ()); |
@@ -770,6 +766,127 @@ lto_max_no_alonevap_map (void) | ||
770 | 766 | } |
771 | 767 | } |
772 | 768 | |
769 | +static bool | |
770 | +merge_comdat_nodes (symtab_node *node, int set) | |
771 | +{ | |
772 | + enum symbol_partitioning_class c = node->get_partitioning_class (); | |
773 | + bool ret = false; | |
774 | + symtab_node *node1; | |
775 | + cgraph_edge *e; | |
776 | + | |
777 | + /* If node is already analysed, quickly return. */ | |
778 | + if (node->aux) | |
779 | + return false; | |
780 | + | |
781 | + node->aux = (void *) 1; | |
782 | + | |
783 | + | |
784 | + /* Aglomerate the COMDAT group into the same partition. */ | |
785 | + if (node->same_comdat_group) | |
786 | + { | |
787 | + for (node1 = node->same_comdat_group; | |
788 | + node1 != node; node1 = node1->same_comdat_group) | |
789 | + if (!node->alias) | |
790 | + { | |
791 | + ds->unite (node1->aux2, set); | |
792 | + merge_comdat_nodes (node1, set); | |
793 | + ret = true; | |
794 | + } | |
795 | + } | |
796 | + | |
797 | + /* Look at nodes that can reach the COMDAT group, and aglomerate to the | |
798 | + same partition. These nodes are called the "COMDAT Frontier". The | |
799 | + idea is that every unpartitioned node that reaches a COMDAT group MUST | |
800 | + go through the COMDAT frontier before reaching it. Therefore, only | |
801 | + nodes in the frontier are exported. */ | |
802 | + if (node->same_comdat_group || c == SYMBOL_DUPLICATE) | |
803 | + { | |
804 | + if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node)) | |
805 | + { | |
806 | + /* Add all inline clones and callees that are duplicated. */ | |
807 | + for (e = cnode->callers; e; e = e->next_caller) | |
808 | + if (!e->inline_failed) | |
809 | + { | |
810 | + ds->unite (set, e->caller->aux2); | |
811 | + merge_comdat_nodes (e->caller, set); | |
812 | + ret = true; | |
813 | + } | |
814 | + else if (c == SYMBOL_DUPLICATE) | |
815 | + { | |
816 | + ds->unite (set, e->caller->aux2); | |
817 | + merge_comdat_nodes (e->caller, set); | |
818 | + ret = true; | |
819 | + } | |
820 | + | |
821 | + /* Add all thunks associated with the function. */ | |
822 | + for (e = cnode->callees; e; e = e->next_callee) | |
823 | + if (e->caller->thunk.thunk_p && !e->caller->inlined_to) | |
824 | + { | |
825 | + ds->unite (set, e->callee->aux2); | |
826 | + merge_comdat_nodes (e->callee, set); | |
827 | + ret = true; | |
828 | + } | |
829 | + } | |
830 | + } | |
831 | + | |
832 | + return ret; | |
833 | +} | |
834 | + | |
835 | +void | |
836 | +lto_merge_comdat_map (void) | |
837 | +{ | |
838 | + symtab_node *node; | |
839 | + int n_partitions = 0, i, n = 0, j = 0; | |
840 | + int *compression; | |
841 | + | |
842 | + FOR_EACH_SYMBOL (node) | |
843 | + node->aux2 = n++; | |
844 | + | |
845 | + union_find disjoint_sets = union_find (n); | |
846 | + ds = &disjoint_sets; | |
847 | + | |
848 | + compression = (int *) alloca (n * sizeof (*compression)); | |
849 | + for (i = 0; i < n; ++i) | |
850 | + compression[i] = -1; /* Invalid value. */ | |
851 | + | |
852 | + | |
853 | + FOR_EACH_SYMBOL (node) | |
854 | + if (node->same_comdat_group) | |
855 | + merge_comdat_nodes (node, node->aux2); | |
856 | + | |
857 | + | |
858 | + i = 0, j = 0; | |
859 | + FOR_EACH_SYMBOL (node) | |
860 | + { | |
861 | + int root = disjoint_sets.find (i); | |
862 | + node->aux2 = root; | |
863 | + node->aux = NULL; | |
864 | + | |
865 | + if (node->get_partitioning_class () == SYMBOL_PARTITION | |
866 | + && compression[root] < 0) | |
867 | + compression[root] = j++; | |
868 | + i++; | |
869 | + } | |
870 | + | |
871 | + n_partitions = j; | |
872 | + | |
873 | + /* Create LTRANS partitions. */ | |
874 | + ltrans_partitions.create (n_partitions); | |
875 | + for (i = 0; i < n_partitions; i++) | |
876 | + new_partition (""); | |
877 | + | |
878 | + FOR_EACH_SYMBOL (node) | |
879 | + { | |
880 | + if (node->get_partitioning_class () != SYMBOL_PARTITION | |
881 | + || symbol_partitioned_p (node)) | |
882 | + continue; | |
883 | + | |
884 | + int p = compression[node->aux2]; | |
885 | + add_symbol_to_partition (ltrans_partitions[p], node); | |
886 | + } | |
887 | +} | |
888 | + | |
889 | + | |
773 | 890 | /* Helper function for qsort; sort nodes by order. */ |
774 | 891 | static int |
775 | 892 | node_cmp (const void *pa, const void *pb) |
@@ -1332,7 +1449,7 @@ static hash_map<const char *, unsigned> *lto_clone_numbers; | ||
1332 | 1449 | represented by DECL. */ |
1333 | 1450 | |
1334 | 1451 | static bool |
1335 | -privatize_symbol_name_1 (symtab_node *node, tree decl) | |
1452 | +privatize_symbol_name_1 (symtab_node *node, tree decl, bool wpa) | |
1336 | 1453 | { |
1337 | 1454 | const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); |
1338 | 1455 |
@@ -1340,8 +1457,10 @@ privatize_symbol_name_1 (symtab_node *node, tree decl) | ||
1340 | 1457 | return false; |
1341 | 1458 | |
1342 | 1459 | name = maybe_rewrite_identifier (name); |
1343 | - if (lto_clone_numbers) | |
1460 | + if (wpa) | |
1344 | 1461 | { |
1462 | + gcc_assert (lto_clone_numbers); | |
1463 | + | |
1345 | 1464 | unsigned &clone_number = lto_clone_numbers->get_or_insert (name); |
1346 | 1465 | symtab->change_decl_assembler_name (decl, |
1347 | 1466 | clone_function_name ( |
@@ -1375,7 +1494,9 @@ privatize_symbol_name_1 (symtab_node *node, tree decl) | ||
1375 | 1494 | static bool |
1376 | 1495 | privatize_symbol_name (symtab_node *node) |
1377 | 1496 | { |
1378 | - if (!privatize_symbol_name_1 (node, node->decl)) | |
1497 | + bool wpa = !split_outputs; | |
1498 | + | |
1499 | + if (!privatize_symbol_name_1 (node, node->decl, wpa)) | |
1379 | 1500 | return false; |
1380 | 1501 | |
1381 | 1502 | return true; |
@@ -41,3 +41,4 @@ void free_ltrans_partitions (void); | ||
41 | 41 | void lto_promote_statics_nonwpa (void); |
42 | 42 | void lto_check_usage_from_other_partitions (void); |
43 | 43 | void lto_max_no_alonevap_map (void); |
44 | +void lto_merge_comdat_map (void); |