summaryrefslogtreecommitdiff
path: root/gcc/lto/lto.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-20 11:49:31 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2011-10-20 11:49:31 +0000
commitbc2cc717009ffd73f2249d96378847b7c86bd064 (patch)
tree644d8527947266a707ace73a535961b21cadea3f /gcc/lto/lto.c
parent60ac8a3c08cc653bc92507cb1be08ca2ebe6774a (diff)
downloadgcc-bc2cc717009ffd73f2249d96378847b7c86bd064.tar.gz
* lto.c (node_cmp, varpool_node_cmp): New functions.
(lto_balanced_map): Honnor -fno-toplevel-reorder of vars&functions. (cmp_partitions): Rename to ... (cmp_partitions_size): ... this one. (cmp_partitions_order): New function. (lto_wpa_write_files): Sort partitions by order when -fno-toplevel-reorder is used. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@180248 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/lto/lto.c')
-rw-r--r--gcc/lto/lto.c108
1 files changed, 100 insertions, 8 deletions
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 63af047640d..40afc7f1c9b 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -1665,6 +1665,23 @@ lto_1_to_1_map (void)
ltrans_partitions);
}
+/* Helper function for qsort; sort nodes by order. */
+static int
+node_cmp (const void *pa, const void *pb)
+{
+ const struct cgraph_node *a = *(const struct cgraph_node * const *) pa;
+ const struct cgraph_node *b = *(const struct cgraph_node * const *) pb;
+ return b->order - a->order;
+}
+
+/* Helper function for qsort; sort nodes by order. */
+static int
+varpool_node_cmp (const void *pa, const void *pb)
+{
+ const struct varpool_node *a = *(const struct varpool_node * const *) pa;
+ const struct varpool_node *b = *(const struct varpool_node * const *) pb;
+ return b->order - a->order;
+}
/* Group cgraph nodes into equally-sized partitions.
@@ -1708,9 +1725,11 @@ static void
lto_balanced_map (void)
{
int n_nodes = 0;
+ int n_varpool_nodes = 0, varpool_pos = 0;
struct cgraph_node **postorder =
XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
struct cgraph_node **order = XNEWVEC (struct cgraph_node *, cgraph_max_uid);
+ struct varpool_node **varpool_order = NULL;
int i, postorder_len;
struct cgraph_node *node;
int total_size = 0, best_total_size = 0;
@@ -1722,6 +1741,7 @@ lto_balanced_map (void)
int best_n_nodes = 0, best_n_varpool_nodes = 0, best_i = 0, best_cost =
INT_MAX, best_internal = 0;
int npartitions;
+ int current_order = -1;
for (vnode = varpool_nodes; vnode; vnode = vnode->next)
gcc_assert (!vnode->aux);
@@ -1731,6 +1751,7 @@ lto_balanced_map (void)
multiple partitions, this is just an estimate of real size. This is why
we keep partition_size updated after every partition is finalized. */
postorder_len = ipa_reverse_postorder (postorder);
+
for (i = 0; i < postorder_len; i++)
{
node = postorder[i];
@@ -1742,6 +1763,23 @@ lto_balanced_map (void)
}
free (postorder);
+ if (!flag_toplevel_reorder)
+ {
+ qsort (order, n_nodes, sizeof (struct cgraph_node *), node_cmp);
+
+ for (vnode = varpool_nodes; vnode; vnode = vnode->next)
+ if (partition_varpool_node_p (vnode))
+ n_varpool_nodes++;
+ varpool_order = XNEWVEC (struct varpool_node *, n_varpool_nodes);
+
+ n_varpool_nodes = 0;
+ for (vnode = varpool_nodes; vnode; vnode = vnode->next)
+ if (partition_varpool_node_p (vnode))
+ varpool_order[n_varpool_nodes++] = vnode;
+ qsort (varpool_order, n_varpool_nodes, sizeof (struct varpool_node *),
+ varpool_node_cmp);
+ }
+
/* Compute partition size and create the first partition. */
partition_size = total_size / PARAM_VALUE (PARAM_LTO_PARTITIONS);
if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))
@@ -1756,8 +1794,20 @@ lto_balanced_map (void)
{
if (order[i]->aux)
continue;
+
+ current_order = order[i]->order;
+
+ if (!flag_toplevel_reorder)
+ while (varpool_pos < n_varpool_nodes && varpool_order[varpool_pos]->order < current_order)
+ {
+ if (!varpool_order[varpool_pos]->aux)
+ add_varpool_node_to_partition (partition, varpool_order[varpool_pos]);
+ varpool_pos++;
+ }
+
add_cgraph_node_to_partition (partition, order[i]);
total_size -= inline_summary (order[i])->size;
+
/* Once we added a new node to the partition, we also want to add
all referenced variables unless they was already added into some
@@ -1796,7 +1846,7 @@ lto_balanced_map (void)
gcc_assert (node->analyzed);
- /* Compute boundary cost of callgrpah edges. */
+ /* Compute boundary cost of callgraph edges. */
for (edge = node->callees; edge; edge = edge->next_callee)
if (edge->callee->analyzed)
{
@@ -1848,7 +1898,8 @@ lto_balanced_map (void)
vnode = ipa_ref_varpool_node (ref);
if (!vnode->finalized)
continue;
- if (!vnode->aux && partition_varpool_node_p (vnode))
+ if (!vnode->aux && flag_toplevel_reorder
+ && partition_varpool_node_p (vnode))
add_varpool_node_to_partition (partition, vnode);
vsi = varpool_node_set_find (partition->varpool_set, vnode);
if (!vsi_end_p (vsi)
@@ -1878,7 +1929,8 @@ lto_balanced_map (void)
vnode = ipa_ref_refering_varpool_node (ref);
gcc_assert (vnode->finalized);
- if (!vnode->aux && partition_varpool_node_p (vnode))
+ if (!vnode->aux && flag_toplevel_reorder
+ && partition_varpool_node_p (vnode))
add_varpool_node_to_partition (partition, vnode);
vsi = varpool_node_set_find (partition->varpool_set, vnode);
if (!vsi_end_p (vsi)
@@ -1967,9 +2019,22 @@ lto_balanced_map (void)
}
/* Varables that are not reachable from the code go into last partition. */
- for (vnode = varpool_nodes; vnode; vnode = vnode->next)
- if (partition_varpool_node_p (vnode) && !vnode->aux)
- add_varpool_node_to_partition (partition, vnode);
+ if (flag_toplevel_reorder)
+ {
+ for (vnode = varpool_nodes; vnode; vnode = vnode->next)
+ if (partition_varpool_node_p (vnode) && !vnode->aux)
+ add_varpool_node_to_partition (partition, vnode);
+ }
+ else
+ {
+ while (varpool_pos < n_varpool_nodes)
+ {
+ if (!varpool_order[varpool_pos]->aux)
+ add_varpool_node_to_partition (partition, varpool_order[varpool_pos]);
+ varpool_pos++;
+ }
+ free (varpool_order);
+ }
free (order);
}
@@ -2134,7 +2199,7 @@ static lto_file *current_lto_file;
longest compilation being executed too late. */
static int
-cmp_partitions (const void *a, const void *b)
+cmp_partitions_size (const void *a, const void *b)
{
const struct ltrans_partition_def *pa
= *(struct ltrans_partition_def *const *)a;
@@ -2143,6 +2208,28 @@ cmp_partitions (const void *a, const void *b)
return pb->insns - pa->insns;
}
+/* Helper for qsort; compare partitions and return one with smaller order. */
+
+static int
+cmp_partitions_order (const void *a, const void *b)
+{
+ const struct ltrans_partition_def *pa
+ = *(struct ltrans_partition_def *const *)a;
+ const struct ltrans_partition_def *pb
+ = *(struct ltrans_partition_def *const *)b;
+ int ordera = -1, orderb = -1;
+
+ if (VEC_length (cgraph_node_ptr, pa->cgraph_set->nodes))
+ ordera = VEC_index (cgraph_node_ptr, pa->cgraph_set->nodes, 0)->order;
+ else if (VEC_length (varpool_node_ptr, pa->varpool_set->nodes))
+ ordera = VEC_index (varpool_node_ptr, pa->varpool_set->nodes, 0)->order;
+ if (VEC_length (cgraph_node_ptr, pb->cgraph_set->nodes))
+ orderb = VEC_index (cgraph_node_ptr, pb->cgraph_set->nodes, 0)->order;
+ else if (VEC_length (varpool_node_ptr, pb->varpool_set->nodes))
+ orderb = VEC_index (varpool_node_ptr, pb->varpool_set->nodes, 0)->order;
+ return orderb - ordera;
+}
+
/* Write all output files in WPA mode and the file with the list of
LTRANS units. */
@@ -2191,7 +2278,12 @@ lto_wpa_write_files (void)
blen = strlen (temp_filename);
n_sets = VEC_length (ltrans_partition, ltrans_partitions);
- VEC_qsort (ltrans_partition, ltrans_partitions, cmp_partitions);
+
+ /* Sort partitions by size so small ones are compiled last.
+ FIXME: Even when not reordering we may want to output one list for parallel make
+ and other for final link command. */
+ VEC_qsort (ltrans_partition, ltrans_partitions,
+ flag_toplevel_reorder ? cmp_partitions_size : cmp_partitions_order);
for (i = 0; i < n_sets; i++)
{
size_t len;