Commit 51973b1e by Jan Hubicka Committed by Jan Hubicka

lto.c (node_cmp, [...]): New functions.


	* 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.

From-SVN: r180248
parent 8ec802d7
2011-10-09 Jan Hubicka <jh@suse.cz>
* 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.
2011-10-09 Andi Kleen <ak@linux.intel.com> 2011-10-09 Andi Kleen <ak@linux.intel.com>
* lto.c (lto_section_read): Call fatal_error on IO or mmap errors. * lto.c (lto_section_read): Call fatal_error on IO or mmap errors.
......
...@@ -1665,6 +1665,23 @@ lto_1_to_1_map (void) ...@@ -1665,6 +1665,23 @@ lto_1_to_1_map (void)
ltrans_partitions); 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. /* Group cgraph nodes into equally-sized partitions.
...@@ -1708,9 +1725,11 @@ static void ...@@ -1708,9 +1725,11 @@ static void
lto_balanced_map (void) lto_balanced_map (void)
{ {
int n_nodes = 0; int n_nodes = 0;
int n_varpool_nodes = 0, varpool_pos = 0;
struct cgraph_node **postorder = struct cgraph_node **postorder =
XCNEWVEC (struct cgraph_node *, cgraph_n_nodes); XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
struct cgraph_node **order = XNEWVEC (struct cgraph_node *, cgraph_max_uid); struct cgraph_node **order = XNEWVEC (struct cgraph_node *, cgraph_max_uid);
struct varpool_node **varpool_order = NULL;
int i, postorder_len; int i, postorder_len;
struct cgraph_node *node; struct cgraph_node *node;
int total_size = 0, best_total_size = 0; int total_size = 0, best_total_size = 0;
...@@ -1722,6 +1741,7 @@ lto_balanced_map (void) ...@@ -1722,6 +1741,7 @@ lto_balanced_map (void)
int best_n_nodes = 0, best_n_varpool_nodes = 0, best_i = 0, best_cost = int best_n_nodes = 0, best_n_varpool_nodes = 0, best_i = 0, best_cost =
INT_MAX, best_internal = 0; INT_MAX, best_internal = 0;
int npartitions; int npartitions;
int current_order = -1;
for (vnode = varpool_nodes; vnode; vnode = vnode->next) for (vnode = varpool_nodes; vnode; vnode = vnode->next)
gcc_assert (!vnode->aux); gcc_assert (!vnode->aux);
...@@ -1731,6 +1751,7 @@ lto_balanced_map (void) ...@@ -1731,6 +1751,7 @@ lto_balanced_map (void)
multiple partitions, this is just an estimate of real size. This is why multiple partitions, this is just an estimate of real size. This is why
we keep partition_size updated after every partition is finalized. */ we keep partition_size updated after every partition is finalized. */
postorder_len = ipa_reverse_postorder (postorder); postorder_len = ipa_reverse_postorder (postorder);
for (i = 0; i < postorder_len; i++) for (i = 0; i < postorder_len; i++)
{ {
node = postorder[i]; node = postorder[i];
...@@ -1742,6 +1763,23 @@ lto_balanced_map (void) ...@@ -1742,6 +1763,23 @@ lto_balanced_map (void)
} }
free (postorder); 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. */ /* Compute partition size and create the first partition. */
partition_size = total_size / PARAM_VALUE (PARAM_LTO_PARTITIONS); partition_size = total_size / PARAM_VALUE (PARAM_LTO_PARTITIONS);
if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE)) if (partition_size < PARAM_VALUE (MIN_PARTITION_SIZE))
...@@ -1756,8 +1794,20 @@ lto_balanced_map (void) ...@@ -1756,8 +1794,20 @@ lto_balanced_map (void)
{ {
if (order[i]->aux) if (order[i]->aux)
continue; 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]); add_cgraph_node_to_partition (partition, order[i]);
total_size -= inline_summary (order[i])->size; total_size -= inline_summary (order[i])->size;
/* Once we added a new node to the partition, we also want to add /* Once we added a new node to the partition, we also want to add
all referenced variables unless they was already added into some all referenced variables unless they was already added into some
...@@ -1796,7 +1846,7 @@ lto_balanced_map (void) ...@@ -1796,7 +1846,7 @@ lto_balanced_map (void)
gcc_assert (node->analyzed); 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) for (edge = node->callees; edge; edge = edge->next_callee)
if (edge->callee->analyzed) if (edge->callee->analyzed)
{ {
...@@ -1848,7 +1898,8 @@ lto_balanced_map (void) ...@@ -1848,7 +1898,8 @@ lto_balanced_map (void)
vnode = ipa_ref_varpool_node (ref); vnode = ipa_ref_varpool_node (ref);
if (!vnode->finalized) if (!vnode->finalized)
continue; 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); add_varpool_node_to_partition (partition, vnode);
vsi = varpool_node_set_find (partition->varpool_set, vnode); vsi = varpool_node_set_find (partition->varpool_set, vnode);
if (!vsi_end_p (vsi) if (!vsi_end_p (vsi)
...@@ -1878,7 +1929,8 @@ lto_balanced_map (void) ...@@ -1878,7 +1929,8 @@ lto_balanced_map (void)
vnode = ipa_ref_refering_varpool_node (ref); vnode = ipa_ref_refering_varpool_node (ref);
gcc_assert (vnode->finalized); 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); add_varpool_node_to_partition (partition, vnode);
vsi = varpool_node_set_find (partition->varpool_set, vnode); vsi = varpool_node_set_find (partition->varpool_set, vnode);
if (!vsi_end_p (vsi) if (!vsi_end_p (vsi)
...@@ -1967,9 +2019,22 @@ lto_balanced_map (void) ...@@ -1967,9 +2019,22 @@ lto_balanced_map (void)
} }
/* Varables that are not reachable from the code go into last partition. */ /* Varables that are not reachable from the code go into last partition. */
for (vnode = varpool_nodes; vnode; vnode = vnode->next) if (flag_toplevel_reorder)
if (partition_varpool_node_p (vnode) && !vnode->aux) {
add_varpool_node_to_partition (partition, vnode); 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); free (order);
} }
...@@ -2134,7 +2199,7 @@ static lto_file *current_lto_file; ...@@ -2134,7 +2199,7 @@ static lto_file *current_lto_file;
longest compilation being executed too late. */ longest compilation being executed too late. */
static int 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 const struct ltrans_partition_def *pa
= *(struct ltrans_partition_def *const *)a; = *(struct ltrans_partition_def *const *)a;
...@@ -2143,6 +2208,28 @@ cmp_partitions (const void *a, const void *b) ...@@ -2143,6 +2208,28 @@ cmp_partitions (const void *a, const void *b)
return pb->insns - pa->insns; 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 /* Write all output files in WPA mode and the file with the list of
LTRANS units. */ LTRANS units. */
...@@ -2191,7 +2278,12 @@ lto_wpa_write_files (void) ...@@ -2191,7 +2278,12 @@ lto_wpa_write_files (void)
blen = strlen (temp_filename); blen = strlen (temp_filename);
n_sets = VEC_length (ltrans_partition, ltrans_partitions); 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++) for (i = 0; i < n_sets; i++)
{ {
size_t len; size_t len;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment