#include "tree.h"
#include "cgraph.h"
#include "langhooks.h"
-#include "diagnostic.h"
+#include "diagnostic-core.h"
#include "hashtab.h"
#include "ggc.h"
#include "timevar.h"
return NULL;
key.decl = decl;
slot = (struct varpool_node **)
- htab_find_slot (varpool_hash, &key, INSERT);
+ htab_find_slot (varpool_hash, &key, NO_INSERT);
+ if (!slot)
+ return NULL;
return *slot;
}
htab_find_slot (varpool_hash, &key, INSERT);
if (*slot)
return *slot;
- node = GGC_CNEW (struct varpool_node);
+ node = ggc_alloc_cleared_varpool_node ();
node->decl = decl;
node->order = cgraph_order++;
node->next = varpool_nodes;
+ ipa_empty_ref_list (&node->ref_list);
if (varpool_nodes)
varpool_nodes->prev = node;
varpool_nodes = node;
node->prev->next = node->next;
else
{
- if (node->alias)
+ if (node->alias && node->extra_name)
{
gcc_assert (node->extra_name->extra_name == node);
node->extra_name->extra_name = node->next;
gcc_assert (varpool_nodes_queue == node);
varpool_nodes_queue = node->next_needed;
}
- if (DECL_INITIAL (node->decl))
- DECL_INITIAL (node->decl) = error_mark_node;
+ if (node->same_comdat_group)
+ {
+ struct varpool_node *prev;
+ for (prev = node->same_comdat_group;
+ prev->same_comdat_group != node;
+ prev = prev->same_comdat_group)
+ ;
+ if (node->same_comdat_group == prev)
+ prev->same_comdat_group = NULL;
+ else
+ prev->same_comdat_group = node->same_comdat_group;
+ node->same_comdat_group = NULL;
+ }
+ ipa_remove_all_references (&node->ref_list);
+ ipa_remove_all_refering (&node->ref_list);
ggc_free (node);
}
else if (node->used_from_other_partition)
fprintf (f, " used_from_other_partition");
fprintf (f, "\n");
+ fprintf (f, " References: ");
+ ipa_dump_references (f, &node->ref_list);
+ fprintf (f, " Refering this var: ");
+ ipa_dump_refering (f, &node->ref_list);
}
/* Dump the variable pool. */
/* Dump the variable pool to stderr. */
-void
+DEBUG_FUNCTION void
debug_varpool (void)
{
dump_varpool (stderr);
}
/* Reset the queue of needed nodes. */
-static void
+void
varpool_reset_queue (void)
{
varpool_last_needed_node = NULL;
|| node->force_output)
return true;
- /* ??? If the assembler name is set by hand, it is possible to assemble
- the name later after finalizing the function and the fact is noticed
- in assemble_name then. This is arguably a bug. */
- if (DECL_ASSEMBLER_NAME_SET_P (decl)
- && TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)))
- return true;
-
/* Externally visible variables must be output. The exception is
COMDAT variables that must be output only when they are needed. */
if (TREE_PUBLIC (decl)
&& !DECL_EXTERNAL (decl))
return true;
- /* When emulating tls, we actually see references to the control
- variable, rather than the user-level variable. */
- if (!targetm.have_tls
- && TREE_CODE (decl) == VAR_DECL
- && DECL_THREAD_LOCAL_P (decl))
- {
- tree control = emutls_decl (decl);
- if (decide_is_variable_needed (varpool_node (control), control))
- return true;
- }
-
/* When not reordering top level variables, we have to assume that
we are going to keep everything. */
if (flag_toplevel_reorder)
if (node->needed)
varpool_enqueue_needed_node (node);
node->finalized = true;
+ if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl))
+ node->force_output = true;
if (decide_is_variable_needed (node, decl))
varpool_mark_needed_node (node);
timevar_push (TV_VARPOOL);
while (varpool_first_unanalyzed_node)
{
- tree decl = varpool_first_unanalyzed_node->decl;
- bool analyzed = varpool_first_unanalyzed_node->analyzed;
+ struct varpool_node *node = varpool_first_unanalyzed_node, *next;
+ tree decl = node->decl;
+ bool analyzed = node->analyzed;
varpool_first_unanalyzed_node->analyzed = true;
}
if (DECL_INITIAL (decl))
record_references_in_initializer (decl, analyzed);
+ if (node->same_comdat_group)
+ {
+ for (next = node->same_comdat_group;
+ next != node;
+ next = next->same_comdat_group)
+ varpool_mark_needed_node (next);
+ }
changed = true;
}
timevar_pop (TV_VARPOOL);
varpool_reset_queue ();
- if (errorcount || sorrycount)
+ if (seen_error ())
return;
while (node)
{
bool changed = false;
- if (errorcount || sorrycount)
+ if (seen_error ())
return false;
timevar_push (TV_VAROUT);
if (*slot)
return false;
- alias_node = GGC_CNEW (struct varpool_node);
+ alias_node = ggc_alloc_cleared_varpool_node ();
alias_node->decl = alias;
alias_node->alias = 1;
alias_node->extra_name = decl_node;
alias_node->next = decl_node->extra_name;
+ ipa_empty_ref_list (&alias_node->ref_list);
if (decl_node->extra_name)
decl_node->extra_name->prev = alias_node;
decl_node->extra_name = alias_node;