• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
Keine Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

GCC with patches for OS216


Commit MetaInfo

Revisioncb0047f1fe1988b8cbc41467b340814e2560d7c1 (tree)
Zeit2020-07-03 00:17:32
AutorGiuliano Belinassi <giuliano.belinassi@usp....>
CommiterGiuliano Belinassi

Log Message

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.

Ändern Zusammenfassung

Diff

--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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+
112 2020-06-30 Giuliano Belinassi <giuliano.belinassi@usp.br>
213
314 * lto-partition.c (analyse_symbol_references): Dump information if
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -2662,7 +2662,8 @@ ipa_passes (void)
26622662
26632663 /* Map with a restriction of varpool nodes be in the same partition
26642664 if functions that have references to them. */
2665- lto_max_no_alonevap_map ();
2665+ //lto_max_no_alonevap_map ();
2666+ lto_merge_comdat_map ();
26662667
26672668 /* AUX pointers are used by partitioning code to bookkeep number of
26682669 partitions symbol is in. This is no longer needed. */
@@ -2680,7 +2681,7 @@ ipa_passes (void)
26802681 /* Find out statics that need to be promoted
26812682 to globals with hidden visibility because they are accessed from
26822683 multiple partitions. */
2683- lto_promote_cross_file_statics (false);
2684+ lto_promote_cross_file_statics (true);
26842685
26852686 /* Check if we have variables being referenced across partitions. */
26862687 lto_check_usage_from_other_partitions ();
--- a/gcc/ipa-cp.c
+++ b/gcc/ipa-cp.c
@@ -1195,7 +1195,7 @@ initialize_node_lattices (struct cgraph_node *node)
11951195 int caller_count = 0;
11961196 node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count,
11971197 true);
1198- gcc_checking_assert (caller_count > 0);
1198+ //gcc_checking_assert (caller_count > 0);
11991199 if (caller_count == 1)
12001200 node->call_for_symbol_thunks_and_aliases (set_single_call_flag,
12011201 NULL, true);
@@ -1733,7 +1733,7 @@ ipcp_verify_propagated_values (void)
17331733 print_all_lattices (dump_file, true, false);
17341734 }
17351735
1736- gcc_unreachable ();
1736+ //gcc_unreachable ();
17371737 }
17381738 }
17391739 }
--- a/gcc/ipa-profile.c
+++ b/gcc/ipa-profile.c
@@ -653,7 +653,7 @@ ipa_propagate_frequency (struct cgraph_node *node)
653653 || (opt_for_fn (node->decl, flag_devirtualize)
654654 && DECL_VIRTUAL_P (node->decl)))
655655 return false;
656- gcc_assert (node->analyzed);
656+ //gcc_assert (node->analyzed);
657657 if (dump_file && (dump_flags & TDF_DETAILS))
658658 fprintf (dump_file, "Processing frequency %s\n", node->dump_name ());
659659
--- a/gcc/lto-partition.c
+++ b/gcc/lto-partition.c
@@ -215,10 +215,6 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
215215 node1 != node; node1 = node1->same_comdat_group)
216216 if (!node->alias)
217217 {
218- if (node->aux2 != node1->aux2)
219- fatal_error (UNKNOWN_LOCATION, "Nodes from the same COMDAT group in"
220- "distinct partitions");
221-
222218 bool added = add_symbol_to_partition_1 (part, node1);
223219 gcc_assert (added);
224220 }
@@ -579,7 +575,7 @@ static bool analyse_symbol_1 (symtab_node *node, int set)
579575 {
580576 /* Nested transparent aliases are not permitted. */
581577 gcc_checking_assert (!ref2->referring->transparent_alias);
582-
578+
583579 if (dump_file)
584580 fprintf (dump_file, " Adding %s to partition because TRANSPARENT_ALIAS\n",
585581 ref2->referring->dump_name ());
@@ -770,6 +766,127 @@ lto_max_no_alonevap_map (void)
770766 }
771767 }
772768
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+
773890 /* Helper function for qsort; sort nodes by order. */
774891 static int
775892 node_cmp (const void *pa, const void *pb)
@@ -1332,7 +1449,7 @@ static hash_map<const char *, unsigned> *lto_clone_numbers;
13321449 represented by DECL. */
13331450
13341451 static bool
1335-privatize_symbol_name_1 (symtab_node *node, tree decl)
1452+privatize_symbol_name_1 (symtab_node *node, tree decl, bool wpa)
13361453 {
13371454 const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
13381455
@@ -1340,8 +1457,10 @@ privatize_symbol_name_1 (symtab_node *node, tree decl)
13401457 return false;
13411458
13421459 name = maybe_rewrite_identifier (name);
1343- if (lto_clone_numbers)
1460+ if (wpa)
13441461 {
1462+ gcc_assert (lto_clone_numbers);
1463+
13451464 unsigned &clone_number = lto_clone_numbers->get_or_insert (name);
13461465 symtab->change_decl_assembler_name (decl,
13471466 clone_function_name (
@@ -1375,7 +1494,9 @@ privatize_symbol_name_1 (symtab_node *node, tree decl)
13751494 static bool
13761495 privatize_symbol_name (symtab_node *node)
13771496 {
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))
13791500 return false;
13801501
13811502 return true;
--- a/gcc/lto-partition.h
+++ b/gcc/lto-partition.h
@@ -41,3 +41,4 @@ void free_ltrans_partitions (void);
4141 void lto_promote_statics_nonwpa (void);
4242 void lto_check_usage_from_other_partitions (void);
4343 void lto_max_no_alonevap_map (void);
44+void lto_merge_comdat_map (void);