diff options
Diffstat (limited to 'gcc-4.9/gcc/ipa.c')
-rw-r--r-- | gcc-4.9/gcc/ipa.c | 23 |
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; } |