aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2020-07-07 15:48:08 -0300
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-07-07 15:48:08 -0300
commit0db25c6846b063dbd3c140793b7aa246f02a1400 (patch)
treea3e214cda4f02fe03ca30afc518467f9b15f9c14 /gcc
parentf7370689230ad58dbd0e99d4f9b5b5f0de487916 (diff)
downloadgcc-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/ChangeLog21
-rw-r--r--gcc/cgraphunit.c3
-rw-r--r--gcc/ipa-sra.c3
-rw-r--r--gcc/ipa.c3
-rw-r--r--gcc/lto-cgraph.c27
-rw-r--r--gcc/lto-partition.c83
-rw-r--r--gcc/tree.c19
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 (); }
diff --git a/gcc/ipa.c b/gcc/ipa.c
index 6a33674..1d39b9b 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -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;
diff --git a/gcc/tree.c b/gcc/tree.c
index e451401..32977e5 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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);
}