lto-symtab.c (lto_cgraph_replace_node): Assert that inline clones has no address taken.

* lto-symtab.c (lto_cgraph_replace_node): Assert that inline clones has
	no address taken.
	* cgraph.c (cgraph_mark_needed_node): Assert that inline clones are
	never needed.
	(cgraph_clone_node): Clear externally_visible flag for clones.
	* cgraph.h (cgraph_only_called_directly_p,
	cgraph_can_remove_if_no_direct_calls_p): New predicates.
	* tree-pass.h (pass_ipa_whole_program_visibility): Declare.
	* ipa-cp.c (ipcp_cloning_candidate_p): Use new predicate.
	(ipcp_initialize_node_lattices, ipcp_estimate_growth,
	ipcp_insert_stage): Likwise.
	* cgraphunit.c (cgraph_decide_is_function_needed): Do not compute
	externally_visible flag.
	(verify_cgraph_node): Verify that inline clones look right.
	(process_function_and_variable_attributes): Do not set
	externally_visible flags.
	(ipa_passes): Avoid executing small_ipa_passes at LTO stage; they've
	been already run.
	* lto-cgraph.c (lto_output_node): Assert that inline clones are not
	boundaries.
	* ipa-inline.c (cgraph_clone_inlined_nodes): Use new predicates;
	clear externally_visible when turning into inline clones
	(cgraph_mark_inline_edge): Use new predicates.
	(cgraph_estimate_growth): Likewise.
	(cgraph_decide_inlining): Likewise.
	* ipa.c (cgraph_postorder): Likewise.
	(cgraph_remove_unreachable_nodes): Likewise; sanity check
	that inline clones are not needed.
	(cgraph_externally_visible_p): New predicate.
	(function_and_variable_visibility): Add whole_program parameter;
	always set externally_visible flag; handle COMDAT function
	privatization.
	(local_function_and_variable_visibility): New function.
	(gate_whole_program_function_and_variable_visibility): New function.
	(whole_program_function_and_variable_visibility): New function.
	(pass_ipa_whole_program_visibility): New function.
	* passes.c  (init_optimization_passes): Add whole program visibility
	pass.
	(do_per_function_toporder, function_called_by_processed_nodes_p): Do
	not care about needed/reachable flags.
	* varpool.c: Include flags.h
	(decide_is_variable_needed): When doing LTO assume whole-program mode.
	(varpool_finalize_decl): When we are in LTO read-back, all variables
	are analyzed.
	(varpool_analyze_pending_decls): Skip analyzis of analyzed vars.

	* lto/lto.c (read_cgraph_and_symbols): Mark functions neccesary only at
	ltrans stage; explain why this is needed and should not.

From-SVN: r152520
This commit is contained in:
Jan Hubicka 2009-10-07 11:01:16 +02:00 committed by Jan Hubicka
parent d2d9ce5edc
commit b20996ff13
14 changed files with 269 additions and 58 deletions

View File

@ -1,3 +1,51 @@
2009-10-07 Jan Hubicka <jh@suse.cz>
* lto-symtab.c (lto_cgraph_replace_node): Assert that inline clones has
no address taken.
* cgraph.c (cgraph_mark_needed_node): Assert that inline clones are
never needed.
(cgraph_clone_node): Clear externally_visible flag for clones.
* cgraph.h (cgraph_only_called_directly_p,
cgraph_can_remove_if_no_direct_calls_p): New predicates.
* tree-pass.h (pass_ipa_whole_program_visibility): Declare.
* ipa-cp.c (ipcp_cloning_candidate_p): Use new predicate.
(ipcp_initialize_node_lattices, ipcp_estimate_growth,
ipcp_insert_stage): Likwise.
* cgraphunit.c (cgraph_decide_is_function_needed): Do not compute
externally_visible flag.
(verify_cgraph_node): Verify that inline clones look right.
(process_function_and_variable_attributes): Do not set
externally_visible flags.
(ipa_passes): Avoid executing small_ipa_passes at LTO stage; they've
been already run.
* lto-cgraph.c (lto_output_node): Assert that inline clones are not
boundaries.
* ipa-inline.c (cgraph_clone_inlined_nodes): Use new predicates;
clear externally_visible when turning into inline clones
(cgraph_mark_inline_edge): Use new predicates.
(cgraph_estimate_growth): Likewise.
(cgraph_decide_inlining): Likewise.
* ipa.c (cgraph_postorder): Likewise.
(cgraph_remove_unreachable_nodes): Likewise; sanity check
that inline clones are not needed.
(cgraph_externally_visible_p): New predicate.
(function_and_variable_visibility): Add whole_program parameter;
always set externally_visible flag; handle COMDAT function
privatization.
(local_function_and_variable_visibility): New function.
(gate_whole_program_function_and_variable_visibility): New function.
(whole_program_function_and_variable_visibility): New function.
(pass_ipa_whole_program_visibility): New function.
* passes.c (init_optimization_passes): Add whole program visibility
pass.
(do_per_function_toporder, function_called_by_processed_nodes_p): Do
not care about needed/reachable flags.
* varpool.c: Include flags.h
(decide_is_variable_needed): When doing LTO assume whole-program mode.
(varpool_finalize_decl): When we are in LTO read-back, all variables
are analyzed.
(varpool_analyze_pending_decls): Skip analyzis of analyzed vars.
2009-10-07 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* config/s390/tpf.h (TARGET_DEFAULT): Remove MASK_HARD_FLOAT and

View File

@ -1359,6 +1359,7 @@ void
cgraph_mark_needed_node (struct cgraph_node *node)
{
node->needed = 1;
gcc_assert (!node->global.inlined_to);
cgraph_mark_reachable_node (node);
}
@ -1682,6 +1683,7 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq,
}
new_node->analyzed = n->analyzed;
new_node->local = n->local;
new_node->local.externally_visible = false;
new_node->global = n->global;
new_node->rtl = n->rtl;
new_node->count = count;

View File

@ -658,6 +658,26 @@ struct GTY(()) constant_descriptor_tree {
hashval_t hash;
};
/* Return true when function NODE is only called directly.
i.e. it is not externally visible, address was not taken and
it is not used in any other non-standard way. */
static inline bool
cgraph_only_called_directly_p (struct cgraph_node *node)
{
return !node->needed && !node->local.externally_visible;
}
/* Return true when function NODE can be removed from callgraph
if all direct calls are eliminated. */
static inline bool
cgraph_can_remove_if_no_direct_calls_p (struct cgraph_node *node)
{
return (!node->needed
&& (DECL_COMDAT (node->decl) || !node->local.externally_visible));
}
/* Constant pool accessor function. */
htab_t constant_pool_htab (void);

View File

@ -316,13 +316,6 @@ cgraph_build_cdtor_fns (void)
bool
cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
{
if (MAIN_NAME_P (DECL_NAME (decl))
&& TREE_PUBLIC (decl))
{
node->local.externally_visible = true;
return true;
}
/* If the user told us it is used, then it must be so. */
if (node->local.externally_visible)
return true;
@ -360,7 +353,9 @@ cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
|| (!optimize && !node->local.disregard_inline_limits
&& !DECL_DECLARED_INLINE_P (decl)
&& !node->origin))
&& !flag_whole_program)
&& !flag_whole_program
&& !flag_lto
&& !flag_whopr)
&& !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
return true;
@ -593,6 +588,21 @@ verify_cgraph_node (struct cgraph_node *node)
error ("Execution count is negative");
error_found = true;
}
if (node->global.inlined_to && node->local.externally_visible)
{
error ("Externally visible inline clone");
error_found = true;
}
if (node->global.inlined_to && node->address_taken)
{
error ("Inline clone with address taken");
error_found = true;
}
if (node->global.inlined_to && node->needed)
{
error ("Inline clone is needed");
error_found = true;
}
for (e = node->callers; e; e = e->next_caller)
{
if (e->count < 0)
@ -864,12 +874,8 @@ process_function_and_variable_attributes (struct cgraph_node *first,
warning_at (DECL_SOURCE_LOCATION (node->decl), OPT_Wattributes,
"%<externally_visible%>"
" attribute have effect only on public objects");
else
{
if (node->local.finalized)
cgraph_mark_needed_node (node);
node->local.externally_visible = true;
}
else if (node->local.finalized)
cgraph_mark_needed_node (node);
}
}
for (vnode = varpool_nodes; vnode != first_var; vnode = vnode->next)
@ -887,12 +893,8 @@ process_function_and_variable_attributes (struct cgraph_node *first,
warning_at (DECL_SOURCE_LOCATION (vnode->decl), OPT_Wattributes,
"%<externally_visible%>"
" attribute have effect only on public objects");
else
{
if (vnode->finalized)
varpool_mark_needed_node (vnode);
vnode->externally_visible = true;
}
else if (vnode->finalized)
varpool_mark_needed_node (vnode);
}
}
}
@ -1355,7 +1357,9 @@ ipa_passes (void)
current_function_decl = NULL;
gimple_register_cfg_hooks ();
bitmap_obstack_initialize (NULL);
execute_ipa_pass_list (all_small_ipa_passes);
if (!in_lto_p)
execute_ipa_pass_list (all_small_ipa_passes);
/* If pass_all_early_optimizations was not scheduled, the state of
the cgraph will not be properly updated. Update it now. */

View File

@ -442,7 +442,7 @@ ipcp_cloning_candidate_p (struct cgraph_node *node)
FIXME: in future we should clone such functions when they are called with
different constants, but current ipcp implementation is not good on this.
*/
if (!node->needed || !node->analyzed)
if (cgraph_only_called_directly_p (node) || !node->analyzed)
return false;
if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE)
@ -536,7 +536,7 @@ ipcp_initialize_node_lattices (struct cgraph_node *node)
if (ipa_is_called_with_var_arguments (info))
type = IPA_BOTTOM;
else if (!node->needed)
else if (cgraph_only_called_directly_p (node))
type = IPA_TOP;
/* When cloning is allowed, we can assume that externally visible functions
are not called. We will compensate this by cloning later. */
@ -954,7 +954,7 @@ ipcp_estimate_growth (struct cgraph_node *node)
struct cgraph_edge *cs;
int redirectable_node_callers = 0;
int removable_args = 0;
bool need_original = node->needed;
bool need_original = !cgraph_only_called_directly_p (node);
struct ipa_node_params *info;
int i, count;
int growth;
@ -1143,7 +1143,7 @@ ipcp_insert_stage (void)
for (cs = node->callers; cs != NULL; cs = cs->next_caller)
if (cs->caller == node || ipcp_need_redirect_p (cs))
break;
if (!cs && !node->needed)
if (!cs && cgraph_only_called_directly_p (node))
bitmap_set_bit (dead_nodes, node->uid);
info = IPA_NODE_REF (node);

View File

@ -223,7 +223,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
/* We may eliminate the need for out-of-line copy to be output.
In that case just go ahead and re-use it. */
if (!e->callee->callers->next_caller
&& !e->callee->needed
&& cgraph_can_remove_if_no_direct_calls_p (e->callee)
&& !cgraph_new_nodes)
{
gcc_assert (!e->callee->global.inlined_to);
@ -233,6 +233,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
nfunctions_inlined++;
}
duplicate = false;
e->callee->local.externally_visible = false;
}
else
{
@ -286,7 +287,7 @@ cgraph_mark_inline_edge (struct cgraph_edge *e, bool update_original,
e->callee->global.inlined = true;
if (e->callee->callers->next_caller
|| e->callee->needed)
|| !cgraph_can_remove_if_no_direct_calls_p (e->callee))
duplicate = true;
cgraph_clone_inlined_nodes (e, true, update_original);
@ -368,7 +369,8 @@ cgraph_estimate_growth (struct cgraph_node *node)
we decide to not inline for different reasons, but it is not big deal
as in that case we will keep the body around, but we will also avoid
some inlining. */
if (!node->needed && !DECL_EXTERNAL (node->decl) && !self_recursive)
if (cgraph_only_called_directly_p (node)
&& !DECL_EXTERNAL (node->decl) && !self_recursive)
growth -= node->global.size;
node->global.estimated_growth = growth;
@ -1226,7 +1228,7 @@ cgraph_decide_inlining (void)
if (node->callers
&& !node->callers->next_caller
&& !node->needed
&& cgraph_only_called_directly_p (node)
&& node->local.inlinable
&& node->callers->inline_failed
&& node->callers->caller != node

122
gcc/ipa.c
View File

@ -52,7 +52,9 @@ cgraph_postorder (struct cgraph_node **order)
for (pass = 0; pass < 2; pass++)
for (node = cgraph_nodes; node; node = node->next)
if (!node->aux
&& (pass || (node->needed && !node->address_taken)))
&& (pass
|| (!cgraph_only_called_directly_p (node)
&& !node->address_taken)))
{
node2 = node;
if (!node->callers)
@ -132,11 +134,12 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
gcc_assert (!node->aux);
#endif
for (node = cgraph_nodes; node; node = node->next)
if (node->needed && !node->global.inlined_to
if (!cgraph_can_remove_if_no_direct_calls_p (node)
&& ((!DECL_EXTERNAL (node->decl))
|| !node->analyzed
|| before_inlining_p))
{
gcc_assert (!node->global.inlined_to);
node->aux = first;
first = node;
}
@ -248,6 +251,26 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
return changed;
}
static bool
cgraph_externally_visible_p (struct cgraph_node *node, bool whole_program)
{
if (!DECL_COMDAT (node->decl)
&& (!TREE_PUBLIC (node->decl) || DECL_EXTERNAL (node->decl)))
return false;
if (!whole_program)
return true;
/* COMDAT functions must be shared only if they have address taken,
otherwise we can produce our own private implementation with
-fwhole-program. */
if (DECL_COMDAT (node->decl) && (node->address_taken || !node->analyzed))
return true;
if (MAIN_NAME_P (DECL_NAME (node->decl)))
return true;
if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (node->decl)))
return true;
return false;
}
/* Mark visibility of all functions.
A local function is one whose calls can occur only in the current
@ -260,25 +283,29 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
via visibilities for the backend point of view. */
static unsigned int
function_and_variable_visibility (void)
function_and_variable_visibility (bool whole_program)
{
struct cgraph_node *node;
struct varpool_node *vnode;
for (node = cgraph_nodes; node; node = node->next)
{
if (node->reachable
&& (DECL_COMDAT (node->decl)
|| (!flag_whole_program
&& TREE_PUBLIC (node->decl) && !DECL_EXTERNAL (node->decl))))
node->local.externally_visible = true;
if (cgraph_externally_visible_p (node, whole_program))
{
gcc_assert (!node->global.inlined_to);
node->local.externally_visible = true;
}
else
node->local.externally_visible = false;
if (!node->local.externally_visible && node->analyzed
&& !DECL_EXTERNAL (node->decl))
{
gcc_assert (flag_whole_program || !TREE_PUBLIC (node->decl));
gcc_assert (whole_program || !TREE_PUBLIC (node->decl));
TREE_PUBLIC (node->decl) = 0;
DECL_COMDAT (node->decl) = 0;
DECL_WEAK (node->decl) = 0;
}
node->local.local = (!node->needed
node->local.local = (cgraph_only_called_directly_p (node)
&& node->analyzed
&& !DECL_EXTERNAL (node->decl)
&& !node->local.externally_visible);
@ -286,12 +313,16 @@ function_and_variable_visibility (void)
for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
{
if (vnode->needed
&& !flag_whole_program
&& (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl)))
vnode->externally_visible = 1;
&& (DECL_COMDAT (vnode->decl) || TREE_PUBLIC (vnode->decl))
&& (!whole_program
|| lookup_attribute ("externally_visible",
DECL_ATTRIBUTES (vnode->decl))))
vnode->externally_visible = true;
else
vnode->externally_visible = false;
if (!vnode->externally_visible)
{
gcc_assert (flag_whole_program || !TREE_PUBLIC (vnode->decl));
gcc_assert (whole_program || !TREE_PUBLIC (vnode->decl));
TREE_PUBLIC (vnode->decl) = 0;
}
gcc_assert (TREE_STATIC (vnode->decl));
@ -314,13 +345,22 @@ function_and_variable_visibility (void)
return 0;
}
/* Local function pass handling visibilities. This happens before LTO streaming
so in particular -fwhole-program should be ignored at this level. */
static unsigned int
local_function_and_variable_visibility (void)
{
return function_and_variable_visibility (flag_whole_program && !flag_lto && !flag_whopr);
}
struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility =
{
{
SIMPLE_IPA_PASS,
"visibility", /* name */
NULL, /* gate */
function_and_variable_visibility, /* execute */
local_function_and_variable_visibility,/* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
@ -333,6 +373,58 @@ struct simple_ipa_opt_pass pass_ipa_function_and_variable_visibility =
}
};
/* Do not re-run on ltrans stage. */
static bool
gate_whole_program_function_and_variable_visibility (void)
{
return !flag_ltrans;
}
/* Bring functionss local at LTO time whith -fwhole-program. */
static unsigned int
whole_program_function_and_variable_visibility (void)
{
struct cgraph_node *node;
struct varpool_node *vnode;
function_and_variable_visibility (flag_whole_program);
for (node = cgraph_nodes; node; node = node->next)
if (node->local.externally_visible)
cgraph_mark_needed_node (node);
for (vnode = varpool_nodes_queue; vnode; vnode = vnode->next_needed)
if (vnode->externally_visible)
varpool_mark_needed_node (vnode);
return 0;
}
struct ipa_opt_pass_d pass_ipa_whole_program_visibility =
{
{
IPA_PASS,
"whole-program", /* name */
gate_whole_program_function_and_variable_visibility,/* gate */
whole_program_function_and_variable_visibility,/* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_CGRAPHOPT, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
TODO_dump_cgraph | TODO_remove_functions/* todo_flags_finish */
},
NULL, /* generate_summary */
NULL, /* write_summary */
NULL, /* read_summary */
NULL, /* function_read_summary */
0, /* TODOs */
NULL, /* function_transform */
NULL, /* variable_transform */
};
/* Hash a cgraph node set element. */

View File

@ -227,6 +227,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
local static nodes to prevent clashes with other local statics. */
if (boundary_p)
{
/* Inline clones can not be part of boundary. */
gcc_assert (!node->global.inlined_to);
local = 0;
externally_visible = 1;
inlinable = 0;

View File

@ -388,7 +388,10 @@ lto_cgraph_replace_node (struct cgraph_node *old_node,
if (old_node->reachable)
cgraph_mark_reachable_node (new_node);
if (old_node->address_taken)
cgraph_mark_address_taken_node (new_node);
{
gcc_assert (!new_node->global.inlined_to);
cgraph_mark_address_taken_node (new_node);
}
/* Redirect all incoming edges. */
for (e = old_node->callers; e; e = next)

View File

@ -1,3 +1,8 @@
2009-10-07 Jan Hubicka <jh@suse.cz>
* lto.c (read_cgraph_and_symbols): Mark functions neccesary only at
ltrans stage; explain why this is needed and should not.
2009-10-05 Richard Guenther <rguenther@suse.de>
PR lto/41552

View File

@ -1824,11 +1824,18 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
/* Merge global decls. */
lto_symtab_merge_decls ();
/* Mark cgraph nodes needed in the merged cgraph.
??? Is this really necessary? */
for (node = cgraph_nodes; node; node = node->next)
if (cgraph_decide_is_function_needed (node, node->decl))
cgraph_mark_needed_node (node);
/* Mark cgraph nodes needed in the merged cgraph
This normally happens in whole-program pass, but for
ltrans the pass was already run at WPA phase.
FIXME: This is not valid way to do so; nodes can be needed
for non-obvious reasons. We should stream the flags from WPA
phase. */
if (flag_ltrans)
for (node = cgraph_nodes; node; node = node->next)
if (!node->global.inlined_to
&& cgraph_decide_is_function_needed (node, node->decl))
cgraph_mark_needed_node (node);
timevar_push (TV_IPA_LTO_DECL_IO);

View File

@ -759,6 +759,7 @@ init_optimization_passes (void)
*p = NULL;
p = &all_regular_ipa_passes;
NEXT_PASS (pass_ipa_whole_program_visibility);
NEXT_PASS (pass_ipa_cp);
NEXT_PASS (pass_ipa_inline);
NEXT_PASS (pass_ipa_reference);
@ -1099,7 +1100,7 @@ do_per_function_toporder (void (*callback) (void *data), void *data)
/* Allow possibly removed nodes to be garbage collected. */
order[i] = NULL;
node->process = 0;
if (node->analyzed && (node->needed || node->reachable))
if (node->analyzed)
{
push_cfun (DECL_STRUCT_FUNCTION (node->decl));
current_function_decl = node->decl;
@ -1783,7 +1784,7 @@ function_called_by_processed_nodes_p (void)
{
if (e->caller->decl == current_function_decl)
continue;
if (!e->caller->analyzed || (!e->caller->needed && !e->caller->reachable))
if (!e->caller->analyzed)
continue;
if (TREE_ASM_WRITTEN (e->caller->decl))
continue;

View File

@ -437,6 +437,7 @@ extern struct simple_ipa_opt_pass pass_ipa_early_inline;
extern struct simple_ipa_opt_pass pass_early_local_passes;
extern struct ipa_opt_pass_d pass_ipa_whole_program_visibility;
extern struct ipa_opt_pass_d pass_ipa_lto_gimple_out;
extern struct simple_ipa_opt_pass pass_ipa_increase_alignment;
extern struct simple_ipa_opt_pass pass_ipa_matrix_reorg;

View File

@ -35,6 +35,7 @@ along with GCC; see the file COPYING3. If not see
#include "output.h"
#include "gimple.h"
#include "tree-flow.h"
#include "flags.h"
/* This file contains basic routines manipulating variable pool.
@ -245,7 +246,11 @@ decide_is_variable_needed (struct varpool_node *node, tree decl)
/* Externally visible variables must be output. The exception is
COMDAT variables that must be output only when they are needed. */
if (TREE_PUBLIC (decl) && !flag_whole_program && !DECL_COMDAT (decl)
if (TREE_PUBLIC (decl)
&& !flag_whole_program
&& !flag_lto
&& !flag_whopr
&& !DECL_COMDAT (decl)
&& !DECL_EXTERNAL (decl))
return true;
@ -279,6 +284,17 @@ varpool_finalize_decl (tree decl)
{
struct varpool_node *node = varpool_node (decl);
/* FIXME: We don't really stream varpool datastructure and instead rebuild it
by varpool_finalize_decl. This is not quite correct since this way we can't
attach any info to varpool. Eventually we will want to stream varpool nodes
and the flags.
For the moment just prevent analysis of varpool nodes to happen again, so
we will re-try to compute "address_taken" flag of varpool that breaks
in presence of clones. */
if (in_lto_p)
node->analyzed = true;
/* The first declaration of a variable that comes through this function
decides whether it is global (in C, has external linkage)
or local (in C, has internal linkage). So do nothing more
@ -333,17 +349,25 @@ varpool_analyze_pending_decls (void)
while (varpool_first_unanalyzed_node)
{
tree decl = varpool_first_unanalyzed_node->decl;
bool analyzed = varpool_first_unanalyzed_node->analyzed;
varpool_first_unanalyzed_node->analyzed = true;
varpool_first_unanalyzed_node = varpool_first_unanalyzed_node->next_needed;
/* Compute the alignment early so function body expanders are
already informed about increased alignment. */
align_variable (decl, 0);
/* When reading back varpool at LTO time, we re-construct the queue in order
to have "needed" list right by inserting all needed nodes into varpool.
We however don't want to re-analyze already analyzed nodes. */
if (!analyzed)
{
gcc_assert (!in_lto_p);
/* Compute the alignment early so function body expanders are
already informed about increased alignment. */
align_variable (decl, 0);
if (DECL_INITIAL (decl))
record_references_in_initializer (decl);
if (DECL_INITIAL (decl))
record_references_in_initializer (decl);
}
changed = true;
}
timevar_pop (TV_CGRAPH);