aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorGiuliano Belinassi <giuliano.belinassi@usp.br>2020-06-30 00:29:21 -0300
committerGiuliano Belinassi <giuliano.belinassi@usp.br>2020-06-30 00:29:21 -0300
commitf17ad988fabb0adc9a1cd32904a98ccc3720f0b4 (patch)
tree4661fb912d5fe06eb8a9eb0ac88b4445179f6f19 /gcc
parente778bf0fc6f0d6e15f81976b4fc461337ef63146 (diff)
downloadgcc-f17ad988fabb0adc9a1cd32904a98ccc3720f0b4.zip
gcc-f17ad988fabb0adc9a1cd32904a98ccc3720f0b4.tar.gz
gcc-f17ad988fabb0adc9a1cd32904a98ccc3720f0b4.tar.bz2
Better handle statics.
Previously, we merge any reference to static var or function. Now we are more careful by looking if it is publically available, and avoid merging partitions which have references to a non-static variable. 2020-06-30 Giuliano Belinassi <giuliano.belinassi@usp.br> * lto-cgraph.c (lto_apply_partition_mask): Avoid removal of nodes in partition. (maybe_release_function_dominators): Move from. * cgraph.c (maybe_release_dominators): To here. * ipa-visibility.c (localize_node): Skip assertion if split_outputs. * lto-partition.c (analyse_symbol_references): Merge partitions if reference to static varnode instead of any global. (promote_symbol): Correctly handle statics. (lto_max_no_alonevap_map): Remove quick returns. (privatize_symbol_name_1): Implement hashing of static names.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/cgraph.c14
-rw-r--r--gcc/cgraph.h2
-rw-r--r--gcc/ipa-visibility.c2
-rw-r--r--gcc/lto-cgraph.c60
-rw-r--r--gcc/lto-partition.c126
6 files changed, 133 insertions, 84 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 3cdc5eb..a2e5098 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2020-06-30 Giuliano Belinassi <giuliano.belinassi@usp.br>
+ * lto-cgraph.c (lto_apply_partition_mask): Avoid removal of nodes
+ in partition.
+ (maybe_release_function_dominators): Move from.
+ * cgraph.c (maybe_release_dominators): To here.
+ * ipa-visibility.c (localize_node): Skip assertion if
+ split_outputs.
+ * lto-partition.c (analyse_symbol_references): Merge
+ partitions if reference to static varnode instead of any global.
+ (promote_symbol): Correctly handle statics.
+ (lto_max_no_alonevap_map): Remove quick returns.
+ (privatize_symbol_name_1): Implement hashing of static names.
+
2020-06-24 Giuliano Belinassi <giuliano.belinassi@usp.br>
* cgraphunit.c (ipa_passes): Assert for non-empty partition.
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 2a9813d..f99e55d 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -226,6 +226,20 @@ cgraph_node::delete_function_version_by_decl (tree decl)
decl_node->remove ();
}
+void
+cgraph_node::maybe_release_dominators (void)
+{
+ struct function *fun = DECL_STRUCT_FUNCTION (decl);
+
+ if (fun && fun->cfg)
+ {
+ if (dom_info_available_p (fun, CDI_DOMINATORS))
+ free_dominance_info (fun, CDI_DOMINATORS);
+ if (dom_info_available_p (fun, CDI_POST_DOMINATORS))
+ free_dominance_info (fun, CDI_POST_DOMINATORS);
+ }
+}
+
/* Record that DECL1 and DECL2 are semantically identical function
versions. */
void
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 5678696..962670c 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -1337,6 +1337,8 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
/* Dump the callgraph to file F. */
static void dump_cgraph (FILE *f);
+ void maybe_release_dominators ();
+
/* Dump the call graph to stderr. */
static inline
void debug_cgraph (void)
diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c
index 087775d..f83fba9 100644
--- a/gcc/ipa-visibility.c
+++ b/gcc/ipa-visibility.c
@@ -541,7 +541,7 @@ static void
localize_node (bool whole_program, symtab_node *node)
{
/* FIXME: This seems not to be necessary when compiling in fsplit-args. */
- gcc_assert (whole_program || in_lto_p || !TREE_PUBLIC (node->decl));
+ gcc_assert (split_outputs || whole_program || in_lto_p || !TREE_PUBLIC (node->decl));
/* It is possible that one comdat group contains both hidden and non-hidden
symbols. In this case we can privatize all hidden symbol but we need
diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c
index acaef4a..381757a 100644
--- a/gcc/lto-cgraph.c
+++ b/gcc/lto-cgraph.c
@@ -2061,30 +2061,6 @@ input_cgraph_opt_summary (vec<symtab_node *> nodes)
}
}
-static void
-maybe_release_function_dominators (cgraph_node *cnode)
-{
- struct function *fun = DECL_STRUCT_FUNCTION (cnode->decl);
-
- if (fun && fun->cfg)
- {
- if (dom_info_available_p (fun, CDI_DOMINATORS))
- free_dominance_info (fun, CDI_DOMINATORS);
- if (dom_info_available_p (fun, CDI_POST_DOMINATORS))
- free_dominance_info (fun, CDI_POST_DOMINATORS);
- }
-}
-
-static void
-maybe_release_function_dominators (symtab_node *node)
-{
- cgraph_node *cnode = dyn_cast<cgraph_node *> (node);
- if (!cnode)
- return;
-
- maybe_release_function_dominators (cnode);
-}
-
/* Replace the partition in the symbol table, removing every node which is not
in partition. */
@@ -2094,6 +2070,7 @@ lto_apply_partition_mask (ltrans_partition partition)
vec<lto_encoder_entry> &nodes = partition->encoder->nodes;
symtab_node *node;
auto_vec<symtab_node *, 16> mark_to_remove;
+ auto_vec<symtab_node *, 16> force_output_enabled;
unsigned int i;
for (i = 0; i < nodes.length (); i++)
@@ -2104,14 +2081,16 @@ lto_apply_partition_mask (ltrans_partition partition)
if (!nodes[i].in_partition)
{
cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
+ varpool_node *vnode = dyn_cast <varpool_node *> (node);
if (cnode)
{
+ cnode->maybe_release_dominators ();
+
if (cnode->clone_of)
cnode->remove_from_clone_tree ();
if (cnode->has_gimple_body_p ())
{
- maybe_release_function_dominators (cnode);
cnode->remove_callees ();
cnode->remove_all_references ();
cnode->release_body ();
@@ -2133,6 +2112,25 @@ lto_apply_partition_mask (ltrans_partition partition)
cnode->in_other_partition = true;
}
}
+ else if (vnode && !DECL_EXTERNAL (vnode->decl))
+ vnode->in_other_partition = true;
+ }
+ }
+
+ for (i = 0; i < nodes.length (); i++)
+ {
+ symtab_node *node = nodes[i].node;
+
+ /* 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;
}
}
@@ -2145,10 +2143,20 @@ lto_apply_partition_mask (ltrans_partition partition)
for (i = 0; i < mark_to_remove.length (); i++)
{
symtab_node *node = mark_to_remove[i];
- maybe_release_function_dominators (node);
+ if (is_a <cgraph_node *> (node))
+ dyn_cast <cgraph_node *> (node)->maybe_release_dominators ();
node->remove ();
}
symtab->remove_unreachable_nodes (NULL);
+
+ FOR_EACH_SYMBOL (node)
+ node->force_output = false;
+
+ for (i = 0; i < force_output_enabled.length (); ++i)
+ {
+ symtab_node *node = force_output_enabled[i];
+ node->force_output = true;
+ }
}
diff --git a/gcc/lto-partition.c b/gcc/lto-partition.c
index 72a2bdb..2165501 100644
--- a/gcc/lto-partition.c
+++ b/gcc/lto-partition.c
@@ -472,12 +472,16 @@ analyse_symbol_references (symtab_node *node, int set)
symtab_node *node1 = ref->referred;
analyse_symbol (node1, set);
}
- /* References to a readonly variable may be constant foled into its value.
- Recursively look into the initializers of the constant variable and add
- references, too. */
+
/* Check if we have a reference to global variable or function. */
if (is_a <varpool_node *> (ref->referred)
- || is_a <cgraph_node *> (ref->referred))
+ && TREE_STATIC (ref->referred->decl)
+ && !TREE_PUBLIC (ref->referred->decl))
+ {
+ symtab_node *node1 = ref->referred;
+ analyse_symbol (node1, set);
+ }
+ else if (is_a <cgraph_node *> (ref->referred))
{
symtab_node *node1 = ref->referred;
analyse_symbol (node1, set);
@@ -485,6 +489,12 @@ analyse_symbol_references (symtab_node *node, int set)
}
}
+static bool
+privatize_symbol_name (symtab_node *);
+
+static void
+promote_symbol (symtab_node *);
+
static bool analyse_symbol_1 (symtab_node *node, int set)
{
struct ipa_ref *ref;
@@ -505,15 +515,30 @@ static bool analyse_symbol_1 (symtab_node *node, int set)
/* Add all inline clones and callees that are duplicated. */
for (e = cnode->callees; e; e = e->next_callee)
- if (!e->inline_failed || TREE_STATIC (e->callee->decl))
+ if (!e->inline_failed)
analyse_symbol_1 (e->callee, set);
else if (e->callee->get_partitioning_class () == SYMBOL_DUPLICATE)
analyse_symbol (e->callee, set);
+ /*
+ if (!node->same_comdat_group && TREE_STATIC (cnode->decl)
+ && !TREE_PUBLIC (cnode->decl) && !cnode->inlined_to &&
+ !DECL_DECLARED_INLINE_P (cnode->decl))
+ {
+
+ promote_symbol (cnode);
+ cnode->local = false;
+ }
+ */
+
/* Add all thunks associated with the function. */
for (e = cnode->callers; e; e = e->next_caller)
if (e->caller->thunk.thunk_p && !e->caller->inlined_to)
analyse_symbol_1 (e->caller, set);
+
+ else if (e->inline_failed && TREE_STATIC (cnode->decl)
+ && !TREE_PUBLIC (cnode->decl))
+ analyse_symbol_1 (e->caller, set);
}
analyse_symbol_references (node, set);
@@ -571,7 +596,6 @@ lto_max_no_alonevap_map (void)
{
symtab_node *node;
int n_partitions = 0, i, n = 0, j = 0;
- int total_size = 0, max_size = -1;
int *compression;
int *sizes;
@@ -581,6 +605,22 @@ lto_max_no_alonevap_map (void)
union_find disjoint_sets = union_find (n);
ds = &disjoint_sets;
+
+ /* Allocate a compression vector, where we will map each disjoint set into
+ 0, ..., n_partitions - 1. Also allocates a size vector which will
+ hold each partition size. Complexity: n. */
+
+ compression = (int *) alloca (n * sizeof (*compression));
+ sizes = (int *) alloca (n * sizeof (*sizes));
+ memset (sizes, 0, n * sizeof (*sizes));
+ for (i = 0; i < n; ++i)
+ compression[i] = -1; /* Invalid value. */
+
+ int total_size = 0, max_size = -1;
+ int target_size;
+ const int eps = 0;
+ /* Compute the size of each node. */
+
/* Look for each function neighbor, checking for global-like variables that
it references. Complexity:
@@ -594,18 +634,6 @@ lto_max_no_alonevap_map (void)
FOR_EACH_SYMBOL (node)
analyse_symbol (node, node->aux2);
- /* Allocate a compression vector, where we will map each disjoint set into
- 0, ..., n_partitions - 1. Also allocates a size vector which will
- hold each partition size. Complexity: n. */
-
- compression = (int *) alloca (n * sizeof (*compression));
- sizes = (int *) alloca (n * sizeof (*sizes));
- memset (sizes, 0, n * sizeof (*sizes));
- for (i = 0; i < n; ++i)
- compression[i] = -1; /* Invalid value. */
-
-
- /* Compute the size of each partition. */
i = 0;
FOR_EACH_SYMBOL (node)
{
@@ -633,12 +661,13 @@ lto_max_no_alonevap_map (void)
}
/* Quick return if total size is small. */
- if (total_size < param_min_partition_size)
- return;
+ //if (total_size < param_min_partition_size)
+ // return;
- /* Unite small partitions. */
+ target_size = total_size / 8;
- for (i = -1, j = 0; j < n; ++j)
+ /* Unite small partitions. */
+ for (i = 0, j = 0; j < n; ++j)
{
if (sizes[j] == 0)
continue;
@@ -647,43 +676,17 @@ lto_max_no_alonevap_map (void)
i = j;
else
{
- if (sizes[i] + sizes[j] < max_size)
+ if (sizes[i] + sizes[j] < target_size + eps)
{
ds->unite (i, j);
- sizes[j] += sizes[i];
- sizes[i] = 0;
+ sizes[i] += sizes[j];
+ sizes[j] = 0;
}
else
i = j;
}
}
- /* Unite the smallest partition with the second smallest. This is
- to avoid having one very big partition and two other very small ones. */
- int smallest_pos = -1;
- int second_smallest_pos = -1;
- int smallest = INT_MAX;
-
- for (i = 0; i < n; ++i)
- {
- if (sizes[i] == 0)
- continue;
-
- if (sizes[i] < smallest)
- {
- smallest = sizes[i];
- second_smallest_pos = smallest_pos;
- smallest_pos = i;
- }
- }
-
- if (smallest_pos != -1 && second_smallest_pos != -1)
- {
- ds->unite (smallest_pos, second_smallest_pos);
- sizes[smallest_pos] += sizes[second_smallest_pos];
- sizes[second_smallest_pos] = 0;
- }
-
/* Compress 0...(n-1) into 0...(n_partitions-1) so that we avoid manuvers with
the LTRANS partitions. Complexity: n * log*(n). */
@@ -703,8 +706,11 @@ lto_max_no_alonevap_map (void)
n_partitions = j;
/* Quick return if we have only one partition. */
+ /* FIXME: We can't quiclky return here because nodes may be dirty. */
+#if 0
if (n_partitions <= 1)
return;
+#endif
/* Create LTRANS partitions. */
ltrans_partitions.create (n_partitions);
@@ -718,7 +724,7 @@ lto_max_no_alonevap_map (void)
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);
}
@@ -1294,11 +1300,17 @@ privatize_symbol_name_1 (symtab_node *node, tree decl)
return false;
name = maybe_rewrite_identifier (name);
- unsigned &clone_number = lto_clone_numbers->get_or_insert (name);
- symtab->change_decl_assembler_name (decl,
- clone_function_name (
- name, "lto_priv", clone_number));
- clone_number++;
+ if (lto_clone_numbers)
+ {
+ unsigned &clone_number = lto_clone_numbers->get_or_insert (name);
+ symtab->change_decl_assembler_name (decl,
+ clone_function_name (
+ name, "lto_priv", clone_number));
+ clone_number++;
+ }
+ else
+ symtab->change_decl_assembler_name (decl, get_file_function_name
+ (node->asm_name ()));
if (node->lto_file_data)
lto_record_renamed_decl (node->lto_file_data, name,