[08/27] ir: Cache the result of scope_decl::get_sorted_member_types

Message ID 87bk1bmic5.fsf@seketeli.org
State New
Headers
Series Implement type hashing & fix self-comparing gcc-gnat in fc37 |

Commit Message

Dodji Seketeli Aug. 29, 2024, 3:58 p.m. UTC
  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(-)
  

Patch

diff --git a/include/abg-ir.h b/include/abg-ir.h
index 001db6d0..b4fec6c5 100644
--- a/include/abg-ir.h
+++ b/include/abg-ir.h
@@ -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;
 
diff --git a/src/abg-ir-priv.h b/src/abg-ir-priv.h
index a184b804..0a960885 100644
--- a/src/abg-ir-priv.h
+++ b/src/abg-ir-priv.h
@@ -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.
diff --git a/src/abg-ir.cc b/src/abg-ir.cc
index abc1b145..9ff4d3eb 100644
--- a/src/abg-ir.cc
+++ b/src/abg-ir.cc
@@ -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_;
 }