OK.
On Thu, Nov 3, 2016 at 12:42 PM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > My recent optimize_abbrev_table optimization apparently broke Solaris > bootstrap. > The bug is specific I think just to -gdwarf-{2,3} -gno-strict-dwarf, where > DW_FORM_exprloc can't be used for location expressions and some location > expression contains DW_OP_GNU_{{const,regval,deref}_type,convert,reinterpret} > and there are at least 128 die abbreviations used by more than one DIE. > Because of the lack of DW_FORM_exprloc we need to decide on > DW_FORM_block{1,2,4} and size the location expression, for that we need to > know > the DIE offsets of base offset DIEs that are referenced (earlier code > ensures such types appear very early in the CU, right after the > DW_TAG_compile_unit DIE) and for that their size and their abbreviation values > need to be constant, so the optimize_abbrev_table opts that reorder > abbreviation > numbers by decreasing usage count or for -gdwarf-5 attempt to optimize > implicit > constants can't be done for the CU and base types. > For -gdwarf-4 and above, we can emit DW_FORM_exprloc, so value_format doesn't > need to compute any sizes and thus calc_base_type_die_sizes shouldn't be > called. > > Bootstrapped/regtested on x86_64-linux and i686-linux and Rainer has kindly > tested it on Solaris, ok for trunk? > > 2016-11-03 Jakub Jelinek <ja...@redhat.com> > > * dwarf2out.c (size_of_discr_list): Fix typo in function comment. > > PR debug/78191 > * dwarf2out.c (abbrev_opt_base_type_end): New variable. > (die_abbrev_cmp): Sort dies with die_abbrev smaller than > abbrev_opt_base_type_end only by increasing die_abbrev, before > any other dies. > (optimize_abbrev_table): Don't change abbrev numbers of > base types and CU or optimize implicit consts in them if > calc_base_type_die_sizes has been called during build_abbrev_table. > (calc_base_type_die_sizes): If abbrev_opt_start, set > abbrev_opt_base_type_end to one plus largest base type's > die_abbrev. > > --- gcc/dwarf2out.c.jj 2016-11-03 08:47:59.000000000 +0100 > +++ gcc/dwarf2out.c 2016-11-03 12:26:03.192459170 +0100 > @@ -1909,7 +1909,7 @@ size_of_discr_value (dw_discr_value *dis > return size_of_sleb128 (discr_value->v.sval); > } > > -/* Return the size of the value in a DW_discr_list attribute. */ > +/* Return the size of the value in a DW_AT_discr_list attribute. */ > > static int > size_of_discr_list (dw_discr_list_ref discr_list) > @@ -8548,6 +8548,11 @@ optimize_external_refs (dw_die_ref die) > /* First abbrev_id that can be optimized based on usage. */ > static unsigned int abbrev_opt_start; > > +/* Maximum abbrev_id of a base type plus one (we can't optimize DIEs with > + abbrev_id smaller than this, because they must be already sized > + during build_abbrev_table). */ > +static unsigned int abbrev_opt_base_type_end; > + > /* Vector of usage counts during build_abbrev_table. Indexed by > abbrev_id - abbrev_opt_start. */ > static vec<unsigned int> abbrev_usage_count; > @@ -8646,12 +8651,16 @@ die_abbrev_cmp (const void *p1, const vo > gcc_checking_assert (die1->die_abbrev >= abbrev_opt_start); > gcc_checking_assert (die2->die_abbrev >= abbrev_opt_start); > > - if (abbrev_usage_count[die1->die_abbrev - abbrev_opt_start] > - > abbrev_usage_count[die2->die_abbrev - abbrev_opt_start]) > - return -1; > - if (abbrev_usage_count[die1->die_abbrev - abbrev_opt_start] > - < abbrev_usage_count[die2->die_abbrev - abbrev_opt_start]) > - return 1; > + if (die1->die_abbrev >= abbrev_opt_base_type_end > + && die2->die_abbrev >= abbrev_opt_base_type_end) > + { > + if (abbrev_usage_count[die1->die_abbrev - abbrev_opt_start] > + > abbrev_usage_count[die2->die_abbrev - abbrev_opt_start]) > + return -1; > + if (abbrev_usage_count[die1->die_abbrev - abbrev_opt_start] > + < abbrev_usage_count[die2->die_abbrev - abbrev_opt_start]) > + return 1; > + } > > /* Stabilize the sort. */ > if (die1->die_abbrev < die2->die_abbrev) > @@ -8729,10 +8738,12 @@ optimize_abbrev_table (void) > sorted_abbrev_dies.qsort (die_abbrev_cmp); > > unsigned int abbrev_id = abbrev_opt_start - 1; > - unsigned int first_id = 0; > + unsigned int first_id = ~0U; > unsigned int last_abbrev_id = 0; > unsigned int i; > dw_die_ref die; > + if (abbrev_opt_base_type_end > abbrev_opt_start) > + abbrev_id = abbrev_opt_base_type_end - 1; > /* Reassign abbreviation ids from abbrev_opt_start above, so that > most commonly used abbreviations come first. */ > FOR_EACH_VEC_ELT (sorted_abbrev_dies, i, die) > @@ -8740,10 +8751,15 @@ optimize_abbrev_table (void) > dw_attr_node *a; > unsigned ix; > > + /* If calc_base_type_die_sizes has been called, the CU and > + base types after it can't be optimized, because we've already > + calculated their DIE offsets. We've sorted them first. */ > + if (die->die_abbrev < abbrev_opt_base_type_end) > + continue; > if (die->die_abbrev != last_abbrev_id) > { > last_abbrev_id = die->die_abbrev; > - if (dwarf_version >= 5 && i) > + if (dwarf_version >= 5 && first_id != ~0U) > optimize_implicit_const (first_id, i, implicit_consts); > abbrev_id++; > (*abbrev_die_table)[abbrev_id] = die; > @@ -8783,11 +8799,12 @@ optimize_abbrev_table (void) > die->die_abbrev = abbrev_id; > } > gcc_assert (abbrev_id == vec_safe_length (abbrev_die_table) - 1); > - if (dwarf_version >= 5) > + if (dwarf_version >= 5 && first_id != ~0U) > optimize_implicit_const (first_id, i, implicit_consts); > } > > abbrev_opt_start = 0; > + abbrev_opt_base_type_end = 0; > abbrev_usage_count.release (); > sorted_abbrev_dies.release (); > } > @@ -9041,6 +9058,9 @@ calc_base_type_die_sizes (void) > && base_type->die_abbrev); > prev = base_type; > #endif > + if (abbrev_opt_start > + && base_type->die_abbrev >= abbrev_opt_base_type_end) > + abbrev_opt_base_type_end = base_type->die_abbrev + 1; > base_type->die_offset = die_offset; > die_offset += size_of_die (base_type); > } > > > Jakub