aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto/lto-partition.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/lto/lto-partition.c')
-rw-r--r--gcc/lto/lto-partition.c112
1 files changed, 71 insertions, 41 deletions
diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c
index 5bd089b..0451a66 100644
--- a/gcc/lto/lto-partition.c
+++ b/gcc/lto/lto-partition.c
@@ -333,7 +333,8 @@ lto_max_map (void)
new_partition ("empty");
}
-/* Helper function for qsort; sort nodes by order. */
+/* Helper function for qsort; sort nodes by order. noreorder functions must have
+ been removed earlier. */
static int
node_cmp (const void *pa, const void *pb)
{
@@ -365,11 +366,26 @@ node_cmp (const void *pa, const void *pb)
static int
varpool_node_cmp (const void *pa, const void *pb)
{
- const varpool_node *a = *(const varpool_node * const *) pa;
- const varpool_node *b = *(const varpool_node * const *) pb;
+ const symtab_node *a = *static_cast<const symtab_node * const *> (pa);
+ const symtab_node *b = *static_cast<const symtab_node * const *> (pb);
return b->order - a->order;
}
+/* Add all symtab nodes from NEXT_NODE to PARTITION in order. */
+
+static void
+add_sorted_nodes (vec<symtab_node *> &next_nodes, ltrans_partition partition)
+{
+ unsigned i;
+ symtab_node *node;
+
+ next_nodes.qsort (varpool_node_cmp);
+ FOR_EACH_VEC_ELT (next_nodes, i, node)
+ if (!symbol_partitioned_p (node))
+ add_symbol_to_partition (partition, node);
+}
+
+
/* Group cgraph nodes into equally-sized partitions.
The partitioning algorithm is simple: nodes are taken in predefined order.
@@ -414,7 +430,8 @@ lto_balanced_map (int n_lto_partitions)
int n_nodes = 0;
int n_varpool_nodes = 0, varpool_pos = 0, best_varpool_pos = 0;
struct cgraph_node **order = XNEWVEC (cgraph_node *, symtab->cgraph_max_uid);
- varpool_node **varpool_order = NULL;
+ auto_vec<cgraph_node *> noreorder;
+ auto_vec<varpool_node *> varpool_order;
int i;
struct cgraph_node *node;
int total_size = 0, best_total_size = 0;
@@ -427,6 +444,7 @@ lto_balanced_map (int n_lto_partitions)
INT_MAX, best_internal = 0;
int npartitions;
int current_order = -1;
+ int noreorder_pos = 0;
FOR_EACH_VARIABLE (vnode)
gcc_assert (!vnode->aux);
@@ -434,7 +452,10 @@ lto_balanced_map (int n_lto_partitions)
FOR_EACH_DEFINED_FUNCTION (node)
if (node->get_partitioning_class () == SYMBOL_PARTITION)
{
- order[n_nodes++] = node;
+ if (node->no_reorder)
+ noreorder.safe_push (node);
+ else
+ order[n_nodes++] = node;
if (!node->alias)
total_size += inline_summary (node)->size;
}
@@ -445,27 +466,26 @@ lto_balanced_map (int n_lto_partitions)
get better about minimizing the function bounday, but until that
things works smoother if we order in source order. */
qsort (order, n_nodes, sizeof (struct cgraph_node *), node_cmp);
+ noreorder.qsort (node_cmp);
if (symtab->dump_file)
- for(i = 0; i < n_nodes; i++)
- fprintf (symtab->dump_file, "Balanced map symbol order:%s:%u\n",
- order[i]->name (), order[i]->tp_first_run);
-
- if (!flag_toplevel_reorder)
{
- FOR_EACH_VARIABLE (vnode)
- if (vnode->get_partitioning_class () == SYMBOL_PARTITION)
- n_varpool_nodes++;
- varpool_order = XNEWVEC (varpool_node *, n_varpool_nodes);
-
- n_varpool_nodes = 0;
- FOR_EACH_VARIABLE (vnode)
- if (vnode->get_partitioning_class () == SYMBOL_PARTITION)
- varpool_order[n_varpool_nodes++] = vnode;
- qsort (varpool_order, n_varpool_nodes, sizeof (varpool_node *),
- varpool_node_cmp);
+ for(i = 0; i < n_nodes; i++)
+ fprintf (symtab->dump_file, "Balanced map symbol order:%s:%u\n",
+ order[i]->name (), order[i]->tp_first_run);
+ for(i = 0; i < (int)noreorder.length(); i++)
+ fprintf (symtab->dump_file, "Balanced map symbol no_reorder:%s:%u\n",
+ noreorder[i]->name (), noreorder[i]->tp_first_run);
}
+ /* Collect all variables that should not be reordered. */
+ FOR_EACH_VARIABLE (vnode)
+ if (vnode->get_partitioning_class () == SYMBOL_PARTITION
+ && (!flag_toplevel_reorder || vnode->no_reorder))
+ varpool_order.safe_push (vnode);
+ n_varpool_nodes = varpool_order.length ();
+ varpool_order.qsort (varpool_node_cmp);
+
/* Compute partition size and create the first partition. */
partition_size = total_size / n_lto_partitions;
if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))
@@ -476,6 +496,8 @@ lto_balanced_map (int n_lto_partitions)
fprintf (symtab->dump_file, "Total unit size: %i, partition size: %i\n",
total_size, partition_size);
+ auto_vec<symtab_node *> next_nodes;
+
for (i = 0; i < n_nodes; i++)
{
if (symbol_partitioned_p (order[i]))
@@ -483,14 +505,19 @@ lto_balanced_map (int n_lto_partitions)
current_order = order[i]->order;
- if (!flag_toplevel_reorder)
- while (varpool_pos < n_varpool_nodes
- && varpool_order[varpool_pos]->order < current_order)
- {
- if (!symbol_partitioned_p (varpool_order[varpool_pos]))
- add_symbol_to_partition (partition, varpool_order[varpool_pos]);
- varpool_pos++;
- }
+ /* Output noreorder and varpool in program order first. */
+ next_nodes.truncate (0);
+ while (varpool_pos < n_varpool_nodes
+ && varpool_order[varpool_pos]->order < current_order)
+ next_nodes.safe_push (varpool_order[varpool_pos++]);
+ while (noreorder_pos < (int)noreorder.length ()
+ && noreorder[noreorder_pos]->order < current_order)
+ {
+ if (!noreorder[noreorder_pos]->alias)
+ total_size -= inline_summary (noreorder[noreorder_pos])->size;
+ next_nodes.safe_push (noreorder[noreorder_pos++]);
+ }
+ add_sorted_nodes (next_nodes, partition);
add_symbol_to_partition (partition, order[i]);
if (!order[i]->alias)
@@ -580,6 +607,7 @@ lto_balanced_map (int n_lto_partitions)
if (!vnode->definition)
continue;
if (!symbol_partitioned_p (vnode) && flag_toplevel_reorder
+ && !vnode->no_reorder
&& vnode->get_partitioning_class () == SYMBOL_PARTITION)
add_symbol_to_partition (partition, vnode);
index = lto_symtab_encoder_lookup (partition->encoder,
@@ -616,6 +644,7 @@ lto_balanced_map (int n_lto_partitions)
to be removed. Coupling with objects they refer to only helps to reduce
number of symbols promoted to hidden. */
if (!symbol_partitioned_p (vnode) && flag_toplevel_reorder
+ && !vnode->no_reorder
&& !vnode->can_remove_if_no_refs_p ()
&& vnode->get_partitioning_class () == SYMBOL_PARTITION)
add_symbol_to_partition (partition, vnode);
@@ -705,24 +734,25 @@ lto_balanced_map (int n_lto_partitions)
}
}
+ next_nodes.truncate (0);
+
/* Varables that are not reachable from the code go into last partition. */
if (flag_toplevel_reorder)
{
FOR_EACH_VARIABLE (vnode)
if (vnode->get_partitioning_class () == SYMBOL_PARTITION
- && !symbol_partitioned_p (vnode))
- add_symbol_to_partition (partition, vnode);
- }
- else
- {
- while (varpool_pos < n_varpool_nodes)
- {
- if (!symbol_partitioned_p (varpool_order[varpool_pos]))
- add_symbol_to_partition (partition, varpool_order[varpool_pos]);
- varpool_pos++;
- }
- free (varpool_order);
+ && !symbol_partitioned_p (vnode)
+ && !vnode->no_reorder)
+ next_nodes.safe_push (vnode);
}
+
+ /* Output remaining ordered symbols. */
+ while (varpool_pos < n_varpool_nodes)
+ next_nodes.safe_push (varpool_order[varpool_pos++]);
+ while (noreorder_pos < (int)noreorder.length ())
+ next_nodes.safe_push (noreorder[noreorder_pos++]);
+ add_sorted_nodes (next_nodes, partition);
+
free (order);
}