The following patch refactors dwarf2out_late_global_decl to only add location or const value attributes in late dwarf phase. It adds LTO support by doing the early phase there as well (just what it would have done on-the-fly when using dwarf2out_decl).
This change enables the other part of the patch, making sure we finish all template stuff early (well, most of it - the part requiring symbolic constants is left to the late phase). That this change requires the first means that we fail to create some early debug (there's some other unreviewed patch from me addressing parts of that but it doesn't address all cases that happen during bootstrap - we're creating the stuff "late" via the late_global_decl call from cgraphunit.c:analyze_functions). Bootstrapped on x86_64-unknown-linux-gnu, testing in progress. I'll try to dive into the above issue again when I return from vacation. Richard. 2015-09-03 Richard Biener <rguent...@suse.de> * dwarf2out.c (dwarf2out_late_global_decl): For LTO dispatch to dwarf2out_early_global_decl first. With early debug just add locations or const value attributes on the early created DIEs. (append_entry_to_tmpl_value_parm_die_table): Assert we are in early dwarf mode. (schedule_generic_params_dies_gen): Likewise. (gen_remaining_tmpl_value_param_die_attribute): Keep entries we were not able to process. (gen_scheduled_generic_parms_dies): Set early-dwarf and clear vector after we're done. (dwarf2out_finish): Do not call gen_scheduled_generic_parms_dies here. (dwarf2out_early_finish): Call gen_scheduled_generic_parms_dies here and also process a first round of gen_remaining_tmpl_value_param_die_attribute. Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 227446) +++ gcc/dwarf2out.c (working copy) @@ -21640,14 +21640,20 @@ dwarf2out_early_global_decl (tree decl) static void dwarf2out_late_global_decl (tree decl) { - /* Output any global decls we missed or fill-in any location - information we were unable to determine on the first pass. - - Skip over functions because they were handled by the - debug_hooks->function_decl() call in rest_of_handle_final. */ - if ((TREE_CODE (decl) != FUNCTION_DECL || !DECL_INITIAL (decl)) + /* We have to generate early debug late for LTO. */ + if (in_lto_p) + dwarf2out_early_global_decl (decl); + + /* Fill-in any location information we were unable to determine + on the first pass. */ + if (TREE_CODE (decl) == VAR_DECL && !POINTER_BOUNDS_P (decl)) - dwarf2out_decl (decl); + { + dw_die_ref die = lookup_decl_die (decl); + if (die) + add_location_or_const_value_attribute (die, decl, false, + DW_AT_location); + } } /* Output debug information for type decl DECL. Called from toplev.c @@ -22105,6 +22111,8 @@ append_entry_to_tmpl_value_parm_die_tabl if (!die || !arg) return; + gcc_assert (early_dwarf); + if (!tmpl_value_parm_die_table) vec_alloc (tmpl_value_parm_die_table, 32); @@ -22134,6 +22142,8 @@ schedule_generic_params_dies_gen (tree t if (!generic_type_p (t)) return; + gcc_assert (early_dwarf); + if (!generic_type_instances) vec_alloc (generic_type_instances, 256); @@ -22149,11 +22159,21 @@ gen_remaining_tmpl_value_param_die_attri { if (tmpl_value_parm_die_table) { - unsigned i; + unsigned i, j; die_arg_entry *e; + /* We do this in two phases - first get the cases we can + handle during early-finish, preserving those we cannot + (containing symbolic constants where we don't yet know + whether we are going to output the referenced symbols). + For those we try again at late-finish. */ + j = 0; FOR_EACH_VEC_ELT (*tmpl_value_parm_die_table, i, e) - tree_add_const_value_attribute (e->die, e->arg); + { + if (!tree_add_const_value_attribute (e->die, e->arg)) + (*tmpl_value_parm_die_table)[j++] = *e; + } + tmpl_value_parm_die_table->truncate (j); } } @@ -22171,9 +22191,15 @@ gen_scheduled_generic_parms_dies (void) if (!generic_type_instances) return; + /* We end up "recursing" into schedule_generic_params_dies_gen, so + pretend this generation is part of "early dwarf" as well. */ + set_early_dwarf s; + FOR_EACH_VEC_ELT (*generic_type_instances, i, t) if (COMPLETE_TYPE_P (t)) gen_generic_params_dies (t); + + generic_type_instances = NULL; } @@ -25207,7 +25233,6 @@ dwarf2out_finish (const char *filename) producer->dw_attr_val.v.val_str->refcount--; producer->dw_attr_val.v.val_str = find_AT_string (producer_string); - gen_scheduled_generic_parms_dies (); gen_remaining_tmpl_value_param_die_attribute (); /* Add the name for the main input file now. We delayed this from @@ -25564,6 +25589,9 @@ dwarf2out_early_finish (void) /* The point here is to flush out the limbo list so that it is empty and we don't need to stream it for LTO. */ flush_limbo_die_list (); + + gen_scheduled_generic_parms_dies (); + gen_remaining_tmpl_value_param_die_attribute (); } /* Reset all state within dwarf2out.c so that we can rerun the compiler