diff options
author | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-07-07 15:48:08 -0300 |
---|---|---|
committer | Giuliano Belinassi <giuliano.belinassi@usp.br> | 2020-07-07 15:48:08 -0300 |
commit | 0db25c6846b063dbd3c140793b7aa246f02a1400 (patch) | |
tree | a3e214cda4f02fe03ca30afc518467f9b15f9c14 /gcc | |
parent | f7370689230ad58dbd0e99d4f9b5b5f0de487916 (diff) | |
download | gcc-0db25c6846b063dbd3c140793b7aa246f02a1400.zip gcc-0db25c6846b063dbd3c140793b7aa246f02a1400.tar.gz gcc-0db25c6846b063dbd3c140793b7aa246f02a1400.tar.bz2 |
'Bootstrap' with promote statics
This commit manages to get promote statics to work so that stage3
compiler works, but it fails because of symbol randomization. To achive
this, we had to disable the ipa-sra optimization, as it was generating
incorrect code.
gcc/ChangeLog:
2020-07-07 Giuliano Belinassi <giuliano.belinassi@usp.br>
* cgraphunit.c (ipa_passes): Quick switch between promote statics
and balance.
* ipa-sra.c (gate): Disable it for split_outputs.
* ipa.c (remove_unreachable_nodes): Force output vnodes are
obviously needed.
* lto-cgraph.c (lto_apply_partition_mask): use aux2 instead of aux,
and mark nodes in the boundary to not be removed.
* lto-partition.c (merge_comdat_nodes): Handle references.
(balance_partitions): Avoid generating several small partitions.
(merge_contained_symbols): New function.
(lto_merge_comdat_map): Handle contained symbols.
(lto_promote_cross_file_statics): Set promoted nodes to be
non-local.
* tree.c (filter_name): New function.
(get_file_function_name): Filter buf so that it do not confuse ld.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/cgraphunit.c | 3 | ||||
-rw-r--r-- | gcc/ipa-sra.c | 3 | ||||
-rw-r--r-- | gcc/ipa.c | 3 | ||||
-rw-r--r-- | gcc/lto-cgraph.c | 27 | ||||
-rw-r--r-- | gcc/lto-partition.c | 83 | ||||
-rw-r--r-- | gcc/tree.c | 19 |
7 files changed, 121 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 687c559..98d66bd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,23 @@ -2020-07-02 Giuliano Belinass <giuliano.belinassi@usp.br> +2020-07-07 Giuliano Belinassi <giuliano.belinassi@usp.br> + + * cgraphunit.c (ipa_passes): Quick switch between promote statics + and balance. + * ipa-sra.c (gate): Disable it for split_outputs. + * ipa.c (remove_unreachable_nodes): Force output vnodes are + obviously needed. + * lto-cgraph.c (lto_apply_partition_mask): use aux2 instead of aux, + and mark nodes in the boundary to not be removed. + * lto-partition.c (merge_comdat_nodes): Handle references. + (balance_partitions): Avoid generating several small partitions. + (merge_contained_symbols): New function. + (lto_merge_comdat_map): Handle contained symbols. + (lto_promote_cross_file_statics): Set promoted nodes to be + non-local. + * tree.c (filter_name): New function. + (get_file_function_name): Filter buf so that it do not confuse ld. + + +2020-07-02 Giuliano Belinassi <giuliano.belinassi@usp.br> * cgraphunit.c (ipa_passes): Update ipa_passes. * lto-partition.c (balance_partitions): New function. diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index 50997c8..1cb13d1 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -2657,6 +2657,7 @@ ipa_passes (void) if (split_outputs) { bool promote_statics = true; + bool balance = true; /* Trick the compiler to think that we are in WPA. */ flag_wpa = ""; @@ -2665,7 +2666,7 @@ 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_merge_comdat_map (false, promote_statics); + lto_merge_comdat_map (balance, promote_statics); /* AUX pointers are used by partitioning code to bookkeep number of partitions symbol is in. This is no longer needed. */ diff --git a/gcc/ipa-sra.c b/gcc/ipa-sra.c index 7c922e4..8ee027d 100644 --- a/gcc/ipa-sra.c +++ b/gcc/ipa-sra.c @@ -4089,7 +4089,8 @@ public: { /* TODO: We should remove the optimize check after we ensure we never run IPA passes when not optimizing. */ - return (flag_ipa_sra && optimize); + /* FIXME: Fix this optimization when split_outputs is enabled. */ + return (flag_ipa_sra && optimize && !split_outputs); } virtual unsigned int execute (function *) { return ipa_sra_analysis (); } @@ -350,8 +350,9 @@ symbol_table::remove_unreachable_nodes (FILE *file) /* Mark variables that are obviously needed. */ FOR_EACH_DEFINED_VARIABLE (vnode) - if (!vnode->can_remove_if_no_refs_p() + if ((!vnode->can_remove_if_no_refs_p() && !vnode->in_other_partition) + || vnode->force_output) { reachable.add (vnode); enqueue_node (vnode, &first, &reachable); diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index 381757a..8469d5b 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -2073,10 +2073,13 @@ lto_apply_partition_mask (ltrans_partition partition) auto_vec<symtab_node *, 16> force_output_enabled; unsigned int i; + FOR_EACH_SYMBOL (node) + node->aux2 = 0; + for (i = 0; i < nodes.length (); i++) { symtab_node *node = nodes[i].node; - node->aux = (void *) 1; + node->aux2 = 1; if (!nodes[i].in_partition) { @@ -2120,25 +2123,23 @@ lto_apply_partition_mask (ltrans_partition partition) for (i = 0; i < nodes.length (); i++) { symtab_node *node = nodes[i].node; - + + /* Temporarly set force output to avoid incorrect removal of node. */ + if (node->force_output) + force_output_enabled.safe_push (node); + else + node->force_output = true; + /* Handle Schrondiger nodes that are and are not in the partition. */ if (nodes[i].in_partition) - { - node->in_other_partition = false; - - /* Temporarly set force output to avoid incorrect removal of node. */ - if (node->force_output) - force_output_enabled.safe_push (node); - else - node->force_output = true; - } + node->in_other_partition = false; } FOR_EACH_SYMBOL (node) - if (!node->aux) + if (node->aux2 == 0) mark_to_remove.safe_push (node); else - node->aux = NULL; + node->aux2 = 0; for (i = 0; i < mark_to_remove.length (); i++) { diff --git a/gcc/lto-partition.c b/gcc/lto-partition.c index 2566a4e..bc27a09 100644 --- a/gcc/lto-partition.c +++ b/gcc/lto-partition.c @@ -636,19 +636,20 @@ balance_partitions (union_find *ds, int n) i = 0; FOR_EACH_SYMBOL (node) { - cgraph_node *cnode = dyn_cast<cgraph_node *> (node); - if (!cnode) - { - i++; - continue; - } + int root = ds->find (i); - ipa_size_summary *summary = ipa_size_summaries->get (cnode); - if (summary) + if (cgraph_node *cnode = dyn_cast<cgraph_node *> (node)) { - int root = ds->find (i); - sizes[root] += summary->size; + ipa_size_summary *summary = ipa_size_summaries->get (cnode); + if (summary) + sizes[root] += summary->size; + else + sizes[root] += 10; } + else + sizes[root] += 10; + + i++; } @@ -663,7 +664,7 @@ balance_partitions (union_find *ds, int n) if (total_size < param_min_partition_size) return false; - target_size = total_size / 8; + target_size = total_size / 3; /* Unite small partitions. */ for (i = 0, j = 0; j < n; ++j) @@ -930,17 +931,14 @@ merge_comdat_nodes (symtab_node *node, int set) nodes in the frontier are exported. */ if (node->same_comdat_group || c == SYMBOL_DUPLICATE) { + int i; + struct ipa_ref *ref = NULL; + 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) + if (!e->inline_failed || c == SYMBOL_DUPLICATE) { ds->unite (set, e->caller->aux2); merge_comdat_nodes (e->caller, set); @@ -956,6 +954,16 @@ merge_comdat_nodes (symtab_node *node, int set) ret = true; } } + + for (i = 0; node->iterate_referring (i, ref); i++) + { + symtab_node *node1 = ref->referring; + ds->unite (node1->aux2, set); + ret = true; + + if (node1->get_partitioning_class () == SYMBOL_DUPLICATE) + merge_comdat_nodes (node1, set); + } } return ret; @@ -1008,6 +1016,22 @@ merge_static_calls (symtab_node *node, int set) return ret; } +static bool +merge_contained_symbols (symtab_node *node, int set) +{ + bool ret = false; + symtab_node *node1; + + while ((node1 = contained_in_symbol (node)) != node) + { + node = node1; + ds->unite (node->aux2, set); + ret = true; + } + + return ret; +} + /* Partition the program into several partitions with a restriction that COMDATS are partitioned together with all nodes requiring them. If promote_statics is false, we also partition together static functions @@ -1029,8 +1053,11 @@ lto_merge_comdat_map (bool balance, bool promote_statics) /* First look at COMDATs. */ FOR_EACH_SYMBOL (node) - if (node->same_comdat_group) - merge_comdat_nodes (node, node->aux2); + { + if (node->same_comdat_group) + merge_comdat_nodes (node, node->aux2); + merge_contained_symbols (node, node->aux2); + } /* Then look at STATICs, if needed. */ if (!promote_statics) @@ -1038,6 +1065,9 @@ lto_merge_comdat_map (bool balance, bool promote_statics) if (!TREE_PUBLIC (node->decl)) merge_static_calls (node, node->aux2); + FOR_EACH_SYMBOL (node) + node->aux = NULL; + if (balance) if (!balance_partitions (&disjoint_sets, n)) return; @@ -1834,10 +1864,17 @@ lto_promote_cross_file_statics (bool promote) lsei_next (&lsei)) { symtab_node *node = lsei_node (lsei); + cgraph_node *cnode = dyn_cast <cgraph_node *> (node); /* If symbol is static, rename it if its assembler name clashes with anything else in this unit. */ rename_statics (encoder, node); + if (cnode) + { + bool in_partition = lsei.encoder->nodes[lsei.index].in_partition; + if (!in_partition) + cnode->local = false; + } /* No need to promote if symbol already is externally visible ... */ if (node->externally_visible @@ -1851,7 +1888,11 @@ lto_promote_cross_file_statics (bool promote) continue; } if (promote) - promote_symbol (node); + { + promote_symbol (node); + if (cnode && split_outputs) + cnode->local = false; + } } } delete lto_clone_numbers; @@ -9612,6 +9612,24 @@ make_anon_name () return id; } +/* Filter the input name removing characters that may confuse the linker. */ + +static void +filter_name (char *name) +{ + char *p = name; + + while (*p != '\0') + { + switch (*p) + { + case '*': + *p = '_'; + } + p++; + } +} + /* Generate a name for a special-purpose function. The generated name may need to be unique across the whole link. Changes to this function may also require corresponding changes to @@ -9683,6 +9701,7 @@ get_file_function_name (const char *type) the program) rather than the file name (which imposes extra constraints). */ sprintf (buf, FILE_FUNCTION_FORMAT, type, p); + filter_name (buf); return get_identifier (buf); } |