re PR ipa/65005 (FAIL: c-c++-common/torture/builtin-arith-overflow-12.c)

PR ipa/65005
	* ipa-visibility.c (cgraph_node::non_local_p): Turn into static
	function.
	* symtab.c (symtab_node::verify_base): Remove check that non-definitions
	have no comdat group.
	* lto-cgraph.c (lto_output_node): Always output thunk and alias info.
	(lto_output_varpool_node): Always output alias info.
	(output_refs): Output refs of boundary aliases, too.
	(compute_ltrans_boundary): Add alias and thunk target into boundaries.
	(output_symtab): Output call eges in thunks in boundary.
	(get_alias_symbol): Remove.
	(input_node, input_varpool_node): Do not special case weakrefs.
	* ipa.c (symbol_table::remove_unreachable_nodes): Do not remove
	alias and thunks targets in the boundary; do not take removed symbols
	from their comdat groups.
	* cgraph.c (cgraph_node::local_info): Look through aliases and thunks.
	(cgraph_node::global_info): Remove.
	(cgraph_node::rtl_info): Look through aliases and thunks.
	* cgrpah.h (global_info): Remove.
	(non_local_p): Remove.

From-SVN: r220608
This commit is contained in:
Jan Hubicka 2015-02-11 10:11:06 +01:00 committed by Jan Hubicka
parent 80f6181e27
commit 4bd019b8d5
7 changed files with 76 additions and 64 deletions

View file

@ -1,3 +1,26 @@
2015-02-10 Jan Hubicka <hubicka@ucw.cz>
PR ipa/65005
* ipa-visibility.c (cgraph_node::non_local_p): Turn into static
function.
* symtab.c (symtab_node::verify_base): Remove check that non-definitions
have no comdat group.
* lto-cgraph.c (lto_output_node): Always output thunk and alias info.
(lto_output_varpool_node): Always output alias info.
(output_refs): Output refs of boundary aliases, too.
(compute_ltrans_boundary): Add alias and thunk target into boundaries.
(output_symtab): Output call eges in thunks in boundary.
(get_alias_symbol): Remove.
(input_node, input_varpool_node): Do not special case weakrefs.
* ipa.c (symbol_table::remove_unreachable_nodes): Do not remove
alias and thunks targets in the boundary; do not take removed symbols
from their comdat groups.
* cgraph.c (cgraph_node::local_info): Look through aliases and thunks.
(cgraph_node::global_info): Remove.
(cgraph_node::rtl_info): Look through aliases and thunks.
* cgrpah.h (global_info): Remove.
(non_local_p): Remove.
2015-02-10 David Wohlferd <dw@LimeGreenSocks.com>
Sandra Loosemore <sandra@codesourcery.com>

View file

@ -1846,20 +1846,7 @@ cgraph_node::local_info (tree decl)
cgraph_node *node = get (decl);
if (!node)
return NULL;
return &node->local;
}
/* Return global info for the compiled function. */
cgraph_global_info *
cgraph_node::global_info (tree decl)
{
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL
&& symtab->global_info_ready);
cgraph_node *node = get (decl);
if (!node)
return NULL;
return &node->global;
return &node->ultimate_alias_target ()->local;
}
/* Return local info for the compiled function. */
@ -1869,11 +1856,13 @@ cgraph_node::rtl_info (tree decl)
{
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
cgraph_node *node = get (decl);
if (!node
|| (decl != current_function_decl
&& !TREE_ASM_WRITTEN (node->decl)))
if (!node)
return NULL;
return &node->rtl;
node = node->ultimate_alias_target ();
if (node->decl != current_function_decl
&& !TREE_ASM_WRITTEN (node->decl))
return NULL;
return &node->ultimate_alias_target ()->rtl;
}
/* Return a string describing the failure REASON. */

View file

@ -1164,9 +1164,6 @@ public:
/* Return local info for the compiled function. */
static cgraph_local_info *local_info (tree decl);
/* Return global info for the compiled function. */
static cgraph_global_info *global_info (tree);
/* Return local info for the compiled function. */
static cgraph_rtl_info *rtl_info (tree);
@ -1187,10 +1184,6 @@ public:
return node->used_from_object_file_p ();
}
/* Return true when cgraph_node can not be local.
Worker for cgraph_local_node_p. */
static bool non_local_p (cgraph_node *node, void *);
/* Verify whole cgraph structure. */
static void DEBUG_FUNCTION verify_cgraph_nodes (void);

View file

@ -101,8 +101,8 @@ along with GCC; see the file COPYING3. If not see
/* Return true when NODE can not be local. Worker for cgraph_local_node_p. */
bool
cgraph_node::non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
static bool
non_local_p (struct cgraph_node *node, void *data ATTRIBUTE_UNUSED)
{
return !(node->only_called_directly_or_aliased_p ()
/* i386 would need update to output thunk with locak calling
@ -124,7 +124,7 @@ cgraph_node::local_p (void)
if (n->thunk.thunk_p)
return n->callees->callee->local_p ();
return !n->call_for_symbol_thunks_and_aliases (cgraph_node::non_local_p,
return !n->call_for_symbol_thunks_and_aliases (non_local_p,
NULL, true);
}

View file

@ -383,7 +383,11 @@ symbol_table::remove_unreachable_nodes (FILE *file)
/* If we are processing symbol in boundary, mark its AUX pointer for
possible later re-processing in enqueue_node. */
if (in_boundary_p)
node->aux = (void *)2;
{
node->aux = (void *)2;
if (node->alias && node->analyzed)
enqueue_node (node->get_alias_target (), &first, &reachable);
}
else
{
if (TREE_CODE (node->decl) == FUNCTION_DECL
@ -486,6 +490,9 @@ symbol_table::remove_unreachable_nodes (FILE *file)
}
}
else if (cnode->thunk.thunk_p)
enqueue_node (cnode->callees->callee, &first, &reachable);
/* If any reachable function has simd clones, mark them as
reachable as well. */
if (cnode->simd_clones)
@ -534,7 +541,7 @@ symbol_table::remove_unreachable_nodes (FILE *file)
node->release_body ();
else if (!node->clone_of)
gcc_assert (in_lto_p || DECL_RESULT (node->decl));
if (node->definition)
if (node->definition && !node->alias && !node->thunk.thunk_p)
{
if (file)
fprintf (file, " %s/%i", node->name (), node->order);
@ -554,7 +561,6 @@ symbol_table::remove_unreachable_nodes (FILE *file)
if (!node->in_other_partition)
node->local.local = false;
node->remove_callees ();
node->remove_from_same_comdat_group ();
node->remove_all_references ();
changed = true;
if (node->thunk.thunk_p
@ -614,7 +620,7 @@ symbol_table::remove_unreachable_nodes (FILE *file)
vnode->remove ();
changed = true;
}
else if (!reachable.contains (vnode))
else if (!reachable.contains (vnode) && !vnode->alias)
{
tree init;
if (vnode->definition)

View file

@ -432,14 +432,13 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
struct cgraph_node *clone_of, *ultimate_clone_of;
ipa_opt_pass_d *pass;
int i;
bool alias_p;
const char *comdat;
const char *section;
tree group;
boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
if (node->analyzed && !boundary_p)
if (node->analyzed && (!boundary_p || node->alias || node->thunk.thunk_p))
tag = LTO_symtab_analyzed_node;
else
tag = LTO_symtab_unavail_node;
@ -565,14 +564,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
|| referenced_from_other_partition_p (node, encoder)), 1);
bp_pack_value (&bp, node->lowered, 1);
bp_pack_value (&bp, in_other_partition, 1);
/* Real aliases in a boundary become non-aliases. However we still stream
alias info on weakrefs.
TODO: We lose a bit of information here - when we know that variable is
defined in other unit, we may use the info on aliases to resolve
symbol1 != symbol2 type tests that we can do only for locally defined objects
otherwise. */
alias_p = node->alias && (!boundary_p || node->weakref);
bp_pack_value (&bp, alias_p, 1);
bp_pack_value (&bp, node->alias, 1);
bp_pack_value (&bp, node->weakref, 1);
bp_pack_value (&bp, node->frequency, 2);
bp_pack_value (&bp, node->only_called_at_startup, 1);
@ -581,14 +573,14 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
bp_pack_value (&bp, node->calls_comdat_local, 1);
bp_pack_value (&bp, node->icf_merged, 1);
bp_pack_value (&bp, node->nonfreeing_fn, 1);
bp_pack_value (&bp, node->thunk.thunk_p && !boundary_p, 1);
bp_pack_value (&bp, node->thunk.thunk_p, 1);
bp_pack_enum (&bp, ld_plugin_symbol_resolution,
LDPR_NUM_KNOWN, node->resolution);
bp_pack_value (&bp, node->instrumentation_clone, 1);
streamer_write_bitpack (&bp);
streamer_write_data_stream (ob->main_stream, section, strlen (section) + 1);
if (node->thunk.thunk_p && !boundary_p)
if (node->thunk.thunk_p)
{
streamer_write_uhwi_stream
(ob->main_stream,
@ -618,7 +610,6 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
bool boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
struct bitpack_d bp;
int ref;
bool alias_p;
const char *comdat;
const char *section;
tree group;
@ -638,8 +629,7 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
bp_pack_value (&bp, node->implicit_section, 1);
bp_pack_value (&bp, node->writeonly, 1);
bp_pack_value (&bp, node->definition, 1);
alias_p = node->alias && (!boundary_p || node->weakref);
bp_pack_value (&bp, alias_p, 1);
bp_pack_value (&bp, node->alias, 1);
bp_pack_value (&bp, node->weakref, 1);
bp_pack_value (&bp, node->analyzed && !boundary_p, 1);
gcc_assert (node->definition || !node->analyzed);
@ -794,18 +784,18 @@ output_outgoing_cgraph_edges (struct cgraph_edge *edge,
static void
output_refs (lto_symtab_encoder_t encoder)
{
lto_symtab_encoder_iterator lsei;
struct lto_simple_output_block *ob;
int count;
struct ipa_ref *ref;
int i;
ob = lto_create_simple_output_block (LTO_section_refs);
for (lsei = lsei_start_in_partition (encoder); !lsei_end_p (lsei);
lsei_next_in_partition (&lsei))
for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
symtab_node *node = lsei_node (lsei);
symtab_node *node = lto_symtab_encoder_deref (encoder, i);
if (!node->alias && !lto_symtab_encoder_in_partition_p (encoder, node))
continue;
count = node->ref_list.nreferences ();
if (count)
@ -813,7 +803,7 @@ output_refs (lto_symtab_encoder_t encoder)
streamer_write_gcov_count_stream (ob->main_stream, count);
streamer_write_uhwi_stream (ob->main_stream,
lto_symtab_encoder_lookup (encoder, node));
for (i = 0; node->iterate_reference (i, ref); i++)
for (int i = 0; node->iterate_reference (i, ref); i++)
lto_output_ref (ob, ref, encoder);
}
}
@ -987,6 +977,19 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
}
}
}
/* Be sure to also insert alias targert and thunk callees. These needs
to stay to aid local calling conventions. */
for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
symtab_node *node = lto_symtab_encoder_deref (encoder, i);
cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
if (node->alias && node->analyzed)
create_references (encoder, node);
if (cnode
&& cnode->thunk.thunk_p)
add_node_to (encoder, cnode->callees->callee, false);
}
lto_symtab_encoder_delete (in_encoder);
return encoder;
}
@ -998,7 +1001,6 @@ output_symtab (void)
{
struct cgraph_node *node;
struct lto_simple_output_block *ob;
lto_symtab_encoder_iterator lsei;
int i, n_nodes;
lto_symtab_encoder_t encoder;
@ -1028,12 +1030,16 @@ output_symtab (void)
}
/* Go over the nodes in SET again to write edges. */
for (lsei = lsei_start_function_in_partition (encoder); !lsei_end_p (lsei);
lsei_next_function_in_partition (&lsei))
for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
{
node = lsei_cgraph_node (lsei);
output_outgoing_cgraph_edges (node->callees, ob, encoder);
output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder);
node = dyn_cast <cgraph_node *> (lto_symtab_encoder_deref (encoder, i));
if (node
&& (node->thunk.thunk_p
|| lto_symtab_encoder_in_partition_p (encoder, node)))
{
output_outgoing_cgraph_edges (node->callees, ob, encoder);
output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder);
}
}
streamer_write_uhwi_stream (ob->main_stream, 0);

View file

@ -1070,11 +1070,6 @@ symtab_node::verify_base (void)
error ("same_comdat_group list across different groups");
error_found = true;
}
if (!n->definition)
{
error ("Node has same_comdat_group but it is not a definition");
error_found = true;
}
if (n->type != type)
{
error ("mixing different types of symbol in same comdat groups is not supported");