From f6af7dc1920f72b3731d8908a577354ac5bc8864 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 8 Oct 2019 08:52:59 -0400
Subject: [PATCH 69/74] FIXME: use pool allocators

---
 gcc/analyzer/analyzer.h            | 22 ++++++++++++++++++++++
 gcc/analyzer/constraint-manager.cc |  3 +++
 gcc/analyzer/constraint-manager.h  |  3 +++
 gcc/analyzer/region-model.cc       | 27 +++++++++++++++++++++++++++
 gcc/analyzer/region-model.h        | 33 +++++++++++++++++++++++++++++++++
 5 files changed, 88 insertions(+)

diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index ace8924..4934346 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -123,4 +123,26 @@ struct pod_hash_traits : typed_noop_remove<Type>
   static inline bool is_empty (Type);
 };
 
+////////////////////////////////////////////////////////////////////////////
+
+/* Implement an optimized allocator for TYPENAME objects of fixed size,
+   without requiring a default ctor.  */
+
+#define IMPL_POOL_ALLOCATOR(TYPENAME) \
+  static pool_allocator TYPENAME##_pool (#TYPENAME, sizeof (TYPENAME)); \
+									\
+  void *								\
+  TYPENAME::operator new (size_t sz)					\
+  {									\
+    gcc_assert (sz == sizeof (TYPENAME));				\
+    return TYPENAME##_pool.allocate ();					\
+  }									\
+									\
+  void									\
+  TYPENAME::operator delete (void* ptr, size_t sz)			\
+  {									\
+    gcc_assert (sz == sizeof (TYPENAME));				\
+    TYPENAME##_pool.remove (ptr);					\
+  }
+
 #endif /* GCC_ANALYZER_ANALYZER_H */
diff --git a/gcc/analyzer/constraint-manager.cc b/gcc/analyzer/constraint-manager.cc
index 12846f2..1d112cf 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -26,6 +26,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple.h"
 #include "gimple-iterator.h"
 #include "graphviz.h"
+#include "alloc-pool.h"
 #include "selftest.h"
 #include "analyzer/analyzer.h"
 #include "analyzer/supergraph.h"
@@ -152,6 +153,8 @@ range::constrained_to_single_element (tree *out)
 
 /* class equiv_class.  */
 
+IMPL_POOL_ALLOCATOR (equiv_class)
+
 /* equiv_class's default ctor.  */
 
 equiv_class::equiv_class ()
diff --git a/gcc/analyzer/constraint-manager.h b/gcc/analyzer/constraint-manager.h
index 7710dc8..c883d47 100644
--- a/gcc/analyzer/constraint-manager.h
+++ b/gcc/analyzer/constraint-manager.h
@@ -41,6 +41,9 @@ public:
 class equiv_class
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   equiv_class ();
   equiv_class (const equiv_class &other);
 
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index e48d068..affd4cf 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -30,6 +30,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-dfa.h"
 #include "stringpool.h"
 #include "selftest.h"
+#include "alloc-pool.h"
 #include "diagnostic-color.h"
 #include "diagnostic-metadata.h"
 #include "analyzer/analyzer.h"
@@ -377,6 +378,10 @@ svalue::maybe_get_constant () const
 
 /* class region_svalue : public svalue.  */
 
+/* Optimized allocator for region_svalue instances.  */
+
+IMPL_POOL_ALLOCATOR (region_svalue)
+
 /* Compare the fields of this region_svalue with OTHER, returning true
    if they are equal.
    For use by svalue::operator==.  */
@@ -675,6 +680,8 @@ region_svalue::eval_condition (region_svalue *lhs,
 
 /* class constant_svalue : public svalue.  */
 
+IMPL_POOL_ALLOCATOR (constant_svalue)
+
 /* Compare the fields of this constant_svalue with OTHER, returning true
    if they are equal.
    For use by svalue::operator==.  */
@@ -811,6 +818,8 @@ constant_svalue::get_child_sid (region *parent ATTRIBUTE_UNUSED,
 
 /* class unknown_svalue : public svalue.  */
 
+IMPL_POOL_ALLOCATOR (unknown_svalue)
+
 /* Compare the fields of this unknown_svalue with OTHER, returning true
    if they are equal.
    For use by svalue::operator==.  */
@@ -862,6 +871,8 @@ poison_kind_to_str (enum poison_kind kind)
 
 /* class poisoned_svalue : public svalue.  */
 
+IMPL_POOL_ALLOCATOR (poisoned_svalue)
+
 /* Compare the fields of this poisoned_svalue with OTHER, returning true
    if they are equal.
    For use by svalue::operator==.  */
@@ -2190,6 +2201,8 @@ struct_or_union_region::compare_fields (const struct_or_union_region &other)
 
 /* class struct_region : public struct_or_union_region.  */
 
+IMPL_POOL_ALLOCATOR (struct_region)
+
 /* Implementation of region::clone vfunc for struct_region.  */
 
 region *
@@ -2210,6 +2223,8 @@ struct_region::compare_fields (const struct_region &other) const
 
 /* class union_region : public struct_or_union_region.  */
 
+IMPL_POOL_ALLOCATOR (union_region)
+
 /* Implementation of region::clone vfunc for union_region.  */
 
 region *
@@ -2502,6 +2517,8 @@ array_region::key_from_constant (tree cst)
 
 /* class frame_region : public map_region.  */
 
+IMPL_POOL_ALLOCATOR (frame_region)
+
 /* Compare the fields of this frame_region with OTHER, returning true
    if they are equal.
    For use by region::operator==.  */
@@ -2645,6 +2662,8 @@ function_region::valid_key_p (tree key) const
 
 /* class stack_region : public region.  */
 
+IMPL_POOL_ALLOCATOR (stack_region)
+
 /* stack_region's copy ctor.  */
 
 stack_region::stack_region (const stack_region &other)
@@ -2885,6 +2904,8 @@ stack_region::get_value_by_name (tree identifier,
 
 /* class heap_region : public region.  */
 
+IMPL_POOL_ALLOCATOR (heap_region)
+
 /* heap_region's copy ctor.  */
 
 heap_region::heap_region (const heap_region &other)
@@ -2946,6 +2967,8 @@ heap_region::walk_for_canonicalization (canonicalization *) const
 
 /* class root_region : public region.  */
 
+IMPL_POOL_ALLOCATOR (root_region)
+
 /* root_region's default ctor.  */
 
 root_region::root_region ()
@@ -3368,6 +3391,8 @@ root_region::get_value_by_name (tree identifier,
 
 /* class symbolic_region : public map_region.  */
 
+IMPL_POOL_ALLOCATOR (symbolic_region)
+
 /* symbolic_region's copy ctor.  */
 
 symbolic_region::symbolic_region (const symbolic_region &other)
@@ -3407,6 +3432,8 @@ symbolic_region::walk_for_canonicalization (canonicalization *) const
 
 /* class region_model.  */
 
+IMPL_POOL_ALLOCATOR (region_model)
+
 /* region_model's default ctor.  */
 
 region_model::region_model ()
diff --git a/gcc/analyzer/region-model.h b/gcc/analyzer/region-model.h
index bd0c59c..8a919a1 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -521,6 +521,9 @@ public:
 class region_svalue : public svalue
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   region_svalue (tree type, region_id rid) : svalue (type), m_rid (rid)
   {
     /* Should we support NULL ptrs here?  */
@@ -581,6 +584,9 @@ is_a_helper <region_svalue *>::test (svalue *sval)
 class constant_svalue : public svalue
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   constant_svalue (tree cst_expr)
   : svalue (TREE_TYPE (cst_expr)), m_cst_expr (cst_expr)
   {
@@ -642,6 +648,9 @@ is_a_helper <constant_svalue *>::test (svalue *sval)
 class unknown_svalue : public svalue
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   unknown_svalue (tree type)
   : svalue (type)
   {}
@@ -686,6 +695,9 @@ extern const char *poison_kind_to_str (enum poison_kind);
 class poisoned_svalue : public svalue
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   poisoned_svalue (enum poison_kind kind, tree type)
   : svalue (type), m_kind (kind) {}
 
@@ -1034,6 +1046,9 @@ is_a_helper <struct_or_union_region *>::test (region *reg)
 class struct_region : public struct_or_union_region
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   struct_region (region_id parent_rid, tree type)
   : struct_or_union_region (parent_rid, type)
   {
@@ -1061,6 +1076,9 @@ is_a_helper <struct_region *>::test (region *reg)
 class union_region : public struct_or_union_region
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   union_region (region_id parent_rid, tree type)
   : struct_or_union_region (parent_rid, type)
   {
@@ -1361,6 +1379,9 @@ is_a_helper <array_region *>::test (region *reg)
 class stack_region : public region
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   stack_region (region_id parent_rid, svalue_id sval_id)
   : region (parent_rid, sval_id, NULL_TREE)
   {}
@@ -1422,6 +1443,9 @@ is_a_helper <stack_region *>::test (region *reg)
 class heap_region : public region
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   heap_region (region_id parent_rid, svalue_id sval_id)
   : region (parent_rid, sval_id, NULL_TREE)
   {}
@@ -1457,6 +1481,9 @@ is_a_helper <heap_region *>::test (region *reg)
 class root_region : public region
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   root_region ();
   root_region (const root_region &other);
 
@@ -1532,6 +1559,9 @@ is_a_helper <root_region *>::test (region *reg)
 class symbolic_region : public region
 {
 public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   symbolic_region (region_id parent_rid, bool possibly_null)
   : region (parent_rid, svalue_id::null (), NULL_TREE),
     m_possibly_null (possibly_null)
@@ -1564,6 +1594,9 @@ public:
 class region_model
 {
  public:
+  static void *operator new (size_t sz);
+  static void operator delete (void* ptr, size_t sz);
+
   region_model ();
   region_model (const region_model &other);
   ~region_model ();
-- 
1.8.5.3

