aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.9/gcc/ipa.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.9/gcc/ipa.c')
-rw-r--r--gcc-4.9/gcc/ipa.c23
1 files changed, 18 insertions, 5 deletions
diff --git a/gcc-4.9/gcc/ipa.c b/gcc-4.9/gcc/ipa.c
index d23031286..26e9b03b9 100644
--- a/gcc-4.9/gcc/ipa.c
+++ b/gcc-4.9/gcc/ipa.c
@@ -139,7 +139,10 @@ process_references (struct ipa_ref_list *list,
if (node->definition && !node->in_other_partition
&& ((!DECL_EXTERNAL (node->decl) || node->alias)
- || (before_inlining_p
+ || (((before_inlining_p
+ && (cgraph_state < CGRAPH_STATE_IPA_SSA
+ || !lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (node->decl)))))
/* We use variable constructors during late complation for
constant folding. Keep references alive so partitioning
knows about potential references. */
@@ -191,7 +194,10 @@ walk_polymorphic_call_targets (pointer_set_t *reachable_call_targets,
/* Prior inlining, keep alive bodies of possible targets for
devirtualization. */
if (n->definition
- && before_inlining_p)
+ && (before_inlining_p
+ && (cgraph_state < CGRAPH_STATE_IPA_SSA
+ || !lookup_attribute ("always_inline",
+ DECL_ATTRIBUTES (n->decl)))))
pointer_set_insert (reachable, n);
/* Even after inlining we want to keep the possible targets in the
@@ -469,7 +475,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
if (!node->aux)
{
if (file)
- fprintf (file, " %s", node->name ());
+ fprintf (file, " %s/%i", node->name (), node->order);
cgraph_remove_node (node);
changed = true;
}
@@ -483,7 +489,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
if (node->definition)
{
if (file)
- fprintf (file, " %s", node->name ());
+ fprintf (file, " %s/%i", node->name (), node->order);
node->body_removed = true;
node->analyzed = false;
node->definition = false;
@@ -491,6 +497,12 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
node->alias = false;
node->thunk.thunk_p = false;
node->weakref = false;
+ /* After early inlining we drop always_inline attributes on
+ bodies of functions that are still referenced (have their
+ address taken). */
+ DECL_ATTRIBUTES (node->decl)
+ = remove_attribute ("always_inline",
+ DECL_ATTRIBUTES (node->decl));
if (!node->in_other_partition)
node->local.local = false;
cgraph_node_remove_callees (node);
@@ -531,7 +543,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
&& (!flag_ltrans || !DECL_EXTERNAL (vnode->decl)))
{
if (file)
- fprintf (file, " %s", vnode->name ());
+ fprintf (file, " %s/%i", vnode->name (), vnode->order);
varpool_remove_node (vnode);
changed = true;
}
@@ -1020,6 +1032,7 @@ function_and_variable_visibility (bool whole_program)
== DECL_COMDAT_GROUP (decl_node->decl));
gcc_checking_assert (node->same_comdat_group);
}
+ node->forced_by_abi = decl_node->forced_by_abi;
if (DECL_EXTERNAL (decl_node->decl))
DECL_EXTERNAL (node->decl) = 1;
}