libabigail/tests/data/test-abidiff/test-PR18791-report0.txt
Dodji Seketeli 912eb7e36b Speed up type canonicalization by avoiding recursive hashing
Recursive type hashing was showing up as the major hot spot of
performance profiles.  After spending a few days on trying to speed it
up, I have officially declared recursive tree node hashing as a slow
process and I am giving up.

I have thus decided to not use that at type canonicalization time.

Rather, I am proposing a new type canonicalization routine where types
are first hashed by hashing their pretty representation string.

Basically, if T is the total number of types in the system and C the
number of classes of equivalences (or the number of canonical types),
the number of type comparisons done by a naive type canonicalization
routine is N x C.  With the worse C being equal to N itself, that
worse number of comparisons is N*N.

By using a hash table to store the canonical types, keyed by a hash of
their pretty representation string, the number of type comparisons can
be brought down to N*P, where P is a the greater number of which
pretty representation string hash collide.  That number P is usually
small; my measurements show that N usually goes from 1 to 3.  And
moreover, computing the hash of the pretty representation string of
the function is way faster than using the recursive type hash!

As a result, running abidw on the libcilkrts.so library, from GCC goes
from 12 minutes to 0.4 seconds!

Incidentally, now that we are not trying to speed up the recursive
type hashing process, all the complicated business we had around
caching the result of the hashing is gone!  I was thinking that hash
cashing was inherently a bad idea, especially for recursive types --
that refer to themselves directly or indirectly, because in those
case, depending on when you cached the hash value, the value of the
hashing can be different.

The abixml writer's code doesn't use the recursive type hash anymore
either; it uses the pointer value of the canonical type as hash.
Super fast too!

The patch had to fix pieces here and there to comply with the fact
that canonical types are now used across the board in a mandatory
fashion.

	* include/abg-ir.h (canonical_types_map_type): Adjust this typedef
	to make it point to an unordered_map which the key is now a string
	and the value is a vector of types.
	(type_or_decl_base::{get_cached_hash_value, set_cached_hash_value,
	cached_hash}): Remove these member functions and type.
	(struct type_base::cached_hash): Remove.
	* src/abg-ir.cc (struct type_or_decl_base::priv::hash_): Remove.
	(type_or_decl_base::priv::priv): Adjust.
	(type_or_decl_base::{g,s}et_cached_hash_value): Remove.
	(type_base::get_canonical_type_for): For declaration-only classes,
	look at their definition for the canonical_type.  Do not use
	recursive type hashing anymore.  Rather, use the pretty
	representation string, and hash that.
	(class_decl::base_spec::get_hash): Do away with hash value caching
	here.
	(class_decl::operator==): For decl-only classes, look at their
	definitions for canonical types.
	(hash_type_or_decl): Adjust comment.  Use the canonical type
	pointer value for type hash.  That's the fast path.  Otherwise, if
	not available, fall back to a slow path which is the recursive
	type hash we were using before.
	* src/abg-dwarf-reader.cc (maybe_canonicalize_type): Schedule all
	classes and typedef to classes for late canonicalization.
	* src/abg-hash.cc (type_base::dynamic_hash::operator()): There is
	no hash value cashing anymore.
	(type_base::cached_hash::operator()): Remove.
	* src/abg-reader.cc (read_context::get_type): Slight style
	adjustment.
	(read_translation_unit_from_file)
	(read_translation_unit_from_buffer): Do not forget to canonicalize
	types when reading just one translation unit.
	(build_type_tparameter, build_template_tparameter): Canonicalize
	the type.
	* src/abg-writer.cc (struct type_hasher): New hasher type.
	(type_ptr_map): Use a deep pointer comparison equal operator
	functor, and canonical types as type hash values.
	(write_class_decl): Do not write size and alignment on decl-only
	classes.  Do not record decl-only classes as being emitted.  Their
	definition must be emitted before.
	* tests/test-read-write.cc (main): Do not do abi testing on
	translation units (as opposed to doing it on abi corpora) as that
	code is not wet yet.  We need to know how to diff namespaces.
	* tests/data/test-abidiff/test-PR18791-report0.txt: Adjust.
	* tests/data/test-read-dwarf/test9-pr18818-clang.so.abi: Likewise.
	* tests/data/test-read-dwarf/test10-pr18818-gcc.so.abi: Likewise.
	* tests/data/test-read-dwarf/test12-pr18844.so.abi: Likewise.
	* tests/data/test-read-dwarf/test13-pr18894.so.abi: Likewise.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-read-dwarf/test15-pr18892.so.abi: Likewise.
	* tests/data/test-read-dwarf/test16-pr18904.so.abi: Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
2015-09-21 13:51:31 +02:00

200 lines
13 KiB
Plaintext

Functions changes summary: 1 Removed, 19 Changed, 1 Added functions
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1 Removed function:
'method void std::_List_base<sigc::slot_base, std::allocator<sigc::slot_base> >::_M_clear()'
1 Added function:
'method void std::__cxx11::_List_base<sigc::slot_base, std::allocator<sigc::slot_base> >::_M_clear()'
19 functions with some indirect sub-type change:
[C]'method sigc::connection::connection(const sigc::connection&)' has some indirect sub-type changes:
parameter 1 of type 'const sigc::connection&' has sub-type changes:
in referenced type 'const sigc::connection':
in unqualified underlying type 'struct sigc::connection':
1 data member change:
type of 'sigc::slot_base* sigc::connection::slot_' changed:
in pointed to type 'class sigc::slot_base':
1 data member change:
type of 'sigc::slot_base::rep_type* sigc::slot_base::rep_' changed:
in pointed to type 'typedef sigc::slot_base::rep_type':
underlying type 'struct sigc::internal::slot_rep' changed:
1 base class change:
'struct sigc::trackable' changed:
1 data member change:
type of 'sigc::internal::trackable_callback_list* sigc::trackable::callback_list_' changed:
in pointed to type 'struct sigc::internal::trackable_callback_list':
type size changed from 192 to 256 bits
2 data member changes:
type of 'sigc::internal::trackable_callback_list::callback_list sigc::internal::trackable_callback_list::callbacks_' changed:
underlying type 'class std::list<sigc::internal::trackable_callback, std::allocator<sigc::internal::trackable_callback> >' changed:
type name changed from 'std::list<sigc::internal::trackable_callback, std::allocator<sigc::internal::trackable_callback> >' to 'std::__cxx11::list<sigc::internal::trackable_callback, std::allocator<sigc::internal::trackable_callback> >'
type size changed from 128 to 192 bits
1 base class deletion:
class std::_List_base<sigc::internal::trackable_callback, std::allocator<sigc::internal::trackable_callback> >
1 base class insertion:
class std::__cxx11::_List_base<sigc::internal::trackable_callback, std::allocator<sigc::internal::trackable_callback> >
'bool sigc::internal::trackable_callback_list::clearing_' offset changed from 128 to 192 (in bits)
[C]'method sigc::connection::connection(sigc::slot_base&)' has some indirect sub-type changes:
parameter 1 of type 'sigc::slot_base&' has sub-type changes:
referenced type 'class sigc::slot_base' changed, as reported earlier
[C]'method sigc::connection& sigc::connection::operator=(const sigc::connection&)' has some indirect sub-type changes:
return type changed:
referenced type 'struct sigc::connection' changed, as reported earlier
parameter 1 of type 'const sigc::connection&' has sub-type changes:
in referenced type 'const sigc::connection':
unqualified underlying type 'struct sigc::connection' changed, as reported earlier
[C]'method void sigc::connection::set_slot(sigc::slot_base*)' has some indirect sub-type changes:
parameter 1 of type 'sigc::slot_base*' has sub-type changes:
pointed to type 'class sigc::slot_base' changed, as reported earlier
[C]'method sigc::internal::signal_impl::iterator_type sigc::internal::signal_impl::connect(const sigc::slot_base&)' has some indirect sub-type changes:
return type changed:
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
parameter 1 of type 'const sigc::slot_base&' has sub-type changes:
in referenced type 'const sigc::slot_base':
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
[C]'method sigc::internal::signal_impl::iterator_type sigc::internal::signal_impl::erase(sigc::internal::signal_impl::iterator_type)' has some indirect sub-type changes:
return type changed:
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
parameter 1 of type 'typedef sigc::internal::signal_impl::iterator_type' changed:
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
[C]'method sigc::internal::signal_impl::iterator_type sigc::internal::signal_impl::insert(sigc::internal::signal_impl::iterator_type, const sigc::slot_base&)' has some indirect sub-type changes:
return type changed:
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
parameter 1 of type 'typedef sigc::internal::signal_impl::iterator_type' changed:
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
parameter 2 of type 'const sigc::slot_base&' has sub-type changes:
in referenced type 'const sigc::slot_base':
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
[C]'method sigc::signal_base::iterator_type sigc::signal_base::connect(const sigc::slot_base&)' has some indirect sub-type changes:
return type changed:
underlying type 'typedef sigc::internal::signal_impl::iterator_type' changed:
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
parameter 1 of type 'const sigc::slot_base&' has sub-type changes:
in referenced type 'const sigc::slot_base':
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
[C]'method sigc::signal_base::iterator_type sigc::signal_base::erase(sigc::signal_base::iterator_type)' has some indirect sub-type changes:
return type changed:
underlying type 'typedef sigc::internal::signal_impl::iterator_type' changed:
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
parameter 1 of type 'typedef sigc::signal_base::iterator_type' changed:
underlying type 'typedef sigc::internal::signal_impl::iterator_type' changed:
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
[C]'method sigc::internal::signal_impl* sigc::signal_base::impl()' has some indirect sub-type changes:
return type changed:
in pointed to type 'struct sigc::internal::signal_impl':
type size changed from 192 to 256 bits
1 data member change:
type of 'std::list<sigc::slot_base, std::allocator<sigc::slot_base> > sigc::internal::signal_impl::slots_' changed:
type name changed from 'std::list<sigc::slot_base, std::allocator<sigc::slot_base> >' to 'std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >'
type size changed from 128 to 192 bits
1 base class deletion:
class std::_List_base<sigc::slot_base, std::allocator<sigc::slot_base> >
1 base class insertion:
class std::__cxx11::_List_base<sigc::slot_base, std::allocator<sigc::slot_base> >
[C]'method sigc::signal_base::iterator_type sigc::signal_base::insert(sigc::signal_base::iterator_type, const sigc::slot_base&)' has some indirect sub-type changes:
return type changed:
underlying type 'typedef sigc::internal::signal_impl::iterator_type' changed:
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
parameter 1 of type 'typedef sigc::signal_base::iterator_type' changed:
underlying type 'typedef sigc::internal::signal_impl::iterator_type' changed:
underlying type 'typedef std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator' changed:
typedef name changed from std::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator to std::__cxx11::list<sigc::slot_base, std::allocator<sigc::slot_base> >::iterator
parameter 2 of type 'const sigc::slot_base&' has sub-type changes:
in referenced type 'const sigc::slot_base':
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
[C]'method sigc::signal_base& sigc::signal_base::operator=(const sigc::signal_base&)' has some indirect sub-type changes:
return type changed:
in referenced type 'struct sigc::signal_base':
1 base class change:
'struct sigc::trackable' changed:
details were reported earlier
1 data member change:
type of 'sigc::internal::signal_impl* sigc::signal_base::impl_' changed:
pointed to type 'struct sigc::internal::signal_impl' changed, as reported earlier
parameter 1 of type 'const sigc::signal_base&' has sub-type changes:
in referenced type 'const sigc::signal_base':
unqualified underlying type 'struct sigc::signal_base' changed, as reported earlier
[C]'method sigc::signal_base::signal_base(const sigc::signal_base&)' has some indirect sub-type changes:
parameter 1 of type 'const sigc::signal_base&' has sub-type changes:
in referenced type 'const sigc::signal_base':
unqualified underlying type 'struct sigc::signal_base' changed, as reported earlier
[C]'method sigc::slot_base& sigc::slot_base::operator=(const sigc::slot_base&)' has some indirect sub-type changes:
return type changed:
referenced type 'class sigc::slot_base' changed, as reported earlier
parameter 1 of type 'const sigc::slot_base&' has sub-type changes:
in referenced type 'const sigc::slot_base':
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
[C]'method sigc::slot_base::slot_base(sigc::slot_base::rep_type*)' has some indirect sub-type changes:
parameter 1 of type 'sigc::slot_base::rep_type*' has sub-type changes:
in pointed to type 'typedef sigc::slot_base::rep_type':
underlying type 'struct sigc::internal::slot_rep' changed, as reported earlier
[C]'method sigc::slot_base::slot_base(const sigc::slot_base&)' has some indirect sub-type changes:
parameter 1 of type 'const sigc::slot_base&' has sub-type changes:
in referenced type 'const sigc::slot_base':
unqualified underlying type 'class sigc::slot_base' changed, as reported earlier
[C]'method sigc::internal::trackable_callback_list* sigc::trackable::callback_list()' has some indirect sub-type changes:
return type changed:
pointed to type 'struct sigc::internal::trackable_callback_list' changed, as reported earlier
[C]'method sigc::trackable& sigc::trackable::operator=(const sigc::trackable&)' has some indirect sub-type changes:
return type changed:
referenced type 'struct sigc::trackable' changed, as reported earlier
parameter 1 of type 'const sigc::trackable&' has sub-type changes:
in referenced type 'const sigc::trackable':
unqualified underlying type 'struct sigc::trackable' changed, as reported earlier
[C]'method sigc::trackable::trackable(const sigc::trackable&)' has some indirect sub-type changes:
parameter 1 of type 'const sigc::trackable&' has sub-type changes:
in referenced type 'const sigc::trackable':
unqualified underlying type 'struct sigc::trackable' changed, as reported earlier