re PR middle-end/46674 (Weak alias is mistakenly optimized away)

PR middle-end/46674
	PR middle-end/46221
	* varasm.c (symbol_alias_set_t): New typedef for derived pointer_set
	wrapper class.
	(symbol_alias_set_create): New wrapper function.
	(symbol_alias_set_destroy): Likewise.
	(symbol_alias_set_contains): Likewise.
	(symbol_alias_set_insert): Likewise.
	(compute_visible_aliases): Use the above and return symbol_alias_set_t,
	not a pointer_set.
	(remove_unreachable_alias_pairs): Adjust likewise to match.
	(finish_aliases_1): Likewise.

From-SVN: r168047
This commit is contained in:
Dave Korn 2010-12-19 11:14:19 +00:00 committed by Dave Korn
parent f910786b98
commit b48feb9dd8
2 changed files with 72 additions and 19 deletions

View File

@ -1,3 +1,18 @@
2010-12-19 Dave Korn <dave.korn.cygwin@gmail.com>
PR middle-end/46674
PR middle-end/46221
* varasm.c (symbol_alias_set_t): New typedef for derived pointer_set
wrapper class.
(symbol_alias_set_create): New wrapper function.
(symbol_alias_set_destroy): Likewise.
(symbol_alias_set_contains): Likewise.
(symbol_alias_set_insert): Likewise.
(compute_visible_aliases): Use the above and return symbol_alias_set_t,
not a pointer_set.
(remove_unreachable_alias_pairs): Adjust likewise to match.
(finish_aliases_1): Likewise.
2010-12-19 Chung-Lin Tang <cltang@codesourcery.com>
* config/arm/arm.c (arm_legitimate_index_p): Add VFP load/store

View File

@ -5504,21 +5504,67 @@ do_assemble_alias (tree decl, tree target)
#endif
}
/* Derived type for use by compute_visible_aliases and callers. A symbol
alias set is a pointer set into which we enter IDENTIFIER_NODES bearing
the canonicalised assembler-level symbol names corresponding to decls
and their aliases. */
typedef struct pointer_set_t symbol_alias_set_t;
/* Allocate and construct a symbol alias set. */
static symbol_alias_set_t *
symbol_alias_set_create (void)
{
return pointer_set_create ();
}
/* Destruct and free a symbol alias set. */
static void
symbol_alias_set_destroy (symbol_alias_set_t *aset)
{
pointer_set_destroy (aset);
}
/* Test if a symbol alias set contains a given name. */
static int
symbol_alias_set_contains (const symbol_alias_set_t *aset, tree t)
{
/* We accept either a DECL or an IDENTIFIER directly. */
if (TREE_CODE (t) != IDENTIFIER_NODE)
t = DECL_ASSEMBLER_NAME (t);
t = targetm.asm_out.mangle_assembler_name (IDENTIFIER_POINTER (t));
return pointer_set_contains (aset, t);
}
/* Enter a new name into a symbol alias set. */
static int
symbol_alias_set_insert (symbol_alias_set_t *aset, tree t)
{
/* We accept either a DECL or an IDENTIFIER directly. */
if (TREE_CODE (t) != IDENTIFIER_NODE)
t = DECL_ASSEMBLER_NAME (t);
t = targetm.asm_out.mangle_assembler_name (IDENTIFIER_POINTER (t));
return pointer_set_insert (aset, t);
}
/* Compute the set of indentifier nodes that is generated by aliases
whose targets are reachable. */
static struct pointer_set_t *
static symbol_alias_set_t *
compute_visible_aliases (void)
{
struct pointer_set_t *visible;
symbol_alias_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 ();
visible = symbol_alias_set_create ();
do
{
changed = false;
@ -5526,21 +5572,13 @@ compute_visible_aliases (void)
{
struct cgraph_node *fnode = NULL;
struct varpool_node *vnode = NULL;
tree asmname = DECL_ASSEMBLER_NAME (p->decl);
const char *str = IDENTIFIER_POINTER (asmname);
if (str[0] == '*')
{
str ++;
asmname = get_identifier (str);
}
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, asmname))
|| symbol_alias_set_contains (visible, p->target))
&& !symbol_alias_set_insert (visible, p->decl))
changed = true;
}
}
@ -5555,7 +5593,7 @@ compute_visible_aliases (void)
void
remove_unreachable_alias_pairs (void)
{
struct pointer_set_t *visible;
symbol_alias_set_t *visible;
unsigned i;
alias_pair *p;
@ -5576,7 +5614,7 @@ remove_unreachable_alias_pairs (void)
vnode = (fnode == NULL) ? varpool_node_for_asm (p->target) : NULL;
if (!fnode
&& !vnode
&& !pointer_set_contains (visible, p->target))
&& !symbol_alias_set_contains (visible, p->target))
{
VEC_unordered_remove (alias_pair, alias_pairs, i);
continue;
@ -5586,7 +5624,7 @@ remove_unreachable_alias_pairs (void)
i++;
}
pointer_set_destroy (visible);
symbol_alias_set_destroy (visible);
}
@ -5596,7 +5634,7 @@ remove_unreachable_alias_pairs (void)
void
finish_aliases_1 (void)
{
struct pointer_set_t *visible;
symbol_alias_set_t *visible;
unsigned i;
alias_pair *p;
@ -5614,7 +5652,7 @@ finish_aliases_1 (void)
target_decl = find_decl_and_mark_needed (p->decl, p->target);
if (target_decl == NULL)
{
if (pointer_set_contains (visible, p->target))
if (symbol_alias_set_contains (visible, p->target))
continue;
if (! (p->emitted_diags & ALIAS_DIAG_TO_UNDEF)
@ -5640,7 +5678,7 @@ finish_aliases_1 (void)
}
}
pointer_set_destroy (visible);
symbol_alias_set_destroy (visible);
}
/* Second pass of completing pending aliases. Emit the actual assembly.