Hello,
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>
---
include/abg-ir.h | 6 ++++++
src/abg-ir-priv.h | 13 +++++++++++-
src/abg-ir.cc | 53 +++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 69 insertions(+), 3 deletions(-)
@@ -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;
@@ -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.
@@ -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_;
}