aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2012-05-17 16:37:33 +0000
committerJan Hubicka <jh@suse.cz>2012-05-17 16:37:33 +0000
commit8b5aa709baaac3fbc8182229773eba8cb8c7fc25 (patch)
treec091b61bf18ed877244605adef29bd8f35c140b1 /gcc/ipa.c
parent3dca45fe8fc1d6c8fae7da8942716e53ea37d2bf (diff)
* lto-symtab.c (lto_symtab_resolve_symbols): Preffer decl with constructor
over decl without. * cgraph.c (cgraph_remove_node): Clear also body of unanalyzed nodes. * cgraph.h (varpool_can_remove_if_no_refs): Handle external correctly. * cgraphunit.c (process_function_and_variable_attributes): Finalize extrnal decls. (mark_functions_to_output): Also accept bodies for functions with clones. (output_in_order): Skip external vars. * lto-cgraph.c (lto_output_node): External functions are never in other partition. (lto_output_varpool_node): Likewise. * lto-streamer-out.c (lto_write_tree): Always use error_mark_nodes for forgotten initializers. * ipa.c (process_references): Handle external vars. (symtab_remove_unreachable_nodes): Update to handle external vars. (varpool_externally_visible_p): External vars are externally visible. * gimple-fold.c (can_refer_decl_in_current_unit_p): Update. * varpool.c (varpool_remove_node): Remove constructor. (decide_is_variable_needed): Handle externals. (varpool_remove_unreferenced_decls): Likewise. * lto-partition.c (add_references_to_partition): Handle external vars. (partition_varpool_node_p): Likewise. (lto_promote_cross_file_statics): Do not promote externals. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@187631 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa.c')
-rw-r--r--gcc/ipa.c29
1 files changed, 27 insertions, 2 deletions
diff --git a/gcc/ipa.c b/gcc/ipa.c
index a107c6f0ec5..cafa7a11f2a 100644
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -100,7 +100,10 @@ process_references (struct ipa_ref_list *list,
{
struct varpool_node *node = ipa_ref_varpool_node (ref);
- if (node->analyzed)
+ if (node->analyzed
+ && (!DECL_EXTERNAL (node->symbol.decl)
+ || node->alias
+ || before_inlining_p))
pointer_set_insert (reachable, node);
enqueue_node ((symtab_node) node, first, reachable);
}
@@ -187,6 +190,12 @@ has_addr_references_p (struct cgraph_node *node,
reshape callgraph and preserve body when offline copy of function or
inline clone is being removed.
+ - C++ virtual tables keyed to other unit are represented as DECL_EXTERNAL
+ variables with DECL_INITIAL set. We finalize these and keep reachable
+ ones around for constant folding purposes. After inlining we however
+ stop walking their references to let everything static referneced by them
+ to be removed when it is otherwise unreachable.
+
We maintain queue of both reachable symbols (i.e. defined symbols that needs
to stay) and symbols that are in boundary (i.e. external symbols referenced
by reachable symbols or origins of clones). The queue is represented
@@ -323,6 +332,19 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
}
}
}
+ /* When we see constructor of external variable, keep referred nodes in the
+ boundary. This will also hold initializers of the external vars NODE
+ reffers to. */
+ if (symtab_variable_p (node)
+ && DECL_EXTERNAL (node->symbol.decl)
+ && !varpool (node)->alias
+ && in_boundary_p)
+ {
+ int i;
+ struct ipa_ref *ref;
+ for (i = 0; ipa_ref_list_reference_iterate (&node->symbol.ref_list, i, ref); i++)
+ enqueue_node (ref->referred, &first, reachable);
+ }
}
/* Remove unreachable functions. */
@@ -347,7 +369,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
changed = true;
}
if (!pointer_set_contains (body_needed_for_clonning, node->symbol.decl)
- && !DECL_ARTIFICIAL (node->symbol.decl))
+ && (node->local.finalized || !DECL_ARTIFICIAL (node->symbol.decl)))
cgraph_release_function_body (node);
node->analyzed = false;
}
@@ -627,6 +649,9 @@ varpool_externally_visible_p (struct varpool_node *vnode, bool aliased)
if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl))
return true;
+ if (DECL_EXTERNAL (vnode->symbol.decl))
+ return true;
+
if (!DECL_COMDAT (vnode->symbol.decl) && !TREE_PUBLIC (vnode->symbol.decl))
return false;