re PR ipa/59469 (LLVM build failure with gcc LTO)

PR ipa/59469
	* lto-cgraph.c (lto_output_node): Use
	symtab_get_symbol_partitioning_class.
	(lto_output_varpool_node): likewise.
	(symtab_get_symbol_partitioning_class): Move here from
	lto/lto-partition.c
	* cgraph.h (symbol_partitioning_class): Likewise.
	(symtab_get_symbol_partitioning_class): Declare.

	* lto-partition.c (symbol_class): Move to cgraph.h
	(get_symbol_class): Move to symtab.c
	(add_references_to_partition, add_symbol_to_partition_1,
	lto_max_map, lto_1_to_1_map, lto_balanced_map,
	lto_promote_cross_file_statics): Update.

From-SVN: r207589
This commit is contained in:
Jan Hubicka 2014-02-07 03:27:05 +01:00 committed by Jan Hubicka
parent b3bb0eb9c0
commit 964512791e
4 changed files with 47 additions and 87 deletions

View File

@ -704,6 +704,20 @@ extern GTY(()) struct asm_node *asm_nodes;
extern GTY(()) int symtab_order;
extern bool cpp_implicit_aliases_done;
/* Classifcation of symbols WRT partitioning. */
enum symbol_partitioning_class
{
/* External declarations are ignored by partitioning algorithms and they are
added into the boundary later via compute_ltrans_boundary. */
SYMBOL_EXTERNAL,
/* Partitioned symbols are pur into one of partitions. */
SYMBOL_PARTITION,
/* Duplicated symbols (such as comdat or constant pool references) are
copied into every node needing them via add_symbol_to_partition. */
SYMBOL_DUPLICATE
};
/* In symtab.c */
void symtab_register_node (symtab_node *);
void symtab_unregister_node (symtab_node *);
@ -734,6 +748,7 @@ bool symtab_for_node_and_aliases (symtab_node *,
symtab_node *symtab_nonoverwritable_alias (symtab_node *);
enum availability symtab_node_availability (symtab_node *);
bool symtab_semantically_equivalent_p (symtab_node *, symtab_node *);
enum symbol_partitioning_class symtab_get_symbol_partitioning_class (symtab_node *);
/* In cgraph.c */
void dump_cgraph (FILE *);

View File

@ -417,7 +417,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
Cherry-picked nodes: These are nodes we pulled from other
translation units into SET during IPA-inlining. We make them as
local static nodes to prevent clashes with other local statics. */
if (boundary_p && node->analyzed && !DECL_EXTERNAL (node->decl))
if (boundary_p && node->analyzed
&& symtab_get_symbol_partitioning_class (node) == SYMBOL_PARTITION)
{
/* Inline clones can not be part of boundary.
gcc_assert (!node->global.inlined_to);
@ -501,8 +502,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
bp_pack_value (&bp, node->unique_name, 1);
bp_pack_value (&bp, node->address_taken, 1);
bp_pack_value (&bp, tag == LTO_symtab_analyzed_node
&& !DECL_EXTERNAL (node->decl)
&& !DECL_COMDAT (node->decl)
&& symtab_get_symbol_partitioning_class (node) == SYMBOL_PARTITION
&& (reachable_from_other_partition_p (node, encoder)
|| referenced_from_other_partition_p (&node->ref_list,
encoder)), 1);
@ -569,9 +569,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
/* Constant pool initializers can be de-unified into individual ltrans units.
FIXME: Alternatively at -Os we may want to avoid generating for them the local
labels and share them across LTRANS partitions. */
if (DECL_IN_CONSTANT_POOL (node->decl)
&& !DECL_EXTERNAL (node->decl)
&& !DECL_COMDAT (node->decl))
if (symtab_get_symbol_partitioning_class (node) != SYMBOL_PARTITION)
{
bp_pack_value (&bp, 0, 1); /* used_from_other_parition. */
bp_pack_value (&bp, 0, 1); /* in_other_partition. */

View File

@ -1,3 +1,12 @@
2014-02-06 Jan Hubicka <hubicka@ucw.cz>
PR ipa/59469
* lto-partition.c (symbol_class): Move to cgraph.h
(get_symbol_class): Move to symtab.c
(add_references_to_partition, add_symbol_to_partition_1,
lto_max_map, lto_1_to_1_map, lto_balanced_map,
lto_promote_cross_file_statics): Update.
2014-02-05 Jan Hubicka <hubicka@ucw.cz>
* lto.c (lto_parallelism): New static var.

View File

@ -38,73 +38,10 @@ along with GCC; see the file COPYING3. If not see
#include "ipa-utils.h"
#include "lto-partition.h"
/* Classifcation of symbols into classes WRT partitioning. */
enum symbol_class
{
/* External declarations are ignored by partitioning algorithms and they are
added into the boundary later via compute_ltrans_boundary. */
SYMBOL_EXTERNAL,
/* Partitioned symbols are pur into one of partitions. */
SYMBOL_PARTITION,
/* Duplicated symbols (such as comdat or constant pool references) are
copied into every node needing them via add_symbol_to_partition. */
SYMBOL_DUPLICATE
};
vec<ltrans_partition> ltrans_partitions;
static void add_symbol_to_partition (ltrans_partition part, symtab_node *node);
/* Classify symbol NODE. */
enum symbol_class
get_symbol_class (symtab_node *node)
{
/* Inline clones are always duplicated.
This include external delcarations. */
cgraph_node *cnode = dyn_cast <cgraph_node> (node);
if (DECL_ABSTRACT (node->decl))
return SYMBOL_EXTERNAL;
if (cnode && cnode->global.inlined_to)
return SYMBOL_DUPLICATE;
/* Weakref aliases are always duplicated. */
if (node->weakref)
return SYMBOL_DUPLICATE;
/* External declarations are external. */
if (DECL_EXTERNAL (node->decl))
return SYMBOL_EXTERNAL;
if (varpool_node *vnode = dyn_cast <varpool_node> (node))
{
/* Constant pool references use local symbol names that can not
be promoted global. We should never put into a constant pool
objects that can not be duplicated across partitions. */
if (DECL_IN_CONSTANT_POOL (node->decl))
return SYMBOL_DUPLICATE;
gcc_checking_assert (vnode->definition);
}
/* Functions that are cloned may stay in callgraph even if they are unused.
Handle them as external; compute_ltrans_boundary take care to make
proper things to happen (i.e. to make them appear in the boundary but
with body streamed, so clone can me materialized). */
else if (!cgraph (node)->definition)
return SYMBOL_EXTERNAL;
/* Linker discardable symbols are duplicated to every use unless they are
keyed.
Keyed symbols or those. */
if (DECL_ONE_ONLY (node->decl)
&& !node->force_output
&& !node->forced_by_abi
&& !symtab_used_from_object_file_p (node))
return SYMBOL_DUPLICATE;
return SYMBOL_PARTITION;
}
/* Create new partition with name NAME. */
@ -153,7 +90,7 @@ add_references_to_partition (ltrans_partition part, symtab_node *node)
/* Add all duplicated references to the partition. */
for (i = 0; ipa_ref_list_reference_iterate (&node->ref_list, i, ref); i++)
if (get_symbol_class (ref->referred) == SYMBOL_DUPLICATE)
if (symtab_get_symbol_partitioning_class (ref->referred) == SYMBOL_DUPLICATE)
add_symbol_to_partition (part, ref->referred);
/* References to a readonly variable may be constant foled into its value.
Recursively look into the initializers of the constant variable and add
@ -175,7 +112,7 @@ add_references_to_partition (ltrans_partition part, symtab_node *node)
static bool
add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
{
enum symbol_class c = get_symbol_class (node);
enum symbol_partitioning_class c = symtab_get_symbol_partitioning_class (node);
int i;
struct ipa_ref *ref;
symtab_node *node1;
@ -218,7 +155,7 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
for (e = cnode->callees; e; e = e->next_callee)
if (!e->inline_failed)
add_symbol_to_partition_1 (part, e->callee);
else if (get_symbol_class (e->callee) == SYMBOL_DUPLICATE)
else if (symtab_get_symbol_partitioning_class (e->callee) == SYMBOL_DUPLICATE)
add_symbol_to_partition (part, e->callee);
/* Add all thunks associated with the function. */
@ -238,10 +175,11 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node)
if (node->same_comdat_group)
for (node1 = node->same_comdat_group;
node1 != node; node1 = node1->same_comdat_group)
{
bool added = add_symbol_to_partition_1 (part, node1);
gcc_assert (added);
}
if (!node->alias)
{
bool added = add_symbol_to_partition_1 (part, node1);
gcc_assert (added);
}
return true;
}
@ -276,7 +214,7 @@ add_symbol_to_partition (ltrans_partition part, symtab_node *node)
symtab_node *node1;
/* Verify that we do not try to duplicate something that can not be. */
gcc_checking_assert (get_symbol_class (node) == SYMBOL_DUPLICATE
gcc_checking_assert (symtab_get_symbol_partitioning_class (node) == SYMBOL_DUPLICATE
|| !symbol_partitioned_p (node));
while ((node1 = contained_in_symbol (node)) != node)
@ -289,7 +227,7 @@ add_symbol_to_partition (ltrans_partition part, symtab_node *node)
Be lax about comdats; they may or may not be duplicated and we may
end up in need to duplicate keyed comdat because it has unkeyed alias. */
gcc_assert (get_symbol_class (node) == SYMBOL_DUPLICATE
gcc_assert (symtab_get_symbol_partitioning_class (node) == SYMBOL_DUPLICATE
|| DECL_COMDAT (node->decl)
|| !symbol_partitioned_p (node));
@ -336,7 +274,7 @@ lto_1_to_1_map (void)
FOR_EACH_SYMBOL (node)
{
if (get_symbol_class (node) != SYMBOL_PARTITION
if (symtab_get_symbol_partitioning_class (node) != SYMBOL_PARTITION
|| symbol_partitioned_p (node))
continue;
@ -388,7 +326,7 @@ lto_max_map (void)
FOR_EACH_SYMBOL (node)
{
if (get_symbol_class (node) != SYMBOL_PARTITION
if (symtab_get_symbol_partitioning_class (node) != SYMBOL_PARTITION
|| symbol_partitioned_p (node))
continue;
partition = new_partition (node->asm_name ());
@ -498,7 +436,7 @@ lto_balanced_map (void)
gcc_assert (!vnode->aux);
FOR_EACH_DEFINED_FUNCTION (node)
if (get_symbol_class (node) == SYMBOL_PARTITION)
if (symtab_get_symbol_partitioning_class (node) == SYMBOL_PARTITION)
{
order[n_nodes++] = node;
total_size += inline_summary (node)->size;
@ -518,13 +456,13 @@ lto_balanced_map (void)
if (!flag_toplevel_reorder)
{
FOR_EACH_VARIABLE (vnode)
if (get_symbol_class (vnode) == SYMBOL_PARTITION)
if (symtab_get_symbol_partitioning_class (vnode) == SYMBOL_PARTITION)
n_varpool_nodes++;
varpool_order = XNEWVEC (varpool_node *, n_varpool_nodes);
n_varpool_nodes = 0;
FOR_EACH_VARIABLE (vnode)
if (get_symbol_class (vnode) == SYMBOL_PARTITION)
if (symtab_get_symbol_partitioning_class (vnode) == SYMBOL_PARTITION)
varpool_order[n_varpool_nodes++] = vnode;
qsort (varpool_order, n_varpool_nodes, sizeof (varpool_node *),
varpool_node_cmp);
@ -643,7 +581,7 @@ lto_balanced_map (void)
if (!vnode->definition)
continue;
if (!symbol_partitioned_p (vnode) && flag_toplevel_reorder
&& get_symbol_class (vnode) == SYMBOL_PARTITION)
&& symtab_get_symbol_partitioning_class (vnode) == SYMBOL_PARTITION)
add_symbol_to_partition (partition, vnode);
index = lto_symtab_encoder_lookup (partition->encoder,
vnode);
@ -676,7 +614,7 @@ lto_balanced_map (void)
vnode = ipa_ref_referring_varpool_node (ref);
gcc_assert (vnode->definition);
if (!symbol_partitioned_p (vnode) && flag_toplevel_reorder
&& get_symbol_class (vnode) == SYMBOL_PARTITION)
&& symtab_get_symbol_partitioning_class (vnode) == SYMBOL_PARTITION)
add_symbol_to_partition (partition, vnode);
index = lto_symtab_encoder_lookup (partition->encoder,
vnode);
@ -769,7 +707,7 @@ lto_balanced_map (void)
if (flag_toplevel_reorder)
{
FOR_EACH_VARIABLE (vnode)
if (get_symbol_class (vnode) == SYMBOL_PARTITION
if (symtab_get_symbol_partitioning_class (vnode) == SYMBOL_PARTITION
&& !symbol_partitioned_p (vnode))
add_symbol_to_partition (partition, vnode);
}
@ -979,7 +917,7 @@ lto_promote_cross_file_statics (void)
|| lto_symtab_encoder_in_partition_p (encoder, node)
/* ... or if we do not partition it. This mean that it will
appear in every partition refernecing it. */
|| get_symbol_class (node) != SYMBOL_PARTITION)
|| symtab_get_symbol_partitioning_class (node) != SYMBOL_PARTITION)
continue;
promote_symbol (node);