From: Richard Biener Date: Thu, 11 Jun 2015 13:39:56 +0000 (+0000) Subject: backport: [multiple changes] X-Git-Tag: releases/gcc-4.8.5~74 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=08568dc747d3e32e58677afb8ec8d5a6db40c90b;p=thirdparty%2Fgcc.git backport: [multiple changes] 2015-06-11 Richard Biener Backport from mainline, guarded with in_lto_p 2015-06-02 Richard Biener PR debug/65549 * dwarf2out.c (lookup_context_die): New function. (resolve_addr): Avoid forcing a full DIE for the target of a DW_TAG_GNU_call_site during late compilation. Instead create a stub DIE without a type if we have a context DIE present. Backport from mainline 2014-04-04 Jan Hubicka PR ipa/59626 * lto-cgraph.c (input_overwrite_node): Check that partitioning flags are set only during streaming. * ipa.c (process_references, symtab_remove_unreachable_nodes): Drop bodies of always inline after early inlining. (symtab_remove_unreachable_nodes): Remove always_inline attribute. * gcc.dg/lto/pr59626_0.c: New testcase. * gcc.dg/lto/pr59626_1.c: New testcase. From-SVN: r224375 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index bfad913c3faf..19f4fe346ff7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,23 @@ +2015-06-11 Richard Biener + + Backport from mainline, guarded with in_lto_p + 2015-06-02 Richard Biener + + PR debug/65549 + * dwarf2out.c (lookup_context_die): New function. + (resolve_addr): Avoid forcing a full DIE for the + target of a DW_TAG_GNU_call_site during late compilation. + Instead create a stub DIE without a type if we have a + context DIE present. + + Backport from mainline + 2014-04-04 Jan Hubicka + + PR ipa/59626 + * ipa.c (process_references, symtab_remove_unreachable_nodes): + Drop bodies of always inline after early inlining. + (symtab_remove_unreachable_nodes): Remove always_inline attribute. + 2015-06-10 Michael Meissner Backport from mainline: diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index c04f8136c85c..9018a461f5fe 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -19697,6 +19697,28 @@ is_naming_typedef_decl (const_tree decl) != TYPE_NAME (TREE_TYPE (decl)))); } +/* Looks up the DIE for a context. */ + +static inline dw_die_ref +lookup_context_die (tree context) +{ + if (context) + { + /* Find die that represents this context. */ + if (TYPE_P (context)) + { + context = TYPE_MAIN_VARIANT (context); + dw_die_ref ctx = lookup_type_die (context); + if (!ctx) + return NULL; + return strip_naming_typedef (context, ctx); + } + else + return lookup_decl_die (context); + } + return comp_unit_die (); +} + /* Returns the DIE for a context. */ static inline dw_die_ref @@ -22751,8 +22773,25 @@ resolve_addr (dw_die_ref die) && DECL_EXTERNAL (tdecl) && DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE) { - force_decl_die (tdecl); - tdie = lookup_decl_die (tdecl); + dw_die_ref cdie; + if (!in_lto_p) + { + force_decl_die (tdecl); + tdie = lookup_decl_die (tdecl); + } + else if ((cdie = lookup_context_die (DECL_CONTEXT (tdecl)))) + { + /* Creating a full DIE for tdecl is overly expensive and + at this point even wrong when in the LTO phase + as it can end up generating new type DIEs we didn't + output and thus optimize_external_refs will crash. */ + tdie = new_die (DW_TAG_subprogram, cdie, NULL_TREE); + add_AT_flag (tdie, DW_AT_external, 1); + add_AT_flag (tdie, DW_AT_declaration, 1); + add_linkage_attr (tdie, tdecl); + add_name_and_src_coords_attributes (tdie, tdecl); + equate_decl_number_to_die (tdecl, tdie); + } } if (tdie) { diff --git a/gcc/ipa.c b/gcc/ipa.c index d73d105a0c49..be377a70e1df 100644 --- a/gcc/ipa.c +++ b/gcc/ipa.c @@ -90,7 +90,11 @@ process_references (struct ipa_ref_list *list, if (node->analyzed && (!DECL_EXTERNAL (node->symbol.decl) || node->alias - || before_inlining_p)) + || (before_inlining_p + && (cgraph_state < CGRAPH_STATE_IPA_SSA + || !lookup_attribute + ("always_inline", + DECL_ATTRIBUTES (node->symbol.decl)))))) pointer_set_insert (reachable, node); enqueue_node ((symtab_node) node, first, reachable); } @@ -361,6 +365,12 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) fprintf (file, " %s", cgraph_node_name (node)); node->alias = false; node->thunk.thunk_p = false; + /* After early inlining we drop always_inline attributes on + bodies of functions that are still referenced (have their + address taken). */ + DECL_ATTRIBUTES (node->symbol.decl) + = remove_attribute ("always_inline", + DECL_ATTRIBUTES (node->symbol.decl)); cgraph_node_remove_callees (node); ipa_remove_all_references (&node->symbol.ref_list); changed = true; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index a66ec2ec0bdc..5fa80fd1dd4b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,12 @@ +2015-06-11 Richard Biener + + Backport from mainline + 2014-04-04 Jan Hubicka + + PR ipa/59626 + * gcc.dg/lto/pr59626_0.c: New testcase. + * gcc.dg/lto/pr59626_1.c: New testcase. + 2015-06-10 Richard Biener Backport from mainline diff --git a/gcc/testsuite/gcc.dg/lto/pr59626_0.c b/gcc/testsuite/gcc.dg/lto/pr59626_0.c new file mode 100644 index 000000000000..752982fb506d --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr59626_0.c @@ -0,0 +1,15 @@ +/* { dg-lto-do run } */ + +int __atoi (const char *) __asm__("atoi"); +extern inline __attribute__((always_inline,gnu_inline)) +int atoi (const char *x) +{ + return __atoi (x); +} + +int bar (int (*)(const char *)); + +int main() +{ + return bar (atoi); +} diff --git a/gcc/testsuite/gcc.dg/lto/pr59626_1.c b/gcc/testsuite/gcc.dg/lto/pr59626_1.c new file mode 100644 index 000000000000..9b3fa1d2e369 --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr59626_1.c @@ -0,0 +1,4 @@ +int bar (int (*fn)(const char *)) +{ + return fn ("0"); +}