From b688dfdb93de7f5b18d1fe3a0664546c5568a117 Mon Sep 17 00:00:00 2001
From: David Malcolm <dmalcolm@redhat.com>
Date: Tue, 8 Oct 2019 08:52:59 -0400
Subject: [PATCH 57/75] 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       | 25 ++++++++++++++++++++++
 gcc/analyzer/region-model.h        | 33 ++++++++++++++++++++++++++++++
 5 files changed, 86 insertions(+)

diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index 199084c4c79..26811350122 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -119,4 +119,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 669d604e1b7..fd820ef069e 100644
--- a/gcc/analyzer/constraint-manager.cc
+++ b/gcc/analyzer/constraint-manager.cc
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple.h"
 #include "gimple-iterator.h"
 #include "fold-const.h"
+#include "alloc-pool.h"
 #include "selftest.h"
 #include "graphviz.h"
 #include "function.h"
@@ -159,6 +160,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 c6a40f90a33..32073c4db5f 100644
--- a/gcc/analyzer/constraint-manager.h
+++ b/gcc/analyzer/constraint-manager.h
@@ -39,6 +39,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 ccbf85d316b..4c296d37604 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -35,6 +35,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "fold-const.h"
 #include "tree-pretty-print.h"
+#include "alloc-pool.h"
 #include "diagnostic-color.h"
 #include "diagnostic-metadata.h"
 #include "diagnostic-core.h"
@@ -393,6 +394,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==.  */
@@ -607,6 +612,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==.  */
@@ -710,6 +717,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==.  */
@@ -761,6 +770,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==.  */
@@ -2016,6 +2027,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 *
@@ -2036,6 +2049,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 *
@@ -2467,6 +2482,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)
@@ -2707,6 +2724,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)
@@ -2744,6 +2763,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 ()
@@ -3160,6 +3181,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)
@@ -3197,6 +3220,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 eea808e61eb..8892d3b791a 100644
--- a/gcc/analyzer/region-model.h
+++ b/gcc/analyzer/region-model.h
@@ -502,6 +502,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?  */
@@ -562,6 +565,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)
   {
@@ -621,6 +627,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)
   {}
@@ -665,6 +674,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) {}
 
@@ -1011,6 +1023,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)
   {
@@ -1038,6 +1053,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)
   {
@@ -1338,6 +1356,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)
   {}
@@ -1399,6 +1420,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)
   {}
@@ -1434,6 +1458,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);
 
@@ -1509,6 +1536,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)
@@ -1539,6 +1569,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 ();
-- 
2.21.0

