Bug 29303 - Cache the result of structural aggregate comparison
When we are forced to structurally compare aggregate types (classes
and function types), some sub-types pairs can be compared an
innumerable number of times over and over again. This leads to having
extremely slow comparison times for the portions of the code that are
subject to structural comparison because canonical comparison has not
yet been setup. For instance, this happens in the dwarf-reader in the
function read_context::resolve_declaration_only_classes or, in the ir
module in the function type_base::get_canonical_type_for when type
canonicalization is being done.
To overcome this, this patch caches the result of comparing two pairs
of aggregate (class or function) type, ensuring that a pair of
aggregate sub-type is compared at most once during the structural
comparison of a given type.
Note that this caching scheme is used only during declaration classes
resolution and type canonicalization.
This sped up things quite noticeably as self comparing both binutils
and dovecot package sets in Fedora 36 was literally taking forever
prior to the patch and is now completing with this patch.
* src/abg-ir-priv.h (struct uint64_t_pair_hash): Define new type.
(uint64_t_pair_type, uint64_t_pairs_set_type)
(type_comparison_result_type): Define new typedefs.
(environment::priv::{classes_being_compared_,
fn_types_being_compared_}): Use the new uint64_t_pairs_set_type
type for these.
(environment::priv::{type_comparison_results_cache_,
allow_type_comparison_results_caching_}): Define new data members.
(environment::priv::priv): Initialize the new
allow_type_comparison_results_caching_ scalar data member.
(environment::priv::{allow_type_comparison_results_caching,
cache_type_comparison_result, is_type_comparison_cached,
clear_type_comparison_results_cache}): Define new member
functions.
(environment::priv::{mark_as_being_compared,
unmark_as_being_compared, comparison_started}): Take a pair of
types.
(struct function_type::priv): Move this here, from ...
* src/abg-ir.cc (struct function_type::priv): ... here.
(is_comparison_cycle_detected, mark_types_as_being_compared)
(unmark_types_as_being_compared): Adjust call to the new
environment::priv::{comparison_started, mark_as_being_compared,
unmark_as_being_compared}.
(type_base::get_canonical_type_for): Use aggregate types
comparison result caching when doing type comparison.
(equals): In the overload for function_type, class_or_union and
class_decl, cache the result of aggregate type comparison and
re-use that cached result when it's available.
* src/abg-dwarf-reader.cc
(read_context::compare_before_canonicalisation): Use aggregate
types comparison result caching when doing type comparison.