mirror of git://gcc.gnu.org/git/gcc.git
lto-symtab.c (lto_cgraph_replace_node): Do not call mark_reahcable_node.
* lto-symtab.c (lto_cgraph_replace_node): Do not call mark_reahcable_node. * cgraph.c (cgraph_remove_node): Do not clear reachable. (cgraph_mark_reachable_node): Remove. (cgraph_mark_force_output_node): Do not set reachable. (dump_cgraph_node): Do not dump reachable. (cgraph_create_virtual_clone): Do not set reachable. * cgraph.h (cgraph_node): Remove reachable flag. (varpool_node): Remove reachable flag. (cgraph_mark_if_needed): Remove. (cgraph_mark_reachable_node): Remove. * tree-emutls.c (ipa_lower_emutls): Do not check reachable. * cgraphunit.c (cgraph_finalize_function): Do not mark node as reachable. (cgraph_add_new_function): Likewise. (cgraph_mark_if_needed): Remove. (cgraph_analyze_function): Do not set target as reachable. (process_function_and_variable_attributes): Do not care about dllexport. (cgraph_analyze_functions): Do not set reachable flags. (cgraph_mark_functions_to_output): Do not check reachability. (cgraph_copy_node_for_versioning): Do not set reachable flag. (dbxout_expand_expr): Update. * c-decl.c (merge_decls): Do not track changed externs. * ipa.c: Include pointer-set.h (enqueue_cgraph_node): Use reachable pointer set. (process_references): Likewise. (cgraph_remove_unreachable_nodes): Likewise. (whole_program_function_and_variable_visibility): Do not recompute reachable. * trans-mem.c (ipa_tm_execute): Do not check reachable flag. From-SVN: r186700
This commit is contained in:
parent
da4343c3df
commit
93a18a7075
|
@ -1,3 +1,36 @@
|
|||
2012-04-23 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* lto-symtab.c (lto_cgraph_replace_node): Do not call
|
||||
mark_reahcable_node.
|
||||
* cgraph.c (cgraph_remove_node): Do not clear reachable.
|
||||
(cgraph_mark_reachable_node): Remove.
|
||||
(cgraph_mark_force_output_node): Do not set reachable.
|
||||
(dump_cgraph_node): Do not dump reachable.
|
||||
(cgraph_create_virtual_clone): Do not set reachable.
|
||||
* cgraph.h (cgraph_node): Remove reachable flag.
|
||||
(varpool_node): Remove reachable flag.
|
||||
(cgraph_mark_if_needed): Remove.
|
||||
(cgraph_mark_reachable_node): Remove.
|
||||
* tree-emutls.c (ipa_lower_emutls): Do not check
|
||||
reachable.
|
||||
* cgraphunit.c (cgraph_finalize_function): Do not mark node as
|
||||
reachable.
|
||||
(cgraph_add_new_function): Likewise.
|
||||
(cgraph_mark_if_needed): Remove.
|
||||
(cgraph_analyze_function): Do not set target as reachable.
|
||||
(process_function_and_variable_attributes): Do not care about dllexport.
|
||||
(cgraph_analyze_functions): Do not set reachable flags.
|
||||
(cgraph_mark_functions_to_output): Do not check reachability.
|
||||
(cgraph_copy_node_for_versioning): Do not set reachable flag.
|
||||
(dbxout_expand_expr): Update.
|
||||
* c-decl.c (merge_decls): Do not track changed externs.
|
||||
* ipa.c: Include pointer-set.h
|
||||
(enqueue_cgraph_node): Use reachable pointer set.
|
||||
(process_references): Likewise.
|
||||
(cgraph_remove_unreachable_nodes): Likewise.
|
||||
(whole_program_function_and_variable_visibility): Do not recompute reachable.
|
||||
* trans-mem.c (ipa_tm_execute): Do not check reachable flag.
|
||||
|
||||
2012-04-23 Georg-Johann Lay <avr@gjlay.de>
|
||||
|
||||
* doc/extend.texi (AVR Named Address Spaces): Fix typos.
|
||||
|
|
10
gcc/c-decl.c
10
gcc/c-decl.c
|
@ -2172,7 +2172,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
|||
&& prototype_p (TREE_TYPE (newdecl)));
|
||||
bool old_is_prototype = (TREE_CODE (olddecl) == FUNCTION_DECL
|
||||
&& prototype_p (TREE_TYPE (olddecl)));
|
||||
bool extern_changed = false;
|
||||
|
||||
/* For real parm decl following a forward decl, rechain the old decl
|
||||
in its new location and clear TREE_ASM_WRITTEN (it's not a
|
||||
|
@ -2443,8 +2442,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
|||
}
|
||||
}
|
||||
|
||||
extern_changed = DECL_EXTERNAL (olddecl) && !DECL_EXTERNAL (newdecl);
|
||||
|
||||
/* Merge the USED information. */
|
||||
if (TREE_USED (olddecl))
|
||||
TREE_USED (newdecl) = 1;
|
||||
|
@ -2506,13 +2503,6 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
|
|||
|| (TREE_CODE (olddecl) == VAR_DECL
|
||||
&& TREE_STATIC (olddecl))))
|
||||
make_decl_rtl (olddecl);
|
||||
|
||||
/* If we changed a function from DECL_EXTERNAL to !DECL_EXTERNAL,
|
||||
and the definition is coming from the old version, cgraph needs
|
||||
to be called again. */
|
||||
if (extern_changed && !new_is_definition
|
||||
&& TREE_CODE (olddecl) == FUNCTION_DECL && DECL_INITIAL (olddecl))
|
||||
cgraph_mark_if_needed (olddecl);
|
||||
}
|
||||
|
||||
/* Handle when a new declaration NEWDECL has the same name as an old
|
||||
|
|
28
gcc/cgraph.c
28
gcc/cgraph.c
|
@ -1344,7 +1344,7 @@ cgraph_remove_node (struct cgraph_node *node)
|
|||
|
||||
/* Incremental inlining access removed nodes stored in the postorder list.
|
||||
*/
|
||||
node->symbol.force_output = node->reachable = false;
|
||||
node->symbol.force_output = false;
|
||||
for (n = node->nested; n; n = n->next_nested)
|
||||
n->origin = NULL;
|
||||
node->nested = NULL;
|
||||
|
@ -1472,27 +1472,6 @@ cgraph_remove_node_and_inline_clones (struct cgraph_node *node, struct cgraph_no
|
|||
return found;
|
||||
}
|
||||
|
||||
/* Notify finalize_compilation_unit that given node is reachable. */
|
||||
|
||||
void
|
||||
cgraph_mark_reachable_node (struct cgraph_node *node)
|
||||
{
|
||||
if (!node->reachable && node->local.finalized)
|
||||
{
|
||||
if (cgraph_global_info_ready)
|
||||
{
|
||||
/* Verify that function does not appear to be needed out of blue
|
||||
during the optimization process. This can happen for extern
|
||||
inlines when bodies was removed after inlining. */
|
||||
gcc_assert ((node->analyzed || node->symbol.in_other_partition
|
||||
|| DECL_EXTERNAL (node->symbol.decl)));
|
||||
}
|
||||
else
|
||||
notice_global_symbol (node->symbol.decl);
|
||||
node->reachable = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Likewise indicate that a node is needed, i.e. reachable via some
|
||||
external means. */
|
||||
|
||||
|
@ -1501,7 +1480,6 @@ cgraph_mark_force_output_node (struct cgraph_node *node)
|
|||
{
|
||||
node->symbol.force_output = 1;
|
||||
gcc_assert (!node->global.inlined_to);
|
||||
cgraph_mark_reachable_node (node);
|
||||
}
|
||||
|
||||
/* Likewise indicate that a node is having address taken. */
|
||||
|
@ -1510,7 +1488,6 @@ void
|
|||
cgraph_mark_address_taken_node (struct cgraph_node *node)
|
||||
{
|
||||
gcc_assert (!node->global.inlined_to);
|
||||
cgraph_mark_reachable_node (node);
|
||||
/* FIXME: address_taken flag is used both as a shortcut for testing whether
|
||||
IPA_REF_ADDR reference exists (and thus it should be set on node
|
||||
representing alias we take address of) and as a test whether address
|
||||
|
@ -1621,8 +1598,6 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
|
|||
(HOST_WIDEST_INT)node->count);
|
||||
if (node->origin)
|
||||
fprintf (f, " nested in: %s", cgraph_node_asm_name (node->origin));
|
||||
else if (node->reachable)
|
||||
fprintf (f, " reachable");
|
||||
if (gimple_has_body_p (node->symbol.decl))
|
||||
fprintf (f, " body");
|
||||
if (node->process)
|
||||
|
@ -2048,7 +2023,6 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
|
|||
new_node->symbol.externally_visible = 0;
|
||||
new_node->local.local = 1;
|
||||
new_node->lowered = true;
|
||||
new_node->reachable = true;
|
||||
|
||||
cgraph_call_node_duplication_hooks (old_node, new_node);
|
||||
|
||||
|
|
12
gcc/cgraph.h
12
gcc/cgraph.h
|
@ -248,13 +248,6 @@ struct GTY(()) cgraph_node {
|
|||
/* Set when decl is an abstract function pointed to by the
|
||||
ABSTRACT_DECL_ORIGIN of a reachable function. */
|
||||
unsigned abstract_and_needed : 1;
|
||||
/* Set when function is reachable by call from other function
|
||||
that is either reachable or needed.
|
||||
This flag is computed at original cgraph construction and then
|
||||
updated in cgraph_remove_unreachable_nodes. Note that after
|
||||
cgraph_remove_unreachable_nodes cgraph still can contain unreachable
|
||||
nodes when they are needed for virtual clone instantiation. */
|
||||
unsigned reachable : 1;
|
||||
/* Set once the function is lowered (i.e. its CFG is built). */
|
||||
unsigned lowered : 1;
|
||||
/* Set once the function has been instantiated and its callee
|
||||
|
@ -416,9 +409,6 @@ struct GTY(()) varpool_node {
|
|||
/* For aliases points to declaration DECL is alias of. */
|
||||
tree alias_of;
|
||||
|
||||
/* Set when function must be output - it is externally visible
|
||||
or its address is taken. */
|
||||
unsigned needed : 1;
|
||||
/* Set once the variable has been instantiated and its callee
|
||||
lists created. */
|
||||
unsigned analyzed : 1;
|
||||
|
@ -589,13 +579,11 @@ VEC (cgraph_edge_p, heap) * collect_callers_of_node (struct cgraph_node *node);
|
|||
/* In cgraphunit.c */
|
||||
extern FILE *cgraph_dump_file;
|
||||
void cgraph_finalize_function (tree, bool);
|
||||
void cgraph_mark_if_needed (tree);
|
||||
void cgraph_analyze_function (struct cgraph_node *);
|
||||
void cgraph_finalize_compilation_unit (void);
|
||||
void cgraph_optimize (void);
|
||||
void cgraph_mark_force_output_node (struct cgraph_node *);
|
||||
void cgraph_mark_address_taken_node (struct cgraph_node *);
|
||||
void cgraph_mark_reachable_node (struct cgraph_node *);
|
||||
bool cgraph_inline_p (struct cgraph_edge *, cgraph_inline_failed_t *reason);
|
||||
bool cgraph_preserve_function_body_p (struct cgraph_node *);
|
||||
void verify_cgraph (void);
|
||||
|
|
|
@ -362,9 +362,6 @@ cgraph_finalize_function (tree decl, bool nested)
|
|||
&& !DECL_COMDAT (decl) && !DECL_EXTERNAL (decl))
|
||||
node->symbol.force_output = 1;
|
||||
|
||||
if (cgraph_decide_is_function_needed (node, decl))
|
||||
cgraph_mark_reachable_node (node);
|
||||
|
||||
/* If we've not yet emitted decl, tell the debug info about it. */
|
||||
if (!TREE_ASM_WRITTEN (decl))
|
||||
(*debug_hooks->deferred_inline_function) (decl);
|
||||
|
@ -416,7 +413,7 @@ cgraph_add_new_function (tree fndecl, bool lowered)
|
|||
node = cgraph_get_create_node (fndecl);
|
||||
node->local.local = false;
|
||||
node->local.finalized = true;
|
||||
node->reachable = node->symbol.force_output = true;
|
||||
node->symbol.force_output = true;
|
||||
if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION)
|
||||
{
|
||||
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
|
||||
|
@ -468,18 +465,6 @@ cgraph_add_new_function (tree fndecl, bool lowered)
|
|||
DECL_FUNCTION_PERSONALITY (fndecl) = lang_hooks.eh_personality ();
|
||||
}
|
||||
|
||||
/* C99 extern inline keywords allow changing of declaration after function
|
||||
has been finalized. We need to re-decide if we want to mark the function as
|
||||
needed then. */
|
||||
|
||||
void
|
||||
cgraph_mark_if_needed (tree decl)
|
||||
{
|
||||
struct cgraph_node *node = cgraph_get_node (decl);
|
||||
if (node->local.finalized && cgraph_decide_is_function_needed (node, decl))
|
||||
cgraph_mark_reachable_node (node);
|
||||
}
|
||||
|
||||
/* Return TRUE if NODE2 is equivalent to NODE or its clone. */
|
||||
static bool
|
||||
clone_of_p (struct cgraph_node *node, struct cgraph_node *node2)
|
||||
|
@ -916,7 +901,6 @@ cgraph_analyze_function (struct cgraph_node *node)
|
|||
if (!VEC_length (ipa_ref_t, node->symbol.ref_list.references))
|
||||
ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
|
||||
IPA_REF_ALIAS, NULL);
|
||||
cgraph_mark_reachable_node (tgt);
|
||||
if (node->same_body_alias)
|
||||
{
|
||||
DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (node->thunk.alias);
|
||||
|
@ -952,11 +936,8 @@ cgraph_analyze_function (struct cgraph_node *node)
|
|||
}
|
||||
}
|
||||
}
|
||||
cgraph_mark_reachable_node (cgraph_alias_aliased_node (node));
|
||||
if (node->symbol.address_taken)
|
||||
cgraph_mark_address_taken_node (cgraph_alias_aliased_node (node));
|
||||
if (cgraph_decide_is_function_needed (node, node->symbol.decl))
|
||||
cgraph_mark_reachable_node (node);
|
||||
}
|
||||
else if (node->thunk.thunk_p)
|
||||
{
|
||||
|
@ -1078,21 +1059,12 @@ process_function_and_variable_attributes (struct cgraph_node *first,
|
|||
tree decl = node->symbol.decl;
|
||||
if (DECL_PRESERVE_P (decl))
|
||||
cgraph_mark_force_output_node (node);
|
||||
if (TARGET_DLLIMPORT_DECL_ATTRIBUTES
|
||||
&& lookup_attribute ("dllexport", DECL_ATTRIBUTES (decl))
|
||||
&& TREE_PUBLIC (node->symbol.decl))
|
||||
{
|
||||
if (node->local.finalized)
|
||||
cgraph_mark_reachable_node (node);
|
||||
}
|
||||
else if (lookup_attribute ("externally_visible", DECL_ATTRIBUTES (decl)))
|
||||
{
|
||||
if (! TREE_PUBLIC (node->symbol.decl))
|
||||
warning_at (DECL_SOURCE_LOCATION (node->symbol.decl), OPT_Wattributes,
|
||||
"%<externally_visible%>"
|
||||
" attribute have effect only on public objects");
|
||||
else if (node->local.finalized)
|
||||
cgraph_mark_reachable_node (node);
|
||||
}
|
||||
if (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl))
|
||||
&& (node->local.finalized && !node->alias))
|
||||
|
@ -1280,11 +1252,8 @@ cgraph_analyze_functions (void)
|
|||
cgraph_analyze_function (cnode);
|
||||
|
||||
for (edge = cnode->callees; edge; edge = edge->next_callee)
|
||||
{
|
||||
cgraph_mark_reachable_node (edge->callee);
|
||||
if (edge->callee->local.finalized)
|
||||
enqueue_node ((symtab_node)edge->callee);
|
||||
}
|
||||
if (edge->callee->local.finalized)
|
||||
enqueue_node ((symtab_node)edge->callee);
|
||||
|
||||
/* If decl is a clone of an abstract function, mark that abstract
|
||||
function so that we don't release its body. The DECL_INITIAL() of that
|
||||
|
@ -1300,9 +1269,7 @@ cgraph_analyze_functions (void)
|
|||
}
|
||||
else if (symtab_variable_p (node)
|
||||
&& varpool (node)->finalized)
|
||||
{
|
||||
varpool_analyze_node (varpool (node));
|
||||
}
|
||||
varpool_analyze_node (varpool (node));
|
||||
|
||||
if (node->symbol.same_comdat_group)
|
||||
{
|
||||
|
@ -1479,9 +1446,6 @@ cgraph_mark_functions_to_output (void)
|
|||
&& !node->thunk.thunk_p
|
||||
&& !node->alias
|
||||
&& !node->global.inlined_to
|
||||
&& (!cgraph_only_called_directly_p (node)
|
||||
|| ((e || ipa_ref_has_aliases_p (&node->symbol.ref_list))
|
||||
&& node->reachable))
|
||||
&& !TREE_ASM_WRITTEN (decl)
|
||||
&& !DECL_EXTERNAL (decl))
|
||||
{
|
||||
|
@ -2085,7 +2049,6 @@ cgraph_expand_all_functions (void)
|
|||
node = order[i];
|
||||
if (node->process)
|
||||
{
|
||||
gcc_assert (node->reachable);
|
||||
node->process = 0;
|
||||
cgraph_expand_function (node);
|
||||
}
|
||||
|
@ -2370,7 +2333,6 @@ cgraph_copy_node_for_versioning (struct cgraph_node *old_version,
|
|||
new_version->local.local = old_version->analyzed;
|
||||
new_version->global = old_version->global;
|
||||
new_version->rtl = old_version->rtl;
|
||||
new_version->reachable = true;
|
||||
new_version->count = old_version->count;
|
||||
|
||||
for (e = old_version->callees; e; e=e->next_callee)
|
||||
|
|
|
@ -2483,7 +2483,7 @@ dbxout_expand_expr (tree expr)
|
|||
return NULL, otherwise stabs might reference an undefined
|
||||
symbol. */
|
||||
struct varpool_node *node = varpool_get_node (expr);
|
||||
if (!node || !node->needed)
|
||||
if (!node || !node->analyzed)
|
||||
return NULL;
|
||||
}
|
||||
/* FALLTHRU */
|
||||
|
|
114
gcc/ipa.c
114
gcc/ipa.c
|
@ -32,6 +32,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "target.h"
|
||||
#include "tree-iterator.h"
|
||||
#include "ipa-utils.h"
|
||||
#include "pointer-set.h"
|
||||
|
||||
/* Look for all functions inlined to NODE and update their inlined_to pointers
|
||||
to INLINED_TO. */
|
||||
|
@ -57,14 +58,15 @@ update_inlined_to_pointer (struct cgraph_node *node, struct cgraph_node *inlined
|
|||
reachable. */
|
||||
|
||||
static void
|
||||
enqueue_cgraph_node (struct cgraph_node *node, struct cgraph_node **first)
|
||||
enqueue_cgraph_node (struct cgraph_node *node, struct cgraph_node **first,
|
||||
struct pointer_set_t *reachable)
|
||||
{
|
||||
/* Node is still in queue; do nothing. */
|
||||
if (node->symbol.aux && node->symbol.aux != (void *) 2)
|
||||
return;
|
||||
/* Node was already processed as unreachable, re-enqueue
|
||||
only if it became reachable now. */
|
||||
if (node->symbol.aux == (void *)2 && !node->reachable)
|
||||
if (node->symbol.aux == (void *)2 && !pointer_set_contains (reachable, node))
|
||||
return;
|
||||
node->symbol.aux = *first;
|
||||
*first = node;
|
||||
|
@ -85,7 +87,8 @@ static void
|
|||
process_references (struct ipa_ref_list *list,
|
||||
struct cgraph_node **first,
|
||||
struct varpool_node **first_varpool,
|
||||
bool before_inlining_p)
|
||||
bool before_inlining_p,
|
||||
struct pointer_set_t *reachable)
|
||||
{
|
||||
int i;
|
||||
struct ipa_ref *ref;
|
||||
|
@ -94,22 +97,18 @@ process_references (struct ipa_ref_list *list,
|
|||
if (symtab_function_p (ref->referred))
|
||||
{
|
||||
struct cgraph_node *node = ipa_ref_node (ref);
|
||||
if (!node->reachable
|
||||
&& node->analyzed
|
||||
if (node->analyzed
|
||||
&& (!DECL_EXTERNAL (node->symbol.decl)
|
||||
|| node->alias
|
||||
|| before_inlining_p))
|
||||
node->reachable = true;
|
||||
enqueue_cgraph_node (node, first);
|
||||
pointer_set_insert (reachable, node);
|
||||
enqueue_cgraph_node (node, first, reachable);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct varpool_node *node = ipa_ref_varpool_node (ref);
|
||||
if (!node->needed)
|
||||
{
|
||||
node->needed = true;
|
||||
enqueue_varpool_node (node, first_varpool);
|
||||
}
|
||||
if (!pointer_set_insert (reachable, node))
|
||||
enqueue_varpool_node (node, first_varpool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -175,6 +174,7 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
struct cgraph_node *node, *next;
|
||||
struct varpool_node *vnode, *vnext;
|
||||
bool changed = false;
|
||||
struct pointer_set_t *reachable = pointer_set_create ();
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
verify_symtab ();
|
||||
|
@ -200,14 +200,11 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
&& (DECL_COMDAT (node->symbol.decl) || DECL_EXTERNAL (node->symbol.decl)))))
|
||||
{
|
||||
gcc_assert (!node->global.inlined_to);
|
||||
enqueue_cgraph_node (node, &first);
|
||||
node->reachable = true;
|
||||
enqueue_cgraph_node (node, &first, reachable);
|
||||
pointer_set_insert (reachable, node);
|
||||
}
|
||||
else
|
||||
{
|
||||
gcc_assert (!node->symbol.aux);
|
||||
node->reachable = false;
|
||||
}
|
||||
gcc_assert (!node->symbol.aux);
|
||||
|
||||
/* Mark variables that are obviously needed. */
|
||||
FOR_EACH_VARIABLE (vnode)
|
||||
|
@ -215,11 +212,9 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
if ((vnode->analyzed || vnode->symbol.force_output)
|
||||
&& !varpool_can_remove_if_no_refs (vnode))
|
||||
{
|
||||
vnode->needed = true;
|
||||
pointer_set_insert (reachable, vnode);
|
||||
enqueue_varpool_node (vnode, &first_varpool);
|
||||
}
|
||||
else
|
||||
vnode->needed = false;
|
||||
}
|
||||
|
||||
/* Perform reachability analysis. As a special case do not consider
|
||||
|
@ -237,44 +232,39 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
struct cgraph_edge *e;
|
||||
node = first;
|
||||
first = (struct cgraph_node *) first->symbol.aux;
|
||||
if (!node->reachable)
|
||||
if (!pointer_set_contains (reachable, node))
|
||||
node->symbol.aux = (void *)2;
|
||||
|
||||
/* If we found this node reachable, first mark on the callees
|
||||
reachable too, unless they are direct calls to extern inline functions
|
||||
we decided to not inline. */
|
||||
if (node->reachable)
|
||||
else
|
||||
{
|
||||
for (e = node->callees; e; e = e->next_callee)
|
||||
{
|
||||
if (!e->callee->reachable
|
||||
&& node->analyzed
|
||||
if (node->analyzed
|
||||
&& (!e->inline_failed
|
||||
|| !DECL_EXTERNAL (e->callee->symbol.decl)
|
||||
|| node->alias
|
||||
|| before_inlining_p))
|
||||
e->callee->reachable = true;
|
||||
enqueue_cgraph_node (e->callee, &first);
|
||||
pointer_set_insert (reachable, e->callee);
|
||||
enqueue_cgraph_node (e->callee, &first, reachable);
|
||||
}
|
||||
process_references (&node->symbol.ref_list, &first,
|
||||
&first_varpool, before_inlining_p);
|
||||
}
|
||||
&first_varpool, before_inlining_p,
|
||||
reachable);
|
||||
|
||||
/* If any function in a comdat group is reachable, force
|
||||
all other functions in the same comdat group to be
|
||||
also reachable. */
|
||||
if (node->symbol.same_comdat_group
|
||||
&& node->reachable
|
||||
&& !node->global.inlined_to)
|
||||
{
|
||||
for (next = cgraph (node->symbol.same_comdat_group);
|
||||
next != node;
|
||||
next = cgraph (next->symbol.same_comdat_group))
|
||||
if (!next->reachable)
|
||||
{
|
||||
next->reachable = true;
|
||||
enqueue_cgraph_node (next, &first);
|
||||
}
|
||||
/* If any function in a comdat group is reachable, force
|
||||
all other functions in the same comdat group to be
|
||||
also reachable. */
|
||||
if (node->symbol.same_comdat_group
|
||||
&& !node->global.inlined_to)
|
||||
{
|
||||
for (next = cgraph (node->symbol.same_comdat_group);
|
||||
next != node;
|
||||
next = cgraph (next->symbol.same_comdat_group))
|
||||
if (!pointer_set_insert (reachable, next))
|
||||
enqueue_cgraph_node (next, &first, reachable);
|
||||
}
|
||||
}
|
||||
|
||||
/* We can freely remove inline clones even if they are cloned, however if
|
||||
|
@ -286,9 +276,9 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
{
|
||||
bool noninline = node->clone_of->symbol.decl != node->symbol.decl;
|
||||
node = node->clone_of;
|
||||
if (noninline && !node->reachable && !node->symbol.aux)
|
||||
if (noninline && !pointer_set_insert (reachable, node) && !node->symbol.aux)
|
||||
{
|
||||
enqueue_cgraph_node (node, &first);
|
||||
enqueue_cgraph_node (node, &first, reachable);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +289,8 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
first_varpool = (struct varpool_node *)first_varpool->symbol.aux;
|
||||
vnode->symbol.aux = NULL;
|
||||
process_references (&vnode->symbol.ref_list, &first,
|
||||
&first_varpool, before_inlining_p);
|
||||
&first_varpool, before_inlining_p,
|
||||
reachable);
|
||||
/* If any function in a comdat group is reachable, force
|
||||
all other functions in the same comdat group to be
|
||||
also reachable. */
|
||||
|
@ -309,11 +300,8 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
for (next = varpool (vnode->symbol.same_comdat_group);
|
||||
next != vnode;
|
||||
next = varpool (next->symbol.same_comdat_group))
|
||||
if (!next->needed)
|
||||
{
|
||||
next->needed = true;
|
||||
enqueue_varpool_node (next, &first_varpool);
|
||||
}
|
||||
if (!pointer_set_insert (reachable, next))
|
||||
enqueue_varpool_node (next, &first_varpool);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -330,7 +318,7 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
for (node = cgraph_first_function (); node; node = next)
|
||||
{
|
||||
next = cgraph_next_function (node);
|
||||
if (node->symbol.aux && !node->reachable)
|
||||
if (node->symbol.aux && !pointer_set_contains (reachable, node))
|
||||
{
|
||||
cgraph_node_remove_callees (node);
|
||||
ipa_remove_all_references (&node->symbol.ref_list);
|
||||
|
@ -348,16 +336,12 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
fprintf (file, " %s", cgraph_node_name (node));
|
||||
/* See if there is reachable caller. */
|
||||
for (e = node->callers; e && !found; e = e->next_caller)
|
||||
if (e->caller->reachable)
|
||||
if (pointer_set_contains (reachable, e->caller))
|
||||
found = true;
|
||||
for (i = 0; (ipa_ref_list_referring_iterate (&node->symbol.ref_list,
|
||||
i, ref)
|
||||
&& !found); i++)
|
||||
if (symtab_function_p (ref->referring)
|
||||
&& ipa_ref_referring_node (ref)->reachable)
|
||||
found = true;
|
||||
else if (symtab_variable_p (ref->referring)
|
||||
&& ipa_ref_referring_varpool_node (ref)->needed)
|
||||
if (pointer_set_contains (reachable, ref->referring))
|
||||
found = true;
|
||||
|
||||
/* If so, we need to keep node in the callgraph. */
|
||||
|
@ -426,7 +410,7 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
for (vnode = varpool_first_variable (); vnode; vnode = vnext)
|
||||
{
|
||||
vnext = varpool_next_variable (vnode);
|
||||
if (!vnode->needed)
|
||||
if (!pointer_set_contains (reachable, vnode))
|
||||
{
|
||||
if (file)
|
||||
fprintf (file, " %s", varpool_node_name (vnode));
|
||||
|
@ -471,6 +455,7 @@ cgraph_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
|
|||
/* Reclaim alias pairs for functions that have disappeared from the
|
||||
call graph. */
|
||||
remove_unreachable_alias_pairs ();
|
||||
pointer_set_destroy (reachable);
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
@ -1010,14 +995,7 @@ gate_whole_program_function_and_variable_visibility (void)
|
|||
static unsigned int
|
||||
whole_program_function_and_variable_visibility (void)
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
|
||||
function_and_variable_visibility (flag_whole_program);
|
||||
|
||||
FOR_EACH_DEFINED_FUNCTION (node)
|
||||
if ((node->symbol.externally_visible && !DECL_COMDAT (node->symbol.decl))
|
||||
&& node->local.finalized)
|
||||
cgraph_mark_reachable_node (node);
|
||||
if (optimize)
|
||||
ipa_discover_readonly_nonaddressable_vars ();
|
||||
return 0;
|
||||
|
|
|
@ -225,8 +225,6 @@ lto_cgraph_replace_node (struct cgraph_node *node,
|
|||
/* Merge node flags. */
|
||||
if (node->symbol.force_output)
|
||||
cgraph_mark_force_output_node (prevailing_node);
|
||||
if (node->reachable)
|
||||
cgraph_mark_reachable_node (prevailing_node);
|
||||
if (node->symbol.address_taken)
|
||||
{
|
||||
gcc_assert (!prevailing_node->global.inlined_to);
|
||||
|
|
|
@ -4779,7 +4779,7 @@ ipa_tm_execute (void)
|
|||
|
||||
/* For all local reachable functions... */
|
||||
FOR_EACH_DEFINED_FUNCTION (node)
|
||||
if (node->reachable && node->lowered
|
||||
if (node->lowered
|
||||
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
|
||||
{
|
||||
/* ... marked tm_pure, record that fact for the runtime by
|
||||
|
@ -4947,7 +4947,7 @@ ipa_tm_execute (void)
|
|||
/* Now validate all tm_safe functions, and all atomic regions in
|
||||
other functions. */
|
||||
FOR_EACH_DEFINED_FUNCTION (node)
|
||||
if (node->reachable && node->lowered
|
||||
if (node->lowered
|
||||
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
|
||||
{
|
||||
d = get_cg_data (&node, true);
|
||||
|
@ -4995,7 +4995,7 @@ ipa_tm_execute (void)
|
|||
}
|
||||
}
|
||||
FOR_EACH_DEFINED_FUNCTION (node)
|
||||
if (node->reachable && node->lowered
|
||||
if (node->lowered
|
||||
&& cgraph_function_body_availability (node) >= AVAIL_OVERWRITABLE)
|
||||
{
|
||||
d = get_cg_data (&node, true);
|
||||
|
|
|
@ -791,7 +791,7 @@ ipa_lower_emutls (void)
|
|||
|
||||
/* Adjust all uses of TLS variables within the function bodies. */
|
||||
FOR_EACH_DEFINED_FUNCTION (func)
|
||||
if (func->reachable && func->lowered)
|
||||
if (func->lowered)
|
||||
lower_emutls_function_body (func);
|
||||
|
||||
/* Generate the constructor for any COMMON control variables created. */
|
||||
|
|
Loading…
Reference in New Issue