This moves gen_scheduled_generic_parms_dies and gen_remaining_tmpl_value_param_die_attribute to early finish as we are never populating them after that (the patch adds asserts to that fact). I left handling "leftovers" of gen_remaining_tmpl_value_param_die_attribute in late finish as well as we are special-casing generating references to symbols where we only can decide late whether we may emit them or not. The example from the testsuite has a template parameter of function pointer type with its value refering to a function we don't know whether we'll end up outputting it. (we need a good solution for this kind of issue for early LTO debug as well - we only know at LTO link time whether the symbol we want to refer to prevails. If only we had the ability to emit "weak" references to those ...)
Bootstrapped and tested on x86_64-unknown-linux-gnu and verified gdb testsuite is fine. I plan to commit this if there are no comments (and the previous two patches have been approved or committed). Richard. 2015-09-16 Richard Biener <rguent...@suse.de> * dwarf2out.c (append_entry_to_tmpl_value_parm_die_table): Assert we're in early phase. (schedule_generic_params_dies_gen): Likewise. (gen_remaining_tmpl_value_param_die_attribute): Do only as much work as possible, retaining unhandled cases. (gen_scheduled_generic_parms_dies): Set early-dwarf flag and clear out generic_type_instances at the end. (dwarf2out_finish): Move call to gen_scheduled_generic_parms_dies... (dwarf2out_early_finish): ... here. Do most of gen_remaining_tmpl_value_param_die_attribute here. Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 227779) +++ gcc/dwarf2out.c (working copy) @@ -22091,6 +22097,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); @@ -22120,6 +22128,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); @@ -22135,11 +22145,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); } } @@ -22157,9 +22177,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; } @@ -25193,7 +25219,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 @@ -25550,6 +25575,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