ir: Cache the result of scope_decl::get_sorted_member_types

Speed up ABIXML emitting by caching the result of
scope_decl::get_sorted_member_types when it's called on a
canonicalized type.

	* include/abg-ir.h
	(environment::canonicalization_started): Define new member
	functions.
	* src/abg-ir-priv.h
	(environment::priv::canonicalization_started_): Define new data
	member.
	(canonicalize_types): Call
	environment::canonicalization_started(true) right before starting
	type canonicalization and call
	environment::canonicalization_started(false) right after type
	canonicalization is done.
	* src/abg-ir.cc (environment::canonicalization_started): Define
	new methods.
	(environment::canonicalization_is_done): Set the
	new canonicalization_started flag to false when the
	canonicalization is done.
	(scope_decl::priv::clear_sorted_member_types_cache_): Declare new
	data member.
	(scope_decl::{add_member_decl, insert_member_type}): If we are
	adding a type to the scope, then flag the scope as needing to
	clear the sorted member types cache.
	(scope_decl::get_sorted_member_types): If type canonicalization is
	not yet started, then the sorted member types cache needs to be
	cleared.  If the sorted member types cache is to be cleared, then
	clear it.  If the cache is empty, fill it.  Then return the
	content of the cache.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2024-08-08 14:13:27 +02:00
parent 923b40893a
commit 2ebe28b77e
3 changed files with 69 additions and 3 deletions

View File

@ -185,6 +185,12 @@ public:
void
canonicalization_is_done(bool);
bool
canonicalization_started() const;
void
canonicalization_started(bool);
bool
decl_only_class_equals_definition() const;

View File

@ -619,6 +619,7 @@ struct environment::priv
// read from abixml and the type-id string it corresponds to.
unordered_map<uintptr_t, string> pointer_type_id_map_;
#endif
bool canonicalization_started_;
bool canonicalization_is_done_;
bool decl_only_class_equals_definition_;
bool use_enum_binary_only_equality_;
@ -646,7 +647,8 @@ struct environment::priv
#endif
priv()
: canonicalization_is_done_(),
: canonicalization_started_(),
canonicalization_is_done_(),
decl_only_class_equals_definition_(false),
use_enum_binary_only_equality_(true),
allow_type_comparison_results_caching_(false),
@ -1464,6 +1466,12 @@ canonicalize_types(const input_iterator& begin,
if (begin == end)
return;
auto first_iter = begin;
auto first = deref(first_iter);
environment& env = const_cast<environment&>(first->get_environment());
env.canonicalization_started(true);
int i;
input_iterator t;
// First, let's compute the canonical type of this type.
@ -1481,6 +1489,9 @@ canonicalize_types(const input_iterator& begin,
canonicalize(deref(t));
}
env.canonicalization_is_done(true);
}
/// Hash and canonicalize a sequence of types.

View File

@ -3336,7 +3336,29 @@ environment::canonicalization_is_done() const
/// @param f the new value of the flag.
void
environment::canonicalization_is_done(bool f)
{priv_->canonicalization_is_done_ = f;}
{
priv_->canonicalization_is_done_ = f;
if (priv_->canonicalization_is_done_)
canonicalization_started(false);
}
/// Getter of a flag saying if the canonicalization process has
/// started or not.
///
/// @return the flag saying if the canonicalization process has
/// started or not.
bool
environment::canonicalization_started() const
{return priv_->canonicalization_started_;}
/// Setter of a flag saying if the canonicalization process has
/// started or not.
///
/// @param f the new value of the flag saying if the canonicalization
/// process has started or not.
void
environment::canonicalization_started(bool f)
{priv_->canonicalization_started_ = f;}
/// Getter of the "decl-only-class-equals-definition" flag.
///
@ -7522,6 +7544,7 @@ struct scope_decl::priv
scopes member_scopes_;
canonical_type_sptr_set_type canonical_types_;
type_base_sptrs_type sorted_canonical_types_;
bool clear_sorted_member_types_cache_ = false;
}; // end struct scope_decl::priv
/// Constructor of the @ref scope_decl type.
@ -7758,7 +7781,10 @@ scope_decl::add_member_decl(const decl_base_sptr& member)
member->set_scope(this);
priv_->members_.push_back(member);
if (is_type(member))
priv_->member_types_.push_back(is_type(member));
{
priv_->member_types_.push_back(is_type(member));
priv_->clear_sorted_member_types_cache_ = true;
}
if (scope_decl_sptr m = dynamic_pointer_cast<scope_decl>(member))
priv_->member_scopes_.push_back(m);
@ -7810,6 +7836,7 @@ scope_decl::insert_member_type(type_base_sptr t,
ABG_ASSERT(!has_scope(d));
priv_->member_types_.push_back(t);
priv_->clear_sorted_member_types_cache_= true;
insert_member_decl(d, before);
}
@ -7864,9 +7891,26 @@ scope_decl::remove_member_type(type_base_sptr t)
const type_base_sptrs_type&
scope_decl::get_sorted_member_types() const
{
if (priv_->clear_sorted_member_types_cache_)
{
priv_->sorted_member_types_.clear();
priv_->clear_sorted_member_types_cache_ = false;
}
if (priv_->sorted_member_types_.empty())
{
unordered_set<type_base_sptr> canonical_pointer_types;
for (auto t : get_member_types())
{
if (is_non_canonicalized_type(t))
priv_->sorted_member_types_.push_back(t);
else if (auto c = t->get_canonical_type())
canonical_pointer_types.insert(c);
else
canonical_pointer_types.insert(t);
}
for (auto t : canonical_pointer_types)
priv_->sorted_member_types_.push_back(t);
type_topo_comp comp;
@ -7874,6 +7918,11 @@ scope_decl::get_sorted_member_types() const
priv_->sorted_member_types_.end(),
comp);
}
const ir::environment& env = get_environment();
if (!env.canonicalization_started() && !env.canonicalization_is_done())
priv_->clear_sorted_member_types_cache_ = true;
return priv_->sorted_member_types_;
}