summaryrefslogtreecommitdiff
path: root/gcc/varpool.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/varpool.c')
-rw-r--r--gcc/varpool.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 12cdad90e28..8815efda249 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -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,24 @@ 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);
+ record_references_in_initializer (decl, analyzed);
changed = true;
}
timevar_pop (TV_CGRAPH);