+2016-11-18 Jakub Jelinek <jakub@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.
+
2016-11-18 Jeff Law <law@redhat.com>
PR target/25112
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)
/* 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;
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)
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)
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;
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 ();
}
&& 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);
}