From 4bd019b8d50600807d95aadeb451b2e68162745f Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 11 Feb 2015 10:11:06 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 23 +++++++++++++++++ gcc/cgraph.c | 25 ++++++------------ gcc/cgraph.h | 7 ------ gcc/ipa-visibility.c | 6 ++--- gcc/ipa.c | 14 ++++++++--- gcc/lto-cgraph.c | 60 ++++++++++++++++++++++++-------------------- gcc/symtab.c | 5 ---- 7 files changed, 76 insertions(+), 64 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a409b164878..c9e0a22552c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,26 @@ +2015-02-10 Jan Hubicka + + 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 Sandra Loosemore diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 8ea8ae93714..a71f68ca4e0 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -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; + node = node->ultimate_alias_target (); + if (node->decl != current_function_decl + && !TREE_ASM_WRITTEN (node->decl)) return NULL; - return &node->rtl; + return &node->ultimate_alias_target ()->rtl; } /* Return a string describing the failure REASON. */ diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 0fdb459ab00..b9a276c3715 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -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); diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c index a8ac971b848..c33ee469dbe 100644 --- a/gcc/ipa-visibility.c +++ b/gcc/ipa-visibility.c @@ -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); } diff --git a/gcc/ipa.c b/gcc/ipa.c index 9cbd2da8023..620431c54d6 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -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) diff --git a/gcc/lto-cgraph.c b/gcc/lto-cgraph.c index ab9524b3b73..c0fa47d2c25 100644 --- a/gcc/lto-cgraph.c +++ b/gcc/lto-cgraph.c @@ -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 (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 (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); diff --git a/gcc/symtab.c b/gcc/symtab.c index aba1ae4063b..3bfb04a25c1 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -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"); -- 2.30.2