param_is (struct lto_symtab_entry_def)))
htab_t lto_symtab_identifiers;
-/* Free symtab hashtable. */
-
-void
-lto_symtab_free (void)
-{
- htab_delete (lto_symtab_identifiers);
- lto_symtab_identifiers = NULL;
-}
-
/* Return the hash value of an lto_symtab_entry_t object pointed to by P. */
static hashval_t
const struct lto_symtab_entry_def *base =
(const struct lto_symtab_entry_def *) p;
- /* Keep this only if the common IDENTIFIER_NODE of the symtab chain
- is marked which it will be if at least one of the DECLs in the
- chain is marked. */
- return ggc_marked_p (base->id);
+ /* Keep this only if the decl or the chain is marked. */
+ return (ggc_marked_p (base->decl)
+ || (base->next && ggc_marked_p (base->next)));
}
/* Lazily initialize resolution hash tables. */
next = e->next_caller;
cgraph_redirect_edge_callee (e, prevailing_node);
}
- /* Redirect incomming references. */
- ipa_clone_refering (prevailing_node, NULL, &node->ref_list);
+
+ /* There are not supposed to be any outgoing edges from a node we
+ replace. Still this can happen for multiple instances of weak
+ functions. */
+ for (e = node->callees; e; e = next)
+ {
+ next = e->next_callee;
+ cgraph_remove_edge (e);
+ }
if (node->same_body)
{
/* Merge node flags. */
if (vnode->needed)
{
- gcc_assert (!vnode->analyzed || prevailing_node->analyzed);
+ gcc_assert (prevailing_node->analyzed);
varpool_mark_needed_node (prevailing_node);
}
- /* Relink aliases. */
- if (vnode->extra_name && !vnode->alias)
- {
- struct varpool_node *alias, *last;
- for (alias = vnode->extra_name;
- alias; alias = alias->next)
- {
- last = alias;
- alias->extra_name = prevailing_node;
- }
-
- if (prevailing_node->extra_name)
- {
- last->next = prevailing_node->extra_name;
- prevailing_node->extra_name->prev = last;
- }
- prevailing_node->extra_name = vnode->extra_name;
- vnode->extra_name = NULL;
- }
gcc_assert (!vnode->finalized || prevailing_node->finalized);
gcc_assert (!vnode->analyzed || prevailing_node->analyzed);
- /* When replacing by an alias, the references goes to the original
- variable. */
- if (prevailing_node->alias && prevailing_node->extra_name)
- prevailing_node = prevailing_node->extra_name;
- ipa_clone_refering (NULL, prevailing_node, &vnode->ref_list);
-
/* Finally remove the replaced node. */
varpool_remove_node (vnode);
}
/* A variable should have a size. */
else if (TREE_CODE (e->decl) == VAR_DECL)
- {
- if (!e->vnode)
- return false;
- if (e->vnode->finalized)
- return true;
- return e->vnode->alias && e->vnode->extra_name->finalized;
- }
+ return (DECL_SIZE (e->decl) != NULL_TREE
+ /* The C++ frontend retains TREE_STATIC on the declaration
+ of foo_ in struct Foo { static Foo *foo_; }; but it is
+ not a definition. g++.dg/lto/20090315_0.C. */
+ && !DECL_EXTERNAL (e->decl));
gcc_unreachable ();
}
while (!prevailing->node
&& prevailing->next)
prevailing = prevailing->next;
- /* For variables chose with a priority variant with vnode
- attached (i.e. from unit where external declaration of
- variable is actually used).
- When there are multiple variants, chose one with size.
- This is needed for C++ typeinfos, for example in
- lto/20081204-1 there are typeifos in both units, just
- one of them do have size. */
if (TREE_CODE (prevailing->decl) == VAR_DECL)
- {
- for (e = prevailing->next; e; e = e->next)
- if ((!prevailing->vnode && e->vnode)
- || ((prevailing->vnode != NULL) == (e->vnode != NULL)
- && !COMPLETE_TYPE_P (TREE_TYPE (prevailing->decl))
- && COMPLETE_TYPE_P (TREE_TYPE (e->decl))))
- prevailing = e;
- }
+ while (!prevailing->vnode
+ && prevailing->next)
+ prevailing = prevailing->next;
+ /* We do not stream varpool nodes, so the first decl has to
+ be good enough for now.
+ ??? For QOI choose a variable with readonly initializer
+ if there is one. This matches C++
+ struct Foo { static const int i = 1; }; without a real
+ definition. */
+ if (TREE_CODE (prevailing->decl) == VAR_DECL)
+ while (!(TREE_READONLY (prevailing->decl)
+ && DECL_INITIAL (prevailing->decl))
+ && prevailing->next)
+ prevailing = prevailing->next;
}
/* Move it first in the list. */