aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2012-05-17 18:37:33 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2012-05-17 16:37:33 +0000
commit6649df51ec79ed1ffe81dc8b93b7fc8cce85040f (patch)
treec091b61bf18ed877244605adef29bd8f35c140b1 /gcc/ipa.c
parentf9eead1f8953869fcfd8be7b0e58aff50fbe1fd5 (diff)
downloadgcc-6649df51ec79ed1ffe81dc8b93b7fc8cce85040f.zip
gcc-6649df51ec79ed1ffe81dc8b93b7fc8cce85040f.tar.gz
gcc-6649df51ec79ed1ffe81dc8b93b7fc8cce85040f.tar.bz2
lto-symtab.c (lto_symtab_resolve_symbols): Preffer decl with constructor over decl without.
* 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. From-SVN: r187631
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 a107c6f..cafa7a1 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;