[dwarf-reader] Optimize speed of compare_as_decl_dies

Profiling shows that the *number of calls* to
compare_dies_string_attribute_value by compare_as_decl_dies represents
a hotspot.  That is, compare_dies_string_attribute_value itself
doesn't necessarily takes long, but it's being called "too much",
especially when compare_as_decl_dies is called for DIEs representing
classes/structs.

This patch thus reduces the calls to
compare_dies_string_attribute_value from 3 to 1 for classes/structs.

This optimization makes abidw's reading be 10% faster (from ~5min:15s
to ~ 4min:45s) on a fullblow vmlinux.  Note that abidw writting time
hasn't been yet optimized.

	* src/abg-dwarf-reader.cc (die_is_class_type): Take a const
	pointer to Dwarf_Die.
	(compare_as_decl_dies): For classes/structs, call
	compare_dies_string_attribute_value just once to compare the
	DW_AT_name attribute values.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2019-06-17 14:26:45 +02:00
parent 23744b4b8e
commit 133d43ad19

View File

@ -346,7 +346,7 @@ static bool
die_is_pointer_reference_or_typedef_type(const Dwarf_Die* die);
static bool
die_is_class_type(Dwarf_Die* die);
die_is_class_type(const Dwarf_Die* die);
static bool
die_is_qualified_type(const Dwarf_Die* die);
@ -9571,9 +9571,9 @@ die_is_pointer_reference_or_typedef_type(const Dwarf_Die* die)
///
/// @return true iff @p die represents a class type.
static bool
die_is_class_type(Dwarf_Die* die)
die_is_class_type(const Dwarf_Die* die)
{
int tag = dwarf_tag(die);
int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
return true;
@ -12132,27 +12132,38 @@ compare_as_decl_dies(const Dwarf_Die *l, const Dwarf_Die *r)
{
ABG_ASSERT(l && r);
if (dwarf_tag(const_cast<Dwarf_Die*>(l))
!= dwarf_tag(const_cast<Dwarf_Die*>(r)))
int l_tag = dwarf_tag(const_cast<Dwarf_Die*>(l));
int r_tag = dwarf_tag(const_cast<Dwarf_Die*>(r));
if (l_tag != r_tag)
return false;
bool result = false;
if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
result)
|| compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
result))
if (l_tag == DW_TAG_subprogram || l_tag == DW_TAG_variable)
{
if (!result)
return false;
// Fast path for functions and global variables.
if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
result)
|| compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
result))
{
if (!result)
return false;
}
if (compare_dies_string_attribute_value(l, r, DW_AT_name,
result))
{
if (!result)
return false;
}
return true;
}
// Fast path for types.
if (compare_dies_string_attribute_value(l, r, DW_AT_name,
result))
{
if (!result)
return false;
}
return result;
return true;
}