diff options
author | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-07-02 12:17:32 -0300 |
---|---|---|
committer | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-07-02 12:17:32 -0300 |
commit | cb0047f1fe1988b8cbc41467b340814e2560d7c1 (patch) | |
tree | f238c10927ab7d91223c6d6587bde79ec66366ec /gcc | |
parent | 6e9a06040d56058918f313ca067f6597565d5651 (diff) | |
download | gcc-cb0047f1fe1988b8cbc41467b340814e2560d7c1.zip gcc-cb0047f1fe1988b8cbc41467b340814e2560d7c1.tar.gz gcc-cb0047f1fe1988b8cbc41467b340814e2560d7c1.tar.bz2 |
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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 5 | ||||
-rw-r--r-- | gcc/ipa-cp.c | 4 | ||||
-rw-r--r-- | gcc/ipa-profile.c | 2 | ||||
-rw-r--r-- | gcc/lto-partition.c | 137 | ||||
-rw-r--r-- | gcc/lto-partition.h | 1 |
6 files changed, 147 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c95991f..fe4eb6e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +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. + 2020-06-30 Giuliano Belinassi <giuliano.belinassi@usp.br> * lto-partition.c (analyse_symbol_references): Dump information if diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 381d360..3f416c1 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -2662,7 +2662,8 @@ ipa_passes (void) /* Map with a restriction of varpool nodes be in the same partition if functions that have references to them. */ - lto_max_no_alonevap_map (); + //lto_max_no_alonevap_map (); + lto_merge_comdat_map (); /* AUX pointers are used by partitioning code to bookkeep number of partitions symbol is in. This is no longer needed. */ @@ -2680,7 +2681,7 @@ ipa_passes (void) /* Find out statics that need to be promoted to globals with hidden visibility because they are accessed from multiple partitions. */ - lto_promote_cross_file_statics (false); + lto_promote_cross_file_statics (true); /* Check if we have variables being referenced across partitions. */ lto_check_usage_from_other_partitions (); diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index c64e910..9915bf6 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -1195,7 +1195,7 @@ initialize_node_lattices (struct cgraph_node *node) int caller_count = 0; node->call_for_symbol_thunks_and_aliases (count_callers, &caller_count, true); - gcc_checking_assert (caller_count > 0); + //gcc_checking_assert (caller_count > 0); if (caller_count == 1) node->call_for_symbol_thunks_and_aliases (set_single_call_flag, NULL, true); @@ -1733,7 +1733,7 @@ ipcp_verify_propagated_values (void) print_all_lattices (dump_file, true, false); } - gcc_unreachable (); + //gcc_unreachable (); } } } diff --git a/gcc/ipa-profile.c b/gcc/ipa-profile.c index 9fbfa90..22a2689 100644 --- a/gcc/ipa-profile.c +++ b/gcc/ipa-profile.c @@ -653,7 +653,7 @@ ipa_propagate_frequency (struct cgraph_node *node) || (opt_for_fn (node->decl, flag_devirtualize) && DECL_VIRTUAL_P (node->decl))) return false; - gcc_assert (node->analyzed); + //gcc_assert (node->analyzed); if (dump_file && (dump_flags & TDF_DETAILS)) fprintf (dump_file, "Processing frequency %s\n", node->dump_name ()); diff --git a/gcc/lto-partition.c b/gcc/lto-partition.c index 1798ff75..78a32ea 100644 --- 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) node1 != node; node1 = node1->same_comdat_group) if (!node->alias) { - if (node->aux2 != node1->aux2) - fatal_error (UNKNOWN_LOCATION, "Nodes from the same COMDAT group in" - "distinct partitions"); - bool added = add_symbol_to_partition_1 (part, node1); gcc_assert (added); } @@ -579,7 +575,7 @@ static bool analyse_symbol_1 (symtab_node *node, int set) { /* Nested transparent aliases are not permitted. */ gcc_checking_assert (!ref2->referring->transparent_alias); - + if (dump_file) fprintf (dump_file, " Adding %s to partition because TRANSPARENT_ALIAS\n", ref2->referring->dump_name ()); @@ -770,6 +766,127 @@ lto_max_no_alonevap_map (void) } } +static bool +merge_comdat_nodes (symtab_node *node, int set) +{ + enum symbol_partitioning_class c = node->get_partitioning_class (); + bool ret = false; + symtab_node *node1; + cgraph_edge *e; + + /* If node is already analysed, quickly return. */ + if (node->aux) + return false; + + node->aux = (void *) 1; + + + /* Aglomerate the COMDAT group into the same partition. */ + if (node->same_comdat_group) + { + for (node1 = node->same_comdat_group; + node1 != node; node1 = node1->same_comdat_group) + if (!node->alias) + { + ds->unite (node1->aux2, set); + merge_comdat_nodes (node1, set); + ret = true; + } + } + + /* Look at nodes that can reach the COMDAT group, and aglomerate to the + same partition. These nodes are called the "COMDAT Frontier". The + idea is that every unpartitioned node that reaches a COMDAT group MUST + go through the COMDAT frontier before reaching it. Therefore, only + nodes in the frontier are exported. */ + if (node->same_comdat_group || c == SYMBOL_DUPLICATE) + { + if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node)) + { + /* Add all inline clones and callees that are duplicated. */ + for (e = cnode->callers; e; e = e->next_caller) + if (!e->inline_failed) + { + ds->unite (set, e->caller->aux2); + merge_comdat_nodes (e->caller, set); + ret = true; + } + else if (c == SYMBOL_DUPLICATE) + { + ds->unite (set, e->caller->aux2); + merge_comdat_nodes (e->caller, set); + ret = true; + } + + /* Add all thunks associated with the function. */ + for (e = cnode->callees; e; e = e->next_callee) + if (e->caller->thunk.thunk_p && !e->caller->inlined_to) + { + ds->unite (set, e->callee->aux2); + merge_comdat_nodes (e->callee, set); + ret = true; + } + } + } + + return ret; +} + +void +lto_merge_comdat_map (void) +{ + symtab_node *node; + int n_partitions = 0, i, n = 0, j = 0; + int *compression; + + FOR_EACH_SYMBOL (node) + node->aux2 = n++; + + union_find disjoint_sets = union_find (n); + ds = &disjoint_sets; + + compression = (int *) alloca (n * sizeof (*compression)); + for (i = 0; i < n; ++i) + compression[i] = -1; /* Invalid value. */ + + + FOR_EACH_SYMBOL (node) + if (node->same_comdat_group) + merge_comdat_nodes (node, node->aux2); + + + i = 0, j = 0; + FOR_EACH_SYMBOL (node) + { + int root = disjoint_sets.find (i); + node->aux2 = root; + node->aux = NULL; + + if (node->get_partitioning_class () == SYMBOL_PARTITION + && compression[root] < 0) + compression[root] = j++; + i++; + } + + n_partitions = j; + + /* Create LTRANS partitions. */ + ltrans_partitions.create (n_partitions); + for (i = 0; i < n_partitions; i++) + new_partition (""); + + FOR_EACH_SYMBOL (node) + { + if (node->get_partitioning_class () != SYMBOL_PARTITION + || symbol_partitioned_p (node)) + continue; + + int p = compression[node->aux2]; + add_symbol_to_partition (ltrans_partitions[p], node); + } +} + + /* Helper function for qsort; sort nodes by order. */ static int node_cmp (const void *pa, const void *pb) @@ -1332,7 +1449,7 @@ static hash_map<const char *, unsigned> *lto_clone_numbers; represented by DECL. */ static bool -privatize_symbol_name_1 (symtab_node *node, tree decl) +privatize_symbol_name_1 (symtab_node *node, tree decl, bool wpa) { const char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); @@ -1340,8 +1457,10 @@ privatize_symbol_name_1 (symtab_node *node, tree decl) return false; name = maybe_rewrite_identifier (name); - if (lto_clone_numbers) + if (wpa) { + gcc_assert (lto_clone_numbers); + unsigned &clone_number = lto_clone_numbers->get_or_insert (name); symtab->change_decl_assembler_name (decl, clone_function_name ( @@ -1375,7 +1494,9 @@ privatize_symbol_name_1 (symtab_node *node, tree decl) static bool privatize_symbol_name (symtab_node *node) { - if (!privatize_symbol_name_1 (node, node->decl)) + bool wpa = !split_outputs; + + if (!privatize_symbol_name_1 (node, node->decl, wpa)) return false; return true; diff --git a/gcc/lto-partition.h b/gcc/lto-partition.h index 7428b03..788442d 100644 --- a/gcc/lto-partition.h +++ b/gcc/lto-partition.h @@ -41,3 +41,4 @@ void free_ltrans_partitions (void); void lto_promote_statics_nonwpa (void); void lto_check_usage_from_other_partitions (void); void lto_max_no_alonevap_map (void); +void lto_merge_comdat_map (void); |