OK.
On Wed, Jan 18, 2017 at 7:32 AM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > The following patch fixes ICE with -fdebug-types-section on the following > testcase. We prune DIEs in the main CU for methods in a class that is > moved into .debug_types section, because we don't see any uses of those > in the debug info. But those uses are only added later when adding > DW_TAG_call_site DIEs. The patch just goes through all direct call edges > at the time of the early debug finish and marks the callees as used, so that > we do not prune them. Of course, some edges might be still indirect and > turned into direct edges only later on, so as fallback the patch for now > just drops DW_AT_call_origin attributes on the floor if they would need to > point into a DIE that would need to be (re-)created inside of .debug_types > section (which is not valid and one can't refer to such DIEs anyway). > The right thing to do is create skeleton DIEs in the main CU as mentioned > in the PR, but that is lots of work. > > The patch grows .debug_info on bootstrapped x86_64-linux cc1plus by 0.009% > and on libstdc++.so.6 by 0.29%, so I think that is still acceptable. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? > > I've also tried bootstrap with -fdebug-types-section on by default, but that > failed miserably during building of libstdc++, seems there are other bugs > unrelated to what this patch addresses (the ICE I've looked at has been > that std::string class had _Rep class inside of it and that contained some > method and during break_out_comdat_type GCC actually didn't keep that > method's DIE inside of the main CU, which is what it ought to be doing > (i.e. have std::string in one .debug_types unit (that DIE moved, all > children duplicated into the .debug_types unit), then std::string::_Rep > in another .debug_types unit (again, that DIE moved, all children > duplicated) and in the main CU std::string and std::string::_Rep be copies > (skeleton), and the rest kept and optionally pruned as unused later on. > > I'll try to reduce a testcase for that and file another PR. > > 2017-01-18 Jakub Jelinek <ja...@redhat.com> > > PR debug/78835 > * dwarf2out.c (prune_unused_types): Mark all functions with DIEs > which have direct callers with -fvar-tracking-assignments enabled > in the current TU. > (resolve_addr): Avoid adding skeleton DIEs for DW_AT_call_origin > inside of type units. > > * g++.dg/debug/dwarf2/pr78835.C: New test. > > --- gcc/dwarf2out.c.jj 2017-01-16 22:31:10.779526222 +0100 > +++ gcc/dwarf2out.c 2017-01-17 10:12:11.853440897 +0100 > @@ -27768,6 +27768,25 @@ prune_unused_types (void) > for (i = 0; base_types.iterate (i, &base_type); i++) > prune_unused_types_mark (base_type, 1); > > + /* For -fvar-tracking-assignments, also set the mark on nodes that could be > + referenced by DW_TAG_call_site DW_AT_call_origin (i.e. direct call > + callees). */ > + cgraph_node *cnode; > + FOR_EACH_FUNCTION (cnode) > + if (cnode->referred_to_p (false)) > + { > + dw_die_ref die = lookup_decl_die (cnode->decl); > + if (die == NULL || die->die_mark) > + continue; > + for (cgraph_edge *e = cnode->callers; e; e = e->next_caller) > + if (e->caller != cnode > + && opt_for_fn (e->caller->decl, flag_var_tracking_assignments)) > + { > + prune_unused_types_mark (die, 1); > + break; > + } > + } > + > if (debug_str_hash) > debug_str_hash->empty (); > if (skeleton_debug_str_hash) > @@ -28669,16 +28688,27 @@ resolve_addr (dw_die_ref die) > && DECL_ABSTRACT_ORIGIN (tdecl) == NULL_TREE > && (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); > + dw_die_ref pdie = cdie; > + /* Make sure we don't add these DIEs into type units. > + We could emit skeleton DIEs for context (namespaces, > + outer structs/classes) and a skeleton DIE for the > + innermost context with DW_AT_signature pointing to the > + type unit. See PR78835. */ > + while (pdie && pdie->die_tag != DW_TAG_type_unit) > + pdie = pdie->die_parent; > + if (pdie == NULL) > + { > + /* 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) > { > --- gcc/testsuite/g++.dg/debug/dwarf2/pr78835.C.jj 2017-01-17 > 10:16:34.301004406 +0100 > +++ gcc/testsuite/g++.dg/debug/dwarf2/pr78835.C 2017-01-17 10:17:45.034078227 > +0100 > @@ -0,0 +1,11 @@ > +/* PR debug/78835 */ > +/* { dg-do compile } */ > +/* { dg-options "-gdwarf-4 -O2 -fdebug-types-section" } */ > + > +struct A { void foo (); }; > + > +void > +bar (A &x) > +{ > + x.foo (); > +} > > Jakub