Commit b4661bfe by Jan Hubicka Committed by Jan Hubicka

passes.c (ipa_write_summaries_1): Set state; do not call compute_ltrans_boundary.



	* passes.c (ipa_write_summaries_1): Set state;
	do not call compute_ltrans_boundary.
	(ipa_write_optimization_summaries): Likewise.
	(ipa_write_summaries): compute_ltrans_boundary here.
	* lto-streamer.h (lto_symtab_encoder_d): NODES are allocated in heap.
	(compute_ltrans_boundary): Update prototype.

	* lto.c (lto_wpa_write_files): Do not delete partition encoder;
	it is deleted after streaming.
	* lto-partition.c (partition_symbol_p): New function.
	(promote_var, promote_fn): Remove.
	(promote_symbol): New function.
	(lto_promote_cross_file_statics): First compute boundaries; rewrite
	to lookup the actual boundaries instead of computing them ad-hoc.

From-SVN: r191113
parent 3ca6351d
2012-09-09 Jan Hubicka <jh@suse.cz>
* passes.c (ipa_write_summaries_1): Set state;
do not call compute_ltrans_boundary.
(ipa_write_optimization_summaries): Likewise.
(ipa_write_summaries): compute_ltrans_boundary here.
* lto-streamer.h (lto_symtab_encoder_d): NODES are allocated in heap.
(compute_ltrans_boundary): Update prototype.
2012-09-09 Ulrich Drepper <drepper@gmail.com> 2012-09-09 Ulrich Drepper <drepper@gmail.com>
* config/i386/cpuid.h: Define signature_*_e[bcd]x macros for * config/i386/cpuid.h: Define signature_*_e[bcd]x macros for
......
...@@ -588,38 +588,6 @@ output_profile_summary (struct lto_simple_output_block *ob) ...@@ -588,38 +588,6 @@ output_profile_summary (struct lto_simple_output_block *ob)
streamer_write_uhwi_stream (ob->main_stream, 0); streamer_write_uhwi_stream (ob->main_stream, 0);
} }
/* Add NODE into encoder as well as nodes it is cloned from.
Do it in a way so clones appear first. */
static void
add_node_to (lto_symtab_encoder_t encoder, struct cgraph_node *node,
bool include_body)
{
if (node->clone_of)
add_node_to (encoder, node->clone_of, include_body);
else if (include_body)
lto_set_symtab_encoder_encode_body (encoder, node);
lto_symtab_encoder_encode (encoder, (symtab_node)node);
}
/* Add all references in LIST to encoders. */
static void
add_references (lto_symtab_encoder_t encoder,
struct ipa_ref_list *list)
{
int i;
struct ipa_ref *ref;
for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
if (symtab_function_p (ref->referred))
add_node_to (encoder, ipa_ref_node (ref), false);
else
{
struct varpool_node *vnode = ipa_ref_varpool_node (ref);
lto_symtab_encoder_encode (encoder, (symtab_node)vnode);
}
}
/* Output all callees or indirect outgoing edges. EDGE must be the first such /* Output all callees or indirect outgoing edges. EDGE must be the first such
edge. */ edge. */
...@@ -674,11 +642,48 @@ output_refs (lto_symtab_encoder_t encoder) ...@@ -674,11 +642,48 @@ output_refs (lto_symtab_encoder_t encoder)
lto_destroy_simple_output_block (ob); lto_destroy_simple_output_block (ob);
} }
/* Find out all cgraph and varpool nodes we want to encode in current unit /* Add NODE into encoder as well as nodes it is cloned from.
and insert them to encoders. */ Do it in a way so clones appear first. */
void
compute_ltrans_boundary (struct lto_out_decl_state *state, static void
lto_symtab_encoder_t in_encoder) add_node_to (lto_symtab_encoder_t encoder, struct cgraph_node *node,
bool include_body)
{
if (node->clone_of)
add_node_to (encoder, node->clone_of, include_body);
else if (include_body)
lto_set_symtab_encoder_encode_body (encoder, node);
lto_symtab_encoder_encode (encoder, (symtab_node)node);
}
/* Add all references in LIST to encoders. */
static void
add_references (lto_symtab_encoder_t encoder,
struct ipa_ref_list *list)
{
int i;
struct ipa_ref *ref;
for (i = 0; ipa_ref_list_reference_iterate (list, i, ref); i++)
if (symtab_function_p (ref->referred))
add_node_to (encoder, ipa_ref_node (ref), false);
else
{
struct varpool_node *vnode = ipa_ref_varpool_node (ref);
lto_symtab_encoder_encode (encoder, (symtab_node)vnode);
}
}
/* Find all symbols we want to stream into given partition and insert them
to encoders.
The function actually replaces IN_ENCODER by new one. The reason is that
streaming code needs clone's origin to be streamed before clone. This
means that we need to insert the nodes in specific order. This order is
ignored by the partitioning logic earlier. */
lto_symtab_encoder_t
compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
{ {
struct cgraph_node *node; struct cgraph_node *node;
struct cgraph_edge *edge; struct cgraph_edge *edge;
...@@ -686,7 +691,7 @@ compute_ltrans_boundary (struct lto_out_decl_state *state, ...@@ -686,7 +691,7 @@ compute_ltrans_boundary (struct lto_out_decl_state *state,
lto_symtab_encoder_t encoder; lto_symtab_encoder_t encoder;
lto_symtab_encoder_iterator lsei; lto_symtab_encoder_iterator lsei;
encoder = state->symtab_node_encoder = lto_symtab_encoder_new (); encoder = lto_symtab_encoder_new ();
/* Go over all entries in the IN_ENCODER and duplicate them to /* Go over all entries in the IN_ENCODER and duplicate them to
ENCODER. At the same time insert masters of clones so ENCODER. At the same time insert masters of clones so
...@@ -747,6 +752,8 @@ compute_ltrans_boundary (struct lto_out_decl_state *state, ...@@ -747,6 +752,8 @@ compute_ltrans_boundary (struct lto_out_decl_state *state,
} }
} }
} }
lto_symtab_encoder_delete (in_encoder);
return encoder;
} }
/* Output the part of the symtab in SET and VSET. */ /* Output the part of the symtab in SET and VSET. */
......
...@@ -441,7 +441,7 @@ DEF_VEC_ALLOC_O(lto_encoder_entry, heap); ...@@ -441,7 +441,7 @@ DEF_VEC_ALLOC_O(lto_encoder_entry, heap);
/* Encoder data structure used to stream callgraph nodes. */ /* Encoder data structure used to stream callgraph nodes. */
struct lto_symtab_encoder_d struct lto_symtab_encoder_d
{ {
VEC(lto_encoder_entry,gc) *nodes; VEC(lto_encoder_entry,heap) *nodes;
pointer_map_t *map; pointer_map_t *map;
}; };
...@@ -856,8 +856,7 @@ bool referenced_from_this_partition_p (struct ipa_ref_list *, ...@@ -856,8 +856,7 @@ bool referenced_from_this_partition_p (struct ipa_ref_list *,
lto_symtab_encoder_t); lto_symtab_encoder_t);
bool reachable_from_this_partition_p (struct cgraph_node *, bool reachable_from_this_partition_p (struct cgraph_node *,
lto_symtab_encoder_t); lto_symtab_encoder_t);
void compute_ltrans_boundary (struct lto_out_decl_state *state, lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
lto_symtab_encoder_t encoder);
/* In lto-symtab.c. */ /* In lto-symtab.c. */
......
2012-08-12 Jan Hubicka <jh@suse.cz> 2012-08-12 Jan Hubicka <jh@suse.cz>
* lto.c (lto_wpa_write_files): Do not delete partition encoder;
it is deleted after streaming.
* lto-partition.c (partition_symbol_p): New function.
(promote_var, promote_fn): Remove.
(promote_symbol): New function.
(lto_promote_cross_file_statics): First compute boundaries; rewrite
to lookup the actual boundaries instead of computing them ad-hoc.
2012-08-12 Jan Hubicka <jh@suse.cz>
Replace cgraph_node_set and varpool_node_set by symtab_node_encoder Replace cgraph_node_set and varpool_node_set by symtab_node_encoder
in partitioning. in partitioning.
* lto-partition.h (ltrans_partition_def): Replace cgraph_set and varpool_set * lto-partition.h (ltrans_partition_def): Replace cgraph_set and varpool_set
......
...@@ -280,6 +280,18 @@ partition_varpool_node_p (struct varpool_node *vnode) ...@@ -280,6 +280,18 @@ partition_varpool_node_p (struct varpool_node *vnode)
return true; return true;
} }
/* Return true if NODE should be partitioned.
This means that partitioning algorithm should put NODE into one of partitions. */
static bool
partition_symbol_p (symtab_node node)
{
if (symtab_function_p (node))
return partition_cgraph_node_p (cgraph (node));
else
return partition_varpool_node_p (varpool (node));
}
/* Group cgrah nodes by input files. This is used mainly for testing /* Group cgrah nodes by input files. This is used mainly for testing
right now. */ right now. */
...@@ -739,39 +751,26 @@ lto_balanced_map (void) ...@@ -739,39 +751,26 @@ lto_balanced_map (void)
/* Promote variable VNODE to be static. */ /* Promote variable VNODE to be static. */
static bool static void
promote_var (struct varpool_node *vnode) promote_symbol (symtab_node node)
{ {
if (TREE_PUBLIC (vnode->symbol.decl) || DECL_EXTERNAL (vnode->symbol.decl)) /* We already promoted ... */
return false; if (DECL_VISIBILITY (node->symbol.decl) == VISIBILITY_HIDDEN
gcc_assert (flag_wpa); && DECL_VISIBILITY_SPECIFIED (node->symbol.decl)
TREE_PUBLIC (vnode->symbol.decl) = 1; && TREE_PUBLIC (node->symbol.decl))
DECL_VISIBILITY (vnode->symbol.decl) = VISIBILITY_HIDDEN; return;
DECL_VISIBILITY_SPECIFIED (vnode->symbol.decl) = true;
if (cgraph_dump_file)
fprintf (cgraph_dump_file,
"Promoting var as hidden: %s\n", varpool_node_name (vnode));
return true;
}
/* Promote function NODE to be static. */
static bool gcc_checking_assert (!TREE_PUBLIC (node->symbol.decl)
promote_fn (struct cgraph_node *node) && !DECL_EXTERNAL (node->symbol.decl));
{
gcc_assert (flag_wpa);
if (TREE_PUBLIC (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl))
return false;
TREE_PUBLIC (node->symbol.decl) = 1; TREE_PUBLIC (node->symbol.decl) = 1;
DECL_VISIBILITY (node->symbol.decl) = VISIBILITY_HIDDEN; DECL_VISIBILITY (node->symbol.decl) = VISIBILITY_HIDDEN;
DECL_VISIBILITY_SPECIFIED (node->symbol.decl) = true; DECL_VISIBILITY_SPECIFIED (node->symbol.decl) = true;
if (cgraph_dump_file) if (cgraph_dump_file)
fprintf (cgraph_dump_file, fprintf (cgraph_dump_file,
"Promoting function as hidden: %s/%i\n", "Promoting as hidden: %s\n", symtab_node_name (node));
cgraph_node_name (node), node->uid);
return true;
} }
/* Find out all static decls that need to be promoted to global because /* Find out all static decls that need to be promoted to global because
of cross file sharing. This function must be run in the WPA mode after of cross file sharing. This function must be run in the WPA mode after
all inlinees are added. */ all inlinees are added. */
...@@ -779,118 +778,43 @@ promote_fn (struct cgraph_node *node) ...@@ -779,118 +778,43 @@ promote_fn (struct cgraph_node *node)
void void
lto_promote_cross_file_statics (void) lto_promote_cross_file_statics (void)
{ {
struct varpool_node *vnode;
unsigned i, n_sets; unsigned i, n_sets;
VEC(varpool_node_ptr, heap) *promoted_initializers = NULL;
struct pointer_set_t *inserted = pointer_set_create ();
lto_symtab_encoder_iterator lsei;
lto_symtab_encoder_t encoder;
gcc_assert (flag_wpa); gcc_assert (flag_wpa);
/* First compute boundaries. */
n_sets = VEC_length (ltrans_partition, ltrans_partitions); n_sets = VEC_length (ltrans_partition, ltrans_partitions);
for (i = 0; i < n_sets; i++) for (i = 0; i < n_sets; i++)
{ {
ltrans_partition part ltrans_partition part
= VEC_index (ltrans_partition, ltrans_partitions, i); = VEC_index (ltrans_partition, ltrans_partitions, i);
encoder = part->encoder; part->encoder = compute_ltrans_boundary (part->encoder);
}
/* If node called or referred to from other partition, it needs to be
globalized. */
for (lsei = lsei_start_in_partition (encoder); !lsei_end_p (lsei);
lsei_next_in_partition (&lsei))
{
symtab_node node = lsei_node (lsei);
if (node->symbol.externally_visible)
continue;
if (symtab_function_p (node))
{
struct cgraph_node *cnode = cgraph (node);
if (partition_cgraph_node_p (cnode)
&& (referenced_from_other_partition_p (&cnode->symbol.ref_list, encoder)
|| reachable_from_other_partition_p (cnode, encoder)))
promote_fn (cnode);
}
else if (symtab_variable_p (node))
{
vnode = varpool (node);
/* Constant pool references use internal labels and thus can not
be made global. It is sensible to keep those ltrans local to
allow better optimization. */
if (partition_varpool_node_p (vnode)
&& referenced_from_other_partition_p (&vnode->symbol.ref_list,
encoder))
promote_var (vnode);
}
else
gcc_unreachable ();
}
/* We export the initializer of a read-only var into each partition /* Look at boundaries and promote symbols as needed. */
referencing the var. Folding might take declarations from the for (i = 0; i < n_sets; i++)
initializer and use them, so everything referenced from the {
initializer can be accessed from this partition after folding. lto_symtab_encoder_iterator lsei;
lto_symtab_encoder_t encoder;
ltrans_partition part
= VEC_index (ltrans_partition, ltrans_partitions, i);
This means that we need to promote all variables and functions encoder = part->encoder;
referenced from all initializers of read-only vars referenced for (lsei = lsei_start (encoder); !lsei_end_p (lsei);
from this partition that are not in this partition. This needs lsei_next (&lsei))
to be done recursively. */ {
FOR_EACH_VARIABLE (vnode) symtab_node node = lsei_node (lsei);
if (const_value_known_p (vnode->symbol.decl)
&& DECL_INITIAL (vnode->symbol.decl) /* No need to promote if symbol already is externally visible ... */
&& !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)vnode) if (node->symbol.externally_visible
&& referenced_from_this_partition_p (&vnode->symbol.ref_list, encoder) /* ... or if it is part of current partition ... */
&& !pointer_set_insert (inserted, vnode)) || lto_symtab_encoder_in_partition_p (encoder, node)
VEC_safe_push (varpool_node_ptr, heap, promoted_initializers, vnode); /* ... or if we do not partition it. This mean that it will
appear in every partition refernecing it. */
while (!VEC_empty (varpool_node_ptr, promoted_initializers)) || !partition_symbol_p (node))
{ continue;
int i;
struct ipa_ref *ref;
vnode = VEC_pop (varpool_node_ptr, promoted_initializers); promote_symbol (node);
for (i = 0; }
ipa_ref_list_reference_iterate (&vnode->symbol.ref_list, i, ref);
i++)
{
if (symtab_function_p (ref->referred))
{
struct cgraph_node *n = ipa_ref_node (ref);
gcc_assert (!n->global.inlined_to);
if (!n->symbol.externally_visible
&& !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)n))
promote_fn (n);
}
else
{
struct varpool_node *v = ipa_ref_varpool_node (ref);
if (lto_symtab_encoder_in_partition_p (encoder, (symtab_node)v))
continue;
/* Constant pool references use internal labels and thus
cannot be made global. It is sensible to keep those
ltrans local to allow better optimization.
Similarly we ship external vars initializers into
every ltrans unit possibly referring to it. */
if (DECL_IN_CONSTANT_POOL (v->symbol.decl)
|| DECL_EXTERNAL (v->symbol.decl))
{
if (!pointer_set_insert (inserted, vnode))
VEC_safe_push (varpool_node_ptr, heap,
promoted_initializers, v);
}
else if (!v->symbol.externally_visible && v->analyzed)
{
if (promote_var (v)
&& DECL_INITIAL (v->symbol.decl)
&& const_value_known_p (v->symbol.decl)
&& !pointer_set_insert (inserted, vnode))
VEC_safe_push (varpool_node_ptr, heap,
promoted_initializers, v);
}
}
}
}
} }
pointer_set_destroy (inserted);
} }
...@@ -1514,7 +1514,6 @@ lto_wpa_write_files (void) ...@@ -1514,7 +1514,6 @@ lto_wpa_write_files (void)
lto_set_current_out_file (NULL); lto_set_current_out_file (NULL);
lto_obj_file_close (file); lto_obj_file_close (file);
lto_symtab_encoder_delete (part->encoder);
part->encoder = NULL; part->encoder = NULL;
len = strlen (temp_filename); len = strlen (temp_filename);
......
...@@ -2264,7 +2264,7 @@ static void ...@@ -2264,7 +2264,7 @@ static void
ipa_write_summaries_1 (lto_symtab_encoder_t encoder) ipa_write_summaries_1 (lto_symtab_encoder_t encoder)
{ {
struct lto_out_decl_state *state = lto_new_out_decl_state (); struct lto_out_decl_state *state = lto_new_out_decl_state ();
compute_ltrans_boundary (state, encoder); state->symtab_node_encoder = encoder;
lto_push_out_decl_state (state); lto_push_out_decl_state (state);
...@@ -2324,7 +2324,7 @@ ipa_write_summaries (void) ...@@ -2324,7 +2324,7 @@ ipa_write_summaries (void)
if ((!vnode->alias || vnode->alias_of)) if ((!vnode->alias || vnode->alias_of))
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode); lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
ipa_write_summaries_1 (encoder); ipa_write_summaries_1 (compute_ltrans_boundary (encoder));
free (order); free (order);
} }
...@@ -2376,7 +2376,7 @@ ipa_write_optimization_summaries (lto_symtab_encoder_t encoder) ...@@ -2376,7 +2376,7 @@ ipa_write_optimization_summaries (lto_symtab_encoder_t encoder)
{ {
struct lto_out_decl_state *state = lto_new_out_decl_state (); struct lto_out_decl_state *state = lto_new_out_decl_state ();
lto_symtab_encoder_iterator lsei; lto_symtab_encoder_iterator lsei;
compute_ltrans_boundary (state, encoder); state->symtab_node_encoder = encoder;
lto_push_out_decl_state (state); lto_push_out_decl_state (state);
for (lsei = lsei_start_function_in_partition (encoder); for (lsei = lsei_start_function_in_partition (encoder);
......
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