This extends the trick of invoking late-global-decl on optimized out vars which are removed after early-finish. This avoids the need to get debug info for them via other ways, like forced emission via dwarf2out-abstact-function.
This avoids regressing gcc.dg/debug/dwarf2/inline3.c when the dwarf2out-abstact-function is essentially removed with the early LTO patches (the early emitted DIEs provide the abstract copy). Boostrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2016-10-20 Richard Biener <rguent...@suse.de> * cgraphunit.c (analyze_functions): Set node->definition to false to signal symbol removal to debug_hooks->late_global_decl. * ipa.c (symbol_table::remove_unreachable_nodes): When not in WPA signal symbol removal to the debuginfo machinery. * dwarf2out.c (dwarf2out_late_global_decl): Instead of using early_finised to guard the we're called for symbol removal case look at the symtabs definition flag. (gen_variable_die): Remove redundant check. Index: gcc/cgraphunit.c =================================================================== --- gcc/cgraphunit.c (revision 241339) +++ gcc/cgraphunit.c (working copy) @@ -1208,6 +1208,7 @@ analyze_functions (bool first_time) so they effectively appear as readonly. Show that to the debug machinery. */ TREE_READONLY (node->decl) = 1; + node->definition = false; (*debug_hooks->late_global_decl) (node->decl); } Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 241339) +++ gcc/dwarf2out.c (working copy) @@ -21264,7 +21264,6 @@ gen_variable_die (tree decl, tree origin tree ultimate_origin; dw_die_ref var_die; dw_die_ref old_die = decl ? lookup_decl_die (decl) : NULL; - dw_die_ref origin_die = NULL; bool declaration = (DECL_EXTERNAL (decl_or_origin) || class_or_namespace_scope_p (context_die)); bool specialization_p = false; @@ -21424,7 +21423,7 @@ gen_variable_die (tree decl, tree origin var_die = new_die (DW_TAG_variable, context_die, decl); if (origin != NULL) - origin_die = add_abstract_origin_attribute (var_die, origin); + add_abstract_origin_attribute (var_die, origin); /* Loop unrolling can create multiple blocks that refer to the same static variable, so we must test for the DW_AT_declaration flag. @@ -21500,10 +21499,7 @@ gen_variable_die (tree decl, tree origin already set. */ || (VAR_P (decl_or_origin) && TREE_STATIC (decl_or_origin) - && DECL_RTL_SET_P (decl_or_origin))) - /* When abstract origin already has DW_AT_location attribute, no need - to add it again. */ - && (origin_die == NULL || get_AT (origin_die, DW_AT_location) == NULL)) + && DECL_RTL_SET_P (decl_or_origin)))) { if (early_dwarf) add_pubname (decl_or_origin, var_die); @@ -23969,11 +23965,11 @@ dwarf2out_late_global_decl (tree decl) if (die) { - /* We get called during the early debug phase via the symtab - code invoking late_global_decl for symbols that are optimized - out. When the early phase is not finished, do not add - locations. */ - if (! early_dwarf_finished) + /* We get called via the symtab code invoking late_global_decl + for symbols that are optimized out. Do not add locations + for those. */ + varpool_node *node = varpool_node::get (decl); + if (! node || ! node->definition) tree_add_const_value_attribute_for_decl (die, decl); else add_location_or_const_value_attribute (die, decl, false); Index: gcc/ipa.c =================================================================== --- gcc/ipa.c (revision 241339) +++ gcc/ipa.c (working copy) @@ -36,6 +36,7 @@ along with GCC; see the file COPYING3. #include "ipa-prop.h" #include "ipa-inline.h" #include "dbgcnt.h" +#include "debug.h" /* Return true when NODE has ADDR reference. */ @@ -622,6 +623,12 @@ symbol_table::remove_unreachable_nodes ( if (file) fprintf (file, " %s/%i", vnode->name (), vnode->order); vnext = next_variable (vnode); + /* Signal removal to the debug machinery. */ + if (! flag_wpa) + { + vnode->definition = false; + (*debug_hooks->late_global_decl) (vnode->decl); + } vnode->remove (); changed = true; }