summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog23
-rw-r--r--gcc/cgraph.c25
-rw-r--r--gcc/cgraph.h7
-rw-r--r--gcc/ipa-visibility.c6
-rw-r--r--gcc/ipa.c14
-rw-r--r--gcc/lto-cgraph.c60
-rw-r--r--gcc/symtab.c5
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 <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>
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 <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);
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");