#include "cfglayout.h"
#include "basic-block.h"
#include "tree-iterator.h"
+#include "pointer-set.h"
#ifdef XCOFF_DEBUGGING_INFO
#include "xcoffout.h" /* Needed for external data
}
+/* Compute the set of indentifier nodes that is generated by aliases
+ whose targets are reachable. */
+
+static struct pointer_set_t *
+compute_visible_aliases (void)
+{
+ struct pointer_set_t *visible;
+ unsigned i;
+ alias_pair *p;
+ bool changed;
+
+ /* We have to compute the set of visible nodes including aliases
+ themselves. */
+ visible = pointer_set_create ();
+ do
+ {
+ changed = false;
+ for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); ++i)
+ {
+ struct cgraph_node *fnode = NULL;
+ struct varpool_node *vnode = NULL;
+ fnode = cgraph_node_for_asm (p->target);
+ vnode = (fnode == NULL) ? varpool_node_for_asm (p->target) : NULL;
+ if ((fnode
+ || vnode
+ || pointer_set_contains (visible, p->target))
+ && !pointer_set_insert (visible, DECL_ASSEMBLER_NAME (p->decl)))
+ changed = true;
+ }
+ }
+ while (changed);
+
+ return visible;
+}
+
/* Remove the alias pairing for functions that are no longer in the call
graph. */
void
remove_unreachable_alias_pairs (void)
{
+ struct pointer_set_t *visible;
unsigned i;
alias_pair *p;
if (alias_pairs == NULL)
return;
+ /* We have to compute the set of visible nodes including aliases
+ themselves. */
+ visible = compute_visible_aliases ();
+
for (i = 0; VEC_iterate (alias_pair, alias_pairs, i, p); )
{
if (!DECL_EXTERNAL (p->decl))
struct varpool_node *vnode = NULL;
fnode = cgraph_node_for_asm (p->target);
vnode = (fnode == NULL) ? varpool_node_for_asm (p->target) : NULL;
- if (fnode == NULL && vnode == NULL)
+ if (!fnode
+ && !vnode
+ && !pointer_set_contains (visible, p->target))
{
VEC_unordered_remove (alias_pair, alias_pairs, i);
continue;
i++;
}
+
+ pointer_set_destroy (visible);
}
void
finish_aliases_1 (void)
{
+ struct pointer_set_t *visible;
unsigned i;
alias_pair *p;
+ if (alias_pairs == NULL)
+ return;
+
+ /* We have to compute the set of visible nodes including aliases
+ themselves. */
+ visible = compute_visible_aliases ();
+
FOR_EACH_VEC_ELT (alias_pair, alias_pairs, i, p)
{
tree target_decl;
target_decl = find_decl_and_mark_needed (p->decl, p->target);
if (target_decl == NULL)
{
+ if (pointer_set_contains (visible, p->target))
+ continue;
+
if (! (p->emitted_diags & ALIAS_DIAG_TO_UNDEF)
&& ! lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)))
{
p->emitted_diags |= ALIAS_DIAG_TO_EXTERN;
}
}
+
+ pointer_set_destroy (visible);
}
/* Second pass of completing pending aliases. Emit the actual assembly.