public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [pushed] analyzer: add symbol base class, moving region id to there [PR104940]
@ 2023-07-26 14:33 David Malcolm
  0 siblings, 0 replies; only message in thread
From: David Malcolm @ 2023-07-26 14:33 UTC (permalink / raw)
  To: gcc-patches; +Cc: David Malcolm

This patch introduces a "symbol" base class that region and svalue
both inherit from, generalizing the ID from the region class so it's
also used by svalues.  This gives a way of sorting regions and svalues
into creation order, which I've found useful in my experiments with
adding SMT support (PR analyzer/104940).

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as r14-2793-g9d804f9b2709b3.

gcc/ChangeLog:
	PR analyzer/104940
	* Makefile.in (ANALYZER_OBJS): Add analyzer/symbol.o.

gcc/analyzer/ChangeLog:
	PR analyzer/104940
	* region-model-manager.cc
	(region_model_manager::region_model_manager): Update for
	generalizing region ids to also cover svalues.
	(region_model_manager::get_or_create_constant_svalue): Likewise.
	(region_model_manager::get_or_create_unknown_svalue): Likewise.
	(region_model_manager::create_unique_svalue): Likewise.
	(region_model_manager::get_or_create_initial_value): Likewise.
	(region_model_manager::get_or_create_setjmp_svalue): Likewise.
	(region_model_manager::get_or_create_poisoned_svalue): Likewise.
	(region_model_manager::get_ptr_svalue): Likewise.
	(region_model_manager::get_or_create_unaryop): Likewise.
	(region_model_manager::get_or_create_binop): Likewise.
	(region_model_manager::get_or_create_sub_svalue): Likewise.
	(region_model_manager::get_or_create_repeated_svalue): Likewise.
	(region_model_manager::get_or_create_bits_within): Likewise.
	(region_model_manager::get_or_create_unmergeable): Likewise.
	(region_model_manager::get_or_create_widening_svalue): Likewise.
	(region_model_manager::get_or_create_compound_svalue): Likewise.
	(region_model_manager::get_or_create_conjured_svalue): Likewise.
	(region_model_manager::get_or_create_asm_output_svalue): Likewise.
	(region_model_manager::get_or_create_const_fn_result_svalue):
	Likewise.
	(region_model_manager::get_region_for_fndecl): Likewise.
	(region_model_manager::get_region_for_label): Likewise.
	(region_model_manager::get_region_for_global): Likewise.
	(region_model_manager::get_field_region): Likewise.
	(region_model_manager::get_element_region): Likewise.
	(region_model_manager::get_offset_region): Likewise.
	(region_model_manager::get_sized_region): Likewise.
	(region_model_manager::get_cast_region): Likewise.
	(region_model_manager::get_frame_region): Likewise.
	(region_model_manager::get_symbolic_region): Likewise.
	(region_model_manager::get_region_for_string): Likewise.
	(region_model_manager::get_bit_range): Likewise.
	(region_model_manager::get_var_arg_region): Likewise.
	(region_model_manager::get_region_for_unexpected_tree_code):
	Likewise.
	(region_model_manager::get_or_create_region_for_heap_alloc):
	Likewise.
	(region_model_manager::create_region_for_alloca): Likewise.
	(region_model_manager::log_stats): Likewise.
	* region-model-manager.h (region_model_manager::get_num_regions):
	Replace with...
	(region_model_manager::get_num_symbols): ...this.
	(region_model_manager::alloc_region_id): Replace with...
	(region_model_manager::alloc_symbol_id): ...this.
	(region_model_manager::m_next_region_id): Replace with...
	(region_model_manager::m_next_symbol_id): ...this.
	* region-model.cc (selftest::test_get_representative_tree): Update
	for generalizing region ids to also cover svalues.
	(selftest::test_binop_svalue_folding): Likewise.
	(selftest::test_state_merging): Likewise.
	* region.cc (region::cmp_ids): Delete, in favor of
	symbol::cmp_ids.
	(region::region): Update for introduction of symbol base class.
	(frame_region::get_region_for_local): Likewise.
	(root_region::root_region): Likewise.
	(symbolic_region::symbolic_region): Likewise.
	* region.h: Replace include of "analyzer/complexity.h" with
	"analyzer/symbol.h".
	(class region): Make a subclass of symbol.
	(region::get_id): Delete in favor of symbol::get_id.
	(region::cmp_ids): Delete in favor of symbol::cmp_ids.
	(region::get_complexity): Delete in favor of
	symbol::get_complexity.
	(region::region): Use symbol::id_t for "id" param.
	(region::m_complexity): Move field to symbol base class.
	(region::m_id): Likewise.
	(space_region::space_region): Use symbol::id_t for "id" param.
	(frame_region::frame_region): Likewise.
	(globals_region::globals_region): Likewise.
	(code_region::code_region): Likewise.
	(function_region::function_region): Likewise.
	(label_region::label_region): Likewise.
	(stack_region::stack_region): Likewise.
	(heap_region::heap_region): Likewise.
	(thread_local_region::thread_local_region): Likewise.
	(root_region::root_region): Likewise.
	(symbolic_region::symbolic_region): Likewise.
	(decl_region::decl_region): Likewise.
	(field_region::field_region): Likewise.
	(element_region::element_region): Likewise.
	(offset_region::offset_region): Likewise.
	(sized_region::sized_region): Likewise.
	(cast_region::cast_region): Likewise.
	(heap_allocated_region::heap_allocated_region): Likewise.
	(alloca_region::alloca_region): Likewise.
	(string_region::string_region): Likewise.
	(bit_range_region::bit_range_region): Likewise.
	(var_arg_region::var_arg_region): Likewise.
	(errno_region::errno_region): Likewise.
	(unknown_region::unknown_region): Likewise.
	* svalue.cc (sub_svalue::sub_svalue): Add symbol::id_t param.
	(repeated_svalue::repeated_svalue): Likewise.
	(bits_within_svalue::bits_within_svalue): Likewise.
	(compound_svalue::compound_svalue): Likewise.
	* svalue.h: Replace include of "analyzer/complexity.h" with
	"analyzer/symbol.h".
	(class svalue): Make a subclass of symbol.
	(svalue::get_complexity): Delete in favor of
	symbol::get_complexity.
	(svalue::svalue): Add symbol::id_t param.  Update for new base
	class.
	(svalue::m_complexity): Delete in favor of
	symbol::m_complexity.
	(region_svalue::region_svalue): Add symbol::id_t param
	(constant_svalue::constant_svalue): Likewise.
	(unknown_svalue::unknown_svalue): Likewise.
	(poisoned_svalue::poisoned_svalue): Likewise.
	(setjmp_svalue::setjmp_svalue): Likewise.
	(initial_svalue::initial_svalue): Likewise.
	(unaryop_svalue::unaryop_svalue): Likewise.
	(binop_svalue::binop_svalue): Likewise.
	(sub_svalue::sub_svalue): Likewise.
	(repeated_svalue::repeated_svalue): Likewise.
	(bits_within_svalue::bits_within_svalue): Likewise.
	(unmergeable_svalue::unmergeable_svalue): Likewise.
	(placeholder_svalue::placeholder_svalue): Likewise.
	(widening_svalue::widening_svalue): Likewise.
	(compound_svalue::compound_svalue): Likewise.
	(conjured_svalue::conjured_svalue): Likewise.
	(asm_output_svalue::asm_output_svalue): Likewise.
	(const_fn_result_svalue::const_fn_result_svalue): Likewise.
	* symbol.cc: New file.
	* symbol.h: New file.
---
 gcc/Makefile.in                      |   1 +
 gcc/analyzer/region-model-manager.cc | 100 +++++++++++++++------------
 gcc/analyzer/region-model-manager.h  |   9 +--
 gcc/analyzer/region-model.cc         |  21 ++++--
 gcc/analyzer/region.cc               |  19 ++---
 gcc/analyzer/region.h                |  61 ++++++++--------
 gcc/analyzer/svalue.cc               |  20 ++++--
 gcc/analyzer/svalue.h                |  86 ++++++++++++-----------
 gcc/analyzer/symbol.cc               |  43 ++++++++++++
 gcc/analyzer/symbol.h                |  53 ++++++++++++++
 10 files changed, 263 insertions(+), 150 deletions(-)
 create mode 100644 gcc/analyzer/symbol.cc
 create mode 100644 gcc/analyzer/symbol.h

diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 683774ad446..e99628cec07 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -1327,6 +1327,7 @@ ANALYZER_OBJS = \
 	analyzer/store.o \
 	analyzer/supergraph.o \
 	analyzer/svalue.o \
+	analyzer/symbol.o \
 	analyzer/trimmed-graph.o \
 	analyzer/varargs.o
 
diff --git a/gcc/analyzer/region-model-manager.cc b/gcc/analyzer/region-model-manager.cc
index e43b99ae0ba..46d271a295c 100644
--- a/gcc/analyzer/region-model-manager.cc
+++ b/gcc/analyzer/region-model-manager.cc
@@ -62,20 +62,20 @@ namespace ana {
 
 region_model_manager::region_model_manager (logger *logger)
 : m_logger (logger),
+  m_next_symbol_id (0),
   m_empty_call_string (),
-  m_next_region_id (0),
-  m_root_region (alloc_region_id ()),
-  m_stack_region (alloc_region_id (), &m_root_region),
-  m_heap_region (alloc_region_id (), &m_root_region),
+  m_root_region (alloc_symbol_id ()),
+  m_stack_region (alloc_symbol_id (), &m_root_region),
+  m_heap_region (alloc_symbol_id (), &m_root_region),
   m_unknown_NULL (NULL),
   m_checking_feasibility (false),
   m_max_complexity (0, 0),
-  m_code_region (alloc_region_id (), &m_root_region),
+  m_code_region (alloc_symbol_id (), &m_root_region),
   m_fndecls_map (), m_labels_map (),
-  m_globals_region (alloc_region_id (), &m_root_region),
+  m_globals_region (alloc_symbol_id (), &m_root_region),
   m_globals_map (),
-  m_thread_local_region (alloc_region_id (), &m_root_region),
-  m_errno_region (alloc_region_id (), &m_thread_local_region),
+  m_thread_local_region (alloc_symbol_id (), &m_root_region),
+  m_errno_region (alloc_symbol_id (), &m_thread_local_region),
   m_store_mgr (this),
   m_range_mgr (new bounded_ranges_manager ()),
   m_known_fn_mgr (logger)
@@ -220,7 +220,8 @@ region_model_manager::get_or_create_constant_svalue (tree cst_expr)
   constant_svalue **slot = m_constants_map.get (cst_expr);
   if (slot)
     return *slot;
-  constant_svalue *cst_sval = new constant_svalue (cst_expr);
+  constant_svalue *cst_sval
+    = new constant_svalue (alloc_symbol_id (), cst_expr);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (cst_sval);
   m_constants_map.put (cst_expr, cst_sval);
   return cst_sval;
@@ -268,14 +269,14 @@ region_model_manager::get_or_create_unknown_svalue (tree type)
   if (type == NULL_TREE)
     {
       if (!m_unknown_NULL)
-	m_unknown_NULL = new unknown_svalue (type);
+	m_unknown_NULL = new unknown_svalue (alloc_symbol_id (), type);
       return m_unknown_NULL;
     }
 
   unknown_svalue **slot = m_unknowns_map.get (type);
   if (slot)
     return *slot;
-  unknown_svalue *sval = new unknown_svalue (type);
+  unknown_svalue *sval = new unknown_svalue (alloc_symbol_id (), type);
   m_unknowns_map.put (type, sval);
   return sval;
 }
@@ -285,7 +286,7 @@ region_model_manager::get_or_create_unknown_svalue (tree type)
 const svalue *
 region_model_manager::create_unique_svalue (tree type)
 {
-  svalue *sval = new placeholder_svalue (type, "unique");
+  svalue *sval = new placeholder_svalue (alloc_symbol_id (), type, "unique");
   m_managed_dynamic_svalues.safe_push (sval);
   return sval;
 }
@@ -315,7 +316,8 @@ region_model_manager::get_or_create_initial_value (const region *reg,
 
   if (initial_svalue **slot = m_initial_values_map.get (reg))
     return *slot;
-  initial_svalue *initial_sval = new initial_svalue (reg->get_type (), reg);
+  initial_svalue *initial_sval
+    = new initial_svalue (alloc_symbol_id (), reg->get_type (), reg);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (initial_sval);
   m_initial_values_map.put (reg, initial_sval);
   return initial_sval;
@@ -331,7 +333,7 @@ region_model_manager::get_or_create_setjmp_svalue (const setjmp_record &r,
   setjmp_svalue::key_t key (r, type);
   if (setjmp_svalue **slot = m_setjmp_values_map.get (key))
     return *slot;
-  setjmp_svalue *setjmp_sval = new setjmp_svalue (r, type);
+  setjmp_svalue *setjmp_sval = new setjmp_svalue (r, alloc_symbol_id (), type);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (setjmp_sval);
   m_setjmp_values_map.put (key, setjmp_sval);
   return setjmp_sval;
@@ -347,7 +349,8 @@ region_model_manager::get_or_create_poisoned_svalue (enum poison_kind kind,
   poisoned_svalue::key_t key (kind, type);
   if (poisoned_svalue **slot = m_poisoned_values_map.get (key))
     return *slot;
-  poisoned_svalue *poisoned_sval = new poisoned_svalue (kind, type);
+  poisoned_svalue *poisoned_sval
+    = new poisoned_svalue (kind, alloc_symbol_id (), type);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (poisoned_sval);
   m_poisoned_values_map.put (key, poisoned_sval);
   return poisoned_sval;
@@ -368,7 +371,8 @@ region_model_manager::get_ptr_svalue (tree ptr_type, const region *pointee)
   region_svalue::key_t key (ptr_type, pointee);
   if (region_svalue **slot = m_pointer_values_map.get (key))
     return *slot;
-  region_svalue *sval = new region_svalue (ptr_type, pointee);
+  region_svalue *sval
+    = new region_svalue (alloc_symbol_id (), ptr_type, pointee);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (sval);
   m_pointer_values_map.put (key, sval);
   return sval;
@@ -491,7 +495,8 @@ region_model_manager::get_or_create_unaryop (tree type, enum tree_code op,
   unaryop_svalue::key_t key (type, op, arg);
   if (unaryop_svalue **slot = m_unaryop_values_map.get (key))
     return *slot;
-  unaryop_svalue *unaryop_sval = new unaryop_svalue (type, op, arg);
+  unaryop_svalue *unaryop_sval
+    = new unaryop_svalue (alloc_symbol_id (), type, op, arg);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (unaryop_sval);
   m_unaryop_values_map.put (key, unaryop_sval);
   return unaryop_sval;
@@ -797,7 +802,8 @@ region_model_manager::get_or_create_binop (tree type, enum tree_code op,
   binop_svalue::key_t key (type, op, arg0, arg1);
   if (binop_svalue **slot = m_binop_values_map.get (key))
     return *slot;
-  binop_svalue *binop_sval = new binop_svalue (type, op, arg0, arg1);
+  binop_svalue *binop_sval
+    = new binop_svalue (alloc_symbol_id (), type, op, arg0, arg1);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (binop_sval);
   m_binop_values_map.put (key, binop_sval);
   return binop_sval;
@@ -903,7 +909,7 @@ region_model_manager::get_or_create_sub_svalue (tree type,
   if (sub_svalue **slot = m_sub_values_map.get (key))
     return *slot;
   sub_svalue *sub_sval
-    = new sub_svalue (type, parent_svalue, subregion);
+    = new sub_svalue (alloc_symbol_id (), type, parent_svalue, subregion);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (sub_sval);
   m_sub_values_map.put (key, sub_sval);
   return sub_sval;
@@ -964,7 +970,7 @@ region_model_manager::get_or_create_repeated_svalue (tree type,
   if (repeated_svalue **slot = m_repeated_values_map.get (key))
     return *slot;
   repeated_svalue *repeated_sval
-    = new repeated_svalue (type, outer_size, inner_svalue);
+    = new repeated_svalue (alloc_symbol_id (), type, outer_size, inner_svalue);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (repeated_sval);
   m_repeated_values_map.put (key, repeated_sval);
   return repeated_sval;
@@ -1157,7 +1163,7 @@ region_model_manager::get_or_create_bits_within (tree type,
   if (bits_within_svalue **slot = m_bits_within_values_map.get (key))
     return *slot;
   bits_within_svalue *bits_within_sval
-    = new bits_within_svalue (type, bits, inner_svalue);
+    = new bits_within_svalue (alloc_symbol_id (), type, bits, inner_svalue);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (bits_within_sval);
   m_bits_within_values_map.put (key, bits_within_sval);
   return bits_within_sval;
@@ -1174,7 +1180,8 @@ region_model_manager::get_or_create_unmergeable (const svalue *arg)
 
   if (unmergeable_svalue **slot = m_unmergeable_values_map.get (arg))
     return *slot;
-  unmergeable_svalue *unmergeable_sval = new unmergeable_svalue (arg);
+  unmergeable_svalue *unmergeable_sval
+    = new unmergeable_svalue (alloc_symbol_id (), arg);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (unmergeable_sval);
   m_unmergeable_values_map.put (arg, unmergeable_sval);
   return unmergeable_sval;
@@ -1196,7 +1203,8 @@ get_or_create_widening_svalue (tree type,
   if (widening_svalue **slot = m_widening_values_map.get (key))
     return *slot;
   widening_svalue *widening_sval
-    = new widening_svalue (type, point, base_sval, iter_sval);
+    = new widening_svalue (alloc_symbol_id (), type, point, base_sval,
+			   iter_sval);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (widening_sval);
   m_widening_values_map.put (key, widening_sval);
   return widening_sval;
@@ -1213,7 +1221,7 @@ region_model_manager::get_or_create_compound_svalue (tree type,
   if (compound_svalue **slot = m_compound_values_map.get (tmp_key))
     return *slot;
   compound_svalue *compound_sval
-    = new compound_svalue (type, map);
+    = new compound_svalue (alloc_symbol_id (), type, map);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (compound_sval);
   /* Use make_key rather than reusing the key, so that we use a
      ptr to compound_sval's binding_map, rather than the MAP param.  */
@@ -1254,7 +1262,7 @@ region_model_manager::get_or_create_conjured_svalue (tree type,
       return sval;
     }
   conjured_svalue *conjured_sval
-    = new conjured_svalue (type, stmt, id_reg);
+    = new conjured_svalue (alloc_symbol_id (), type, stmt, id_reg);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (conjured_sval);
   m_conjured_values_map.put (key, conjured_sval);
   return conjured_sval;
@@ -1299,7 +1307,8 @@ get_or_create_asm_output_svalue (tree type,
   if (asm_output_svalue **slot = m_asm_output_values_map.get (key))
     return *slot;
   asm_output_svalue *asm_output_sval
-    = new asm_output_svalue (type, asm_string, output_idx, noutputs, inputs);
+    = new asm_output_svalue (alloc_symbol_id (), type, asm_string, output_idx,
+			     noutputs, inputs);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (asm_output_sval);
   m_asm_output_values_map.put (key, asm_output_sval);
   return asm_output_sval;
@@ -1327,7 +1336,8 @@ get_or_create_asm_output_svalue (tree type,
   if (asm_output_svalue **slot = m_asm_output_values_map.get (key))
     return *slot;
   asm_output_svalue *asm_output_sval
-    = new asm_output_svalue (type, asm_string, output_idx, num_outputs, inputs);
+    = new asm_output_svalue (alloc_symbol_id (), type, asm_string, output_idx,
+			     num_outputs, inputs);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (asm_output_sval);
   m_asm_output_values_map.put (key, asm_output_sval);
   return asm_output_sval;
@@ -1352,7 +1362,7 @@ get_or_create_const_fn_result_svalue (tree type,
   if (const_fn_result_svalue **slot = m_const_fn_result_values_map.get (key))
     return *slot;
   const_fn_result_svalue *const_fn_result_sval
-    = new const_fn_result_svalue (type, fndecl, inputs);
+    = new const_fn_result_svalue (alloc_symbol_id (), type, fndecl, inputs);
   RETURN_UNKNOWN_IF_TOO_COMPLEX (const_fn_result_sval);
   m_const_fn_result_values_map.put (key, const_fn_result_sval);
   return const_fn_result_sval;
@@ -1399,7 +1409,7 @@ region_model_manager::get_region_for_fndecl (tree fndecl)
   if (slot)
     return *slot;
   function_region *reg
-    = new function_region (alloc_region_id (), &m_code_region, fndecl);
+    = new function_region (alloc_symbol_id (), &m_code_region, fndecl);
   m_fndecls_map.put (fndecl, reg);
   return reg;
 }
@@ -1420,7 +1430,7 @@ region_model_manager::get_region_for_label (tree label)
 
   const function_region *func_reg = get_region_for_fndecl (fndecl);
   label_region *reg
-    = new label_region (alloc_region_id (), func_reg, label);
+    = new label_region (alloc_symbol_id (), func_reg, label);
   m_labels_map.put (label, reg);
   return reg;
 }
@@ -1436,7 +1446,7 @@ region_model_manager::get_region_for_global (tree expr)
   if (slot)
     return *slot;
   decl_region *reg
-    = new decl_region (alloc_region_id (), &m_globals_region, expr);
+    = new decl_region (alloc_symbol_id (), &m_globals_region, expr);
   m_globals_map.put (expr, reg);
   return reg;
 }
@@ -1471,7 +1481,7 @@ region_model_manager::get_field_region (const region *parent, tree field)
     return reg;
 
   field_region *field_reg
-    = new field_region (alloc_region_id (), parent, field);
+    = new field_region (alloc_symbol_id (), parent, field);
   m_field_regions.put (key, field_reg);
   return field_reg;
 }
@@ -1493,7 +1503,7 @@ region_model_manager::get_element_region (const region *parent,
     return reg;
 
   element_region *element_reg
-    = new element_region (alloc_region_id (), parent, element_type, index);
+    = new element_region (alloc_symbol_id (), parent, element_type, index);
   m_element_regions.put (key, element_reg);
   return element_reg;
 }
@@ -1533,7 +1543,7 @@ region_model_manager::get_offset_region (const region *parent,
     return reg;
 
   offset_region *offset_reg
-    = new offset_region (alloc_region_id (), parent, type, byte_offset);
+    = new offset_region (alloc_symbol_id (), parent, type, byte_offset);
   m_offset_regions.put (key, offset_reg);
   return offset_reg;
 }
@@ -1568,7 +1578,7 @@ region_model_manager::get_sized_region (const region *parent,
     return reg;
 
   sized_region *sized_reg
-    = new sized_region (alloc_region_id (), parent, type, byte_size_sval);
+    = new sized_region (alloc_symbol_id (), parent, type, byte_size_sval);
   m_sized_regions.put (key, sized_reg);
   return sized_reg;
 }
@@ -1592,7 +1602,7 @@ region_model_manager::get_cast_region (const region *original_region,
     return reg;
 
   cast_region *cast_reg
-    = new cast_region (alloc_region_id (), original_region, type);
+    = new cast_region (alloc_symbol_id (), original_region, type);
   m_cast_regions.put (key, cast_reg);
   return cast_reg;
 }
@@ -1611,7 +1621,7 @@ region_model_manager::get_frame_region (const frame_region *calling_frame,
     return reg;
 
   frame_region *frame_reg
-    = new frame_region (alloc_region_id (), &m_stack_region, calling_frame,
+    = new frame_region (alloc_symbol_id (), &m_stack_region, calling_frame,
 			 fun, index);
   m_frame_regions.put (key, frame_reg);
   return frame_reg;
@@ -1628,7 +1638,7 @@ region_model_manager::get_symbolic_region (const svalue *sval)
     return reg;
 
   symbolic_region *symbolic_reg
-    = new symbolic_region (alloc_region_id (), &m_root_region, sval);
+    = new symbolic_region (alloc_symbol_id (), &m_root_region, sval);
   m_symbolic_regions.put (key, symbolic_reg);
   return symbolic_reg;
 }
@@ -1645,7 +1655,7 @@ region_model_manager::get_region_for_string (tree string_cst)
   if (slot)
     return *slot;
   string_region *reg
-    = new string_region (alloc_region_id (), &m_root_region, string_cst);
+    = new string_region (alloc_symbol_id (), &m_root_region, string_cst);
   m_string_map.put (string_cst, reg);
   return reg;
 }
@@ -1667,7 +1677,7 @@ region_model_manager::get_bit_range (const region *parent, tree type,
     return reg;
 
   bit_range_region *bit_range_reg
-    = new bit_range_region (alloc_region_id (), parent, type, bits);
+    = new bit_range_region (alloc_symbol_id (), parent, type, bits);
   m_bit_range_regions.put (key, bit_range_reg);
   return bit_range_reg;
 }
@@ -1686,7 +1696,7 @@ region_model_manager::get_var_arg_region (const frame_region *parent_frame,
     return reg;
 
   var_arg_region *var_arg_reg
-    = new var_arg_region (alloc_region_id (), parent_frame, idx);
+    = new var_arg_region (alloc_symbol_id (), parent_frame, idx);
   m_var_arg_regions.put (key, var_arg_reg);
   return var_arg_reg;
 }
@@ -1706,7 +1716,7 @@ get_region_for_unexpected_tree_code (region_model_context *ctxt,
 {
   tree type = TYPE_P (t) ? t : TREE_TYPE (t);
   region *new_reg
-    = new unknown_region (alloc_region_id (), &m_root_region, type);
+    = new unknown_region (alloc_symbol_id (), &m_root_region, type);
   if (ctxt)
     ctxt->on_unexpected_tree_code (t, loc);
   return new_reg;
@@ -1729,7 +1739,7 @@ get_or_create_region_for_heap_alloc (const bitmap &base_regs_in_use)
 
   /* All existing ones (if any) are in use; create a new one.  */
   region *reg
-    = new heap_allocated_region (alloc_region_id (), &m_heap_region);
+    = new heap_allocated_region (alloc_symbol_id (), &m_heap_region);
   m_managed_dynamic_regions.safe_push (reg);
   return reg;
 }
@@ -1740,7 +1750,7 @@ const region *
 region_model_manager::create_region_for_alloca (const frame_region *frame)
 {
   gcc_assert (frame);
-  region *reg = new alloca_region (alloc_region_id (), frame);
+  region *reg = new alloca_region (alloc_symbol_id (), frame);
   m_managed_dynamic_regions.safe_push (reg);
   return reg;
 }
@@ -1832,6 +1842,7 @@ region_model_manager::log_stats (logger *logger, bool show_objs) const
   LOG_SCOPE (logger);
   logger->log ("call string consolidation");
   m_empty_call_string.recursive_log (logger);
+  logger->log ("next symbol id: %i", m_next_symbol_id);
   logger->log ("svalue consolidation");
   log_uniq_map (logger, show_objs, "constant_svalue", m_constants_map);
   log_uniq_map (logger, show_objs, "unknown_svalue", m_unknowns_map);
@@ -1863,7 +1874,6 @@ region_model_manager::log_stats (logger *logger, bool show_objs) const
 	       m_max_complexity.m_max_depth);
 
   logger->log ("region consolidation");
-  logger->log ("  next region id: %i", m_next_region_id);
   log_uniq_map (logger, show_objs, "function_region", m_fndecls_map);
   log_uniq_map (logger, show_objs, "label_region", m_labels_map);
   log_uniq_map (logger, show_objs, "decl_region for globals", m_globals_map);
diff --git a/gcc/analyzer/region-model-manager.h b/gcc/analyzer/region-model-manager.h
index ff5333bf07c..a5281819a69 100644
--- a/gcc/analyzer/region-model-manager.h
+++ b/gcc/analyzer/region-model-manager.h
@@ -34,6 +34,9 @@ public:
   region_model_manager (logger *logger = NULL);
   ~region_model_manager ();
 
+  unsigned get_num_symbols () const { return m_next_symbol_id; }
+  unsigned alloc_symbol_id () { return m_next_symbol_id++; }
+
   /* call_string consolidation.  */
   const call_string &get_empty_call_string () const
   {
@@ -102,7 +105,6 @@ public:
   const svalue *create_unique_svalue (tree type);
 
   /* region consolidation.  */
-  unsigned get_num_regions () const { return m_next_region_id; }
   const stack_region * get_stack_region () const { return &m_stack_region; }
   const heap_region *get_heap_region () const { return &m_heap_region; }
   const code_region *get_code_region () const { return &m_code_region; }
@@ -142,8 +144,6 @@ public:
 				       tree t,
 				       const dump_location_t &loc);
 
-  unsigned alloc_region_id () { return m_next_region_id++; }
-
   store_manager *get_store_manager () { return &m_store_mgr; }
   bounded_ranges_manager *get_range_manager () const { return m_range_mgr; }
 
@@ -193,9 +193,10 @@ private:
 
   logger *m_logger;
 
+  unsigned m_next_symbol_id;
+
   const call_string m_empty_call_string;
 
-  unsigned m_next_region_id;
   root_region m_root_region;
   stack_region m_stack_region;
   heap_region m_heap_region;
diff --git a/gcc/analyzer/region-model.cc b/gcc/analyzer/region-model.cc
index e01b1c88299..5ed735dc2a2 100644
--- a/gcc/analyzer/region-model.cc
+++ b/gcc/analyzer/region-model.cc
@@ -6161,7 +6161,8 @@ test_get_representative_tree ()
     tree tlen = size_int (10);
     tree arr_type = build_array_type (char_type_node, build_index_type (tlen));
     tree a = build_global_decl ("a", arr_type);
-    placeholder_svalue test_sval (char_type_node, "test value");
+    placeholder_svalue test_sval (mgr.alloc_symbol_id (),
+				  char_type_node, "test value");
 
     /* Value of a[3].  */
     {
@@ -6206,7 +6207,8 @@ test_get_representative_tree ()
     {
       region_model m (&mgr);
       const region *c_x_reg = m.get_lvalue (c_x, &ctxt);
-      placeholder_svalue test_sval_x (integer_type_node, "test x val");
+      placeholder_svalue test_sval_x (mgr.alloc_symbol_id (),
+				      integer_type_node, "test x val");
       m.set_value (c_x_reg, &test_sval_x, &ctxt);
       tree rep = m.get_representative_tree (&test_sval_x);
       ASSERT_DUMP_TREE_EQ (rep, "c.x");
@@ -6216,7 +6218,8 @@ test_get_representative_tree ()
     {
       region_model m (&mgr);
       const region *c_y_reg = m.get_lvalue (c_y, &ctxt);
-      placeholder_svalue test_sval_y (integer_type_node, "test y val");
+      placeholder_svalue test_sval_y (mgr.alloc_symbol_id (),
+				      integer_type_node, "test y val");
       m.set_value (c_y_reg, &test_sval_y, &ctxt);
       tree rep = m.get_representative_tree (&test_sval_y);
       ASSERT_DUMP_TREE_EQ (rep, "c.y");
@@ -6460,7 +6463,8 @@ test_binop_svalue_folding ()
     const svalue *sval_false = mgr.get_or_create_int_cst (boolean_type_node, 0);
     const svalue *sval_unknown
       = mgr.get_or_create_unknown_svalue (boolean_type_node);
-    const placeholder_svalue sval_placeholder (boolean_type_node, "v");
+    const placeholder_svalue sval_placeholder (mgr.alloc_symbol_id (),
+					       boolean_type_node, "v");
     for (auto op : {BIT_IOR_EXPR, TRUTH_OR_EXPR})
       {
 	ASSERT_EQ (mgr.get_or_create_binop (boolean_type_node, op,
@@ -7072,7 +7076,8 @@ test_state_merging ()
     ASSERT_EQ (model0.get_stack_depth (), 1);
     model1.push_frame (DECL_STRUCT_FUNCTION (test_fndecl), NULL, &ctxt);
 
-    placeholder_svalue test_sval (integer_type_node, "test sval");
+    placeholder_svalue test_sval (mgr.alloc_symbol_id (),
+				  integer_type_node, "test sval");
     model0.set_value (model0.get_lvalue (a, &ctxt), &test_sval, &ctxt);
     model1.set_value (model1.get_lvalue (a, &ctxt), &test_sval, &ctxt);
     ASSERT_EQ (model0, model1);
@@ -7091,7 +7096,8 @@ test_state_merging ()
     region_model model0 (&mgr);
     region_model model1 (&mgr);
 
-    placeholder_svalue test_sval (integer_type_node, "test sval");
+    placeholder_svalue test_sval (mgr.alloc_symbol_id (),
+				  integer_type_node, "test sval");
     model0.set_value (model0.get_lvalue (x, &ctxt), &test_sval, &ctxt);
     model1.set_value (model1.get_lvalue (x, &ctxt), &test_sval, &ctxt);
     ASSERT_EQ (model0, model1);
@@ -7231,7 +7237,8 @@ test_state_merging ()
   {
     test_region_model_context ctxt;
     region_model model0 (&mgr);
-    placeholder_svalue placeholder_sval (integer_type_node, "test");
+    placeholder_svalue placeholder_sval (mgr.alloc_symbol_id (),
+					 integer_type_node, "test");
     model0.set_value (model0.get_lvalue (x, &ctxt),
 		      &placeholder_sval, &ctxt);
     model0.set_value (model0.get_lvalue (y, &ctxt), &placeholder_sval, &ctxt);
diff --git a/gcc/analyzer/region.cc b/gcc/analyzer/region.cc
index 62ae0b2342d..9524739c7a4 100644
--- a/gcc/analyzer/region.cc
+++ b/gcc/analyzer/region.cc
@@ -398,14 +398,6 @@ region::~region ()
   delete m_cached_offset;
 }
 
-/* Compare REG1 and REG2 by id.  */
-
-int
-region::cmp_ids (const region *reg1, const region *reg2)
-{
-  return (long)reg1->get_id () - (long)reg2->get_id ();
-}
-
 /* Determine the base region for this region: when considering bindings
    for this region, the base region is the ancestor which identifies
    which cluster they should be partitioned into.
@@ -1099,8 +1091,9 @@ region::is_named_decl_p (const char *decl_name) const
 
 /* region's ctor.  */
 
-region::region (complexity c, unsigned id, const region *parent, tree type)
-: m_complexity (c), m_id (id), m_parent (parent), m_type (type),
+region::region (complexity c, symbol::id_t id, const region *parent, tree type)
+: symbol (c, id),
+  m_parent (parent), m_type (type),
   m_cached_offset (NULL), m_cached_init_sval_at_main (NULL)
 {
   gcc_assert (type == NULL_TREE || TYPE_P (type));
@@ -1347,7 +1340,7 @@ frame_region::get_region_for_local (region_model_manager *mgr,
   if (decl_region **slot = mutable_locals.get (expr))
     return *slot;
   decl_region *reg
-    = new decl_region (mgr->alloc_region_id (), this, expr);
+    = new decl_region (mgr->alloc_symbol_id (), this, expr);
   mutable_locals.put (expr, reg);
   return reg;
 }
@@ -1446,7 +1439,7 @@ heap_region::dump_to_pp (pretty_printer *pp, bool simple) const
 
 /* root_region's ctor.  */
 
-root_region::root_region (unsigned id)
+root_region::root_region (symbol::id_t id)
 : region (complexity (1, 1), id, NULL, NULL_TREE)
 {
 }
@@ -1477,7 +1470,7 @@ thread_local_region::dump_to_pp (pretty_printer *pp, bool simple) const
 
 /* symbolic_region's ctor.  */
 
-symbolic_region::symbolic_region (unsigned id, region *parent,
+symbolic_region::symbolic_region (symbol::id_t id, region *parent,
 				  const svalue *sval_ptr)
 : region (complexity::from_pair (parent, sval_ptr), id, parent,
 	  (sval_ptr->get_type ()
diff --git a/gcc/analyzer/region.h b/gcc/analyzer/region.h
index 2cbb9234728..47242385fd1 100644
--- a/gcc/analyzer/region.h
+++ b/gcc/analyzer/region.h
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ANALYZER_REGION_H
 #define GCC_ANALYZER_REGION_H
 
-#include "analyzer/complexity.h"
+#include "analyzer/symbol.h"
 
 namespace ana {
 
@@ -118,14 +118,11 @@ enum region_kind
    within the frames and the "globals" region.  Regions for structs
    can have subregions for fields.  */
 
-class region
+class region : public symbol
 {
 public:
   virtual ~region ();
 
-  unsigned get_id () const { return m_id; }
-  static int cmp_ids (const region *reg1, const region *reg2);
-
   virtual enum region_kind get_kind () const = 0;
   virtual const frame_region *
   dyn_cast_frame_region () const { return NULL; }
@@ -231,21 +228,17 @@ public:
      bloating the store object with redundant binding clusters).  */
   virtual bool tracked_p () const { return true; }
 
-  const complexity &get_complexity () const { return m_complexity; }
-
   bool is_named_decl_p (const char *decl_name) const;
 
   bool empty_p () const;
 
  protected:
-  region (complexity c, unsigned id, const region *parent, tree type);
+  region (complexity c, symbol::id_t id, const region *parent, tree type);
 
  private:
   region_offset calc_offset (region_model_manager *mgr) const;
   const svalue *calc_initial_value_at_main (region_model_manager *mgr) const;
 
-  complexity m_complexity;
-  unsigned m_id; // purely for deterministic sorting at this stage, for dumps
   const region *m_parent;
   tree m_type;
 
@@ -274,7 +267,7 @@ namespace ana {
 class space_region : public region
 {
 protected:
-  space_region (unsigned id, const region *parent)
+  space_region (symbol::id_t id, const region *parent)
   : region (complexity (parent), id, parent, NULL_TREE)
   {}
 };
@@ -329,7 +322,7 @@ public:
     function *m_fun;
   };
 
-  frame_region (unsigned id, const region *parent,
+  frame_region (symbol::id_t id, const region *parent,
 		const frame_region *calling_frame,
 		function *fun, int index)
   : space_region (id, parent), m_calling_frame (calling_frame),
@@ -398,7 +391,7 @@ namespace ana {
 class globals_region : public space_region
 {
  public:
-  globals_region (unsigned id, const region *parent)
+  globals_region (symbol::id_t id, const region *parent)
   : space_region (id, parent)
   {}
 
@@ -425,7 +418,7 @@ namespace ana {
 class code_region : public space_region
 {
 public:
-  code_region (unsigned id, const region *parent)
+  code_region (symbol::id_t id, const region *parent)
   : space_region (id, parent)
   {}
 
@@ -452,7 +445,7 @@ namespace ana {
 class function_region : public region
 {
 public:
-  function_region (unsigned id, const code_region *parent, tree fndecl)
+  function_region (symbol::id_t id, const code_region *parent, tree fndecl)
   : region (complexity (parent), id, parent, TREE_TYPE (fndecl)),
     m_fndecl (fndecl)
   {
@@ -489,7 +482,7 @@ namespace ana {
 class label_region : public region
 {
 public:
-  label_region (unsigned id, const function_region *parent, tree label)
+  label_region (symbol::id_t id, const function_region *parent, tree label)
   : region (complexity (parent), id, parent, NULL_TREE), m_label (label)
   {
     gcc_assert (TREE_CODE (label) == LABEL_DECL);
@@ -523,7 +516,7 @@ namespace ana {
 class stack_region : public space_region
 {
 public:
-  stack_region (unsigned id, region *parent)
+  stack_region (symbol::id_t id, region *parent)
   : space_region (id, parent)
   {}
 
@@ -550,7 +543,7 @@ namespace ana {
 class heap_region : public space_region
 {
 public:
-  heap_region (unsigned id, region *parent)
+  heap_region (symbol::id_t id, region *parent)
   : space_region (id, parent)
   {}
 
@@ -576,7 +569,7 @@ namespace ana {
 class thread_local_region : public space_region
 {
 public:
-  thread_local_region (unsigned id, region *parent)
+  thread_local_region (symbol::id_t id, region *parent)
   : space_region (id, parent)
   {}
 
@@ -603,7 +596,7 @@ namespace ana {
 class root_region : public region
 {
 public:
-  root_region (unsigned id);
+  root_region (symbol::id_t id);
 
   enum region_kind get_kind () const final override { return RK_ROOT; }
   void dump_to_pp (pretty_printer *pp, bool simple) const final override;
@@ -661,7 +654,7 @@ public:
     const svalue *m_sval_ptr;
   };
 
-  symbolic_region (unsigned id, region *parent, const svalue *sval_ptr);
+  symbolic_region (symbol::id_t id, region *parent, const svalue *sval_ptr);
 
   const symbolic_region *
   dyn_cast_symbolic_region () const final override { return this; }
@@ -701,7 +694,7 @@ namespace ana {
 class decl_region : public region
 {
 public:
-  decl_region (unsigned id, const region *parent, tree decl)
+  decl_region (symbol::id_t id, const region *parent, tree decl)
   : region (complexity (parent), id, parent, TREE_TYPE (decl)), m_decl (decl),
     m_tracked (calc_tracked_p (decl)),
     m_ctor_svalue (NULL)
@@ -789,7 +782,7 @@ public:
     tree m_field;
   };
 
-  field_region (unsigned id, const region *parent, tree field)
+  field_region (symbol::id_t id, const region *parent, tree field)
   : region (complexity (parent), id, parent, TREE_TYPE (field)),
     m_field (field)
   {}
@@ -871,7 +864,7 @@ public:
     const svalue *m_index;
   };
 
-  element_region (unsigned id, const region *parent, tree element_type,
+  element_region (symbol::id_t id, const region *parent, tree element_type,
 		  const svalue *index)
   : region (complexity::from_pair (parent, index), id, parent, element_type),
     m_index (index)
@@ -958,7 +951,7 @@ public:
     const svalue *m_byte_offset;
   };
 
-  offset_region (unsigned id, const region *parent, tree type,
+  offset_region (symbol::id_t id, const region *parent, tree type,
 		 const svalue *byte_offset)
   : region (complexity::from_pair (parent, byte_offset), id, parent, type),
     m_byte_offset (byte_offset)
@@ -1050,7 +1043,7 @@ public:
     const svalue *m_end_offset;
   };
 
-  sized_region (unsigned id, const region *parent, tree type,
+  sized_region (symbol::id_t id, const region *parent, tree type,
 		const svalue *byte_size_sval)
   : region (complexity::from_pair (parent, byte_size_sval),
 	    id, parent, type),
@@ -1139,7 +1132,7 @@ public:
     tree m_type;
   };
 
-  cast_region (unsigned id, const region *original_region, tree type)
+  cast_region (symbol::id_t id, const region *original_region, tree type)
   : region (complexity (original_region), id,
 	    original_region->get_parent_region (), type),
     m_original_region (original_region)
@@ -1183,7 +1176,7 @@ namespace ana {
 class heap_allocated_region : public region
 {
 public:
-  heap_allocated_region (unsigned id, const region *parent)
+  heap_allocated_region (symbol::id_t id, const region *parent)
   : region (complexity (parent), id, parent, NULL_TREE)
   {}
 
@@ -1198,7 +1191,7 @@ public:
 class alloca_region : public region
 {
 public:
-  alloca_region (unsigned id, const frame_region *parent)
+  alloca_region (symbol::id_t id, const frame_region *parent)
   : region (complexity (parent), id, parent, NULL_TREE)
   {}
 
@@ -1212,7 +1205,7 @@ public:
 class string_region : public region
 {
 public:
-  string_region (unsigned id, const region *parent, tree string_cst)
+  string_region (symbol::id_t id, const region *parent, tree string_cst)
   : region (complexity (parent), id, parent, TREE_TYPE (string_cst)),
     m_string_cst (string_cst)
   {}
@@ -1290,7 +1283,7 @@ public:
     bit_range m_bits;
   };
 
-  bit_range_region (unsigned id, const region *parent, tree type,
+  bit_range_region (symbol::id_t id, const region *parent, tree type,
 		    const bit_range &bits)
   : region (complexity (parent), id, parent, type),
     m_bits (bits)
@@ -1377,7 +1370,7 @@ public:
     unsigned m_idx;
   };
 
-  var_arg_region (unsigned id, const frame_region *parent,
+  var_arg_region (symbol::id_t id, const frame_region *parent,
 		  unsigned idx)
   : region (complexity (parent), id, parent, NULL_TREE),
     m_idx (idx)
@@ -1420,7 +1413,7 @@ namespace ana {
 class errno_region : public region
 {
 public:
-  errno_region (unsigned id, const thread_local_region *parent)
+  errno_region (symbol::id_t id, const thread_local_region *parent)
   : region (complexity (parent), id, parent, integer_type_node)
   {}
 
@@ -1446,7 +1439,7 @@ namespace ana {
 class unknown_region : public region
 {
 public:
-  unknown_region (unsigned id, const region *parent, tree type)
+  unknown_region (symbol::id_t id, const region *parent, tree type)
   : region (complexity (parent), id, parent, type)
   {}
 
diff --git a/gcc/analyzer/svalue.cc b/gcc/analyzer/svalue.cc
index 1444274ad7a..4395018dbc3 100644
--- a/gcc/analyzer/svalue.cc
+++ b/gcc/analyzer/svalue.cc
@@ -1254,10 +1254,12 @@ binop_svalue::implicitly_live_p (const svalue_set *live_svalues,
 
 /* sub_svalue'c ctor.  */
 
-sub_svalue::sub_svalue (tree type, const svalue *parent_svalue,
+sub_svalue::sub_svalue (symbol::id_t id,
+			tree type, const svalue *parent_svalue,
 			const region *subregion)
 : svalue (complexity::from_pair (parent_svalue->get_complexity (),
 				 subregion->get_complexity ()),
+	  id,
 	  type),
   m_parent_svalue (parent_svalue), m_subregion (subregion)
 {
@@ -1311,10 +1313,11 @@ sub_svalue::implicitly_live_p (const svalue_set *live_svalues,
 
 /* repeated_svalue'c ctor.  */
 
-repeated_svalue::repeated_svalue (tree type,
+repeated_svalue::repeated_svalue (symbol::id_t id,
+				  tree type,
 				  const svalue *outer_size,
 				  const svalue *inner_svalue)
-: svalue (complexity::from_pair (outer_size, inner_svalue), type),
+: svalue (complexity::from_pair (outer_size, inner_svalue), id, type),
   m_outer_size (outer_size),
   m_inner_svalue (inner_svalue)
 {
@@ -1438,10 +1441,11 @@ repeated_svalue::maybe_fold_bits_within (tree type,
 
 /* bits_within_svalue'c ctor.  */
 
-bits_within_svalue::bits_within_svalue (tree type,
+bits_within_svalue::bits_within_svalue (symbol::id_t id,
+					tree type,
 					const bit_range &bits,
 					const svalue *inner_svalue)
-: svalue (complexity (inner_svalue), type),
+: svalue (complexity (inner_svalue), id, type),
   m_bits (bits),
   m_inner_svalue (inner_svalue)
 {
@@ -1736,8 +1740,10 @@ unmergeable_svalue::implicitly_live_p (const svalue_set *live_svalues,
 
 /* class compound_svalue : public svalue.  */
 
-compound_svalue::compound_svalue (tree type, const binding_map &map)
-: svalue (calc_complexity (map), type), m_map (map)
+compound_svalue::compound_svalue (symbol::id_t id,
+				  tree type,
+				  const binding_map &map)
+: svalue (calc_complexity (map), id, type), m_map (map)
 {
 #if CHECKING_P
   for (iterator_t iter = begin (); iter != end (); ++iter)
diff --git a/gcc/analyzer/svalue.h b/gcc/analyzer/svalue.h
index c8c3258d6bc..fbb10187677 100644
--- a/gcc/analyzer/svalue.h
+++ b/gcc/analyzer/svalue.h
@@ -21,7 +21,7 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_ANALYZER_SVALUE_H
 #define GCC_ANALYZER_SVALUE_H
 
-#include "analyzer/complexity.h"
+#include "analyzer/symbol.h"
 #include "analyzer/store.h"
 #include "analyzer/program-point.h"
 
@@ -86,7 +86,7 @@ enum svalue_kind
 
 /* An abstract base class representing a value held by a region of memory.  */
 
-class svalue
+class svalue : public symbol
 {
 public:
   virtual ~svalue () {}
@@ -146,8 +146,6 @@ public:
 			      region_model_manager *mgr,
 			      model_merger *merger) const;
 
-  const complexity &get_complexity () const { return m_complexity; }
-
   virtual void accept (visitor *v) const  = 0;
 
   bool live_p (const svalue_set *live_svalues,
@@ -180,12 +178,11 @@ public:
   const region *maybe_get_deref_base_region () const;
 
  protected:
-  svalue (complexity c, tree type)
-  : m_complexity (c), m_type (type)
+  svalue (complexity c, symbol::id_t id, tree type)
+  : symbol (c, id), m_type (type)
   {}
 
  private:
-  complexity m_complexity;
   tree m_type;
 };
 
@@ -224,8 +221,8 @@ public:
     const region *m_reg;
   };
 
-  region_svalue (tree type, const region *reg)
-  : svalue (complexity (reg), type),
+  region_svalue (symbol::id_t id, tree type, const region *reg)
+  : svalue (complexity (reg), id, type),
     m_reg (reg)
   {
     gcc_assert (m_reg != NULL);
@@ -273,8 +270,8 @@ namespace ana {
 class constant_svalue : public svalue
 {
 public:
-  constant_svalue (tree cst_expr)
-  : svalue (complexity (1, 1), TREE_TYPE (cst_expr)), m_cst_expr (cst_expr)
+  constant_svalue (symbol::id_t id, tree cst_expr)
+  : svalue (complexity (1, 1), id, TREE_TYPE (cst_expr)), m_cst_expr (cst_expr)
   {
     gcc_assert (cst_expr);
     gcc_assert (CONSTANT_CLASS_P (cst_expr));
@@ -325,8 +322,8 @@ namespace ana {
 class unknown_svalue : public svalue
 {
 public:
-  unknown_svalue (tree type)
-  : svalue (complexity (1, 1), type)
+  unknown_svalue (symbol::id_t id, tree type)
+  : svalue (complexity (1, 1), id, type)
   {}
 
   enum svalue_kind get_kind () const final override { return SK_UNKNOWN; }
@@ -394,8 +391,8 @@ public:
     tree m_type;
   };
 
-  poisoned_svalue (enum poison_kind kind, tree type)
-  : svalue (complexity (1, 1), type), m_kind (kind) {}
+  poisoned_svalue (enum poison_kind kind, symbol::id_t id, tree type)
+  : svalue (complexity (1, 1), id, type), m_kind (kind) {}
 
   enum svalue_kind get_kind () const final override { return SK_POISONED; }
   const poisoned_svalue *
@@ -502,8 +499,9 @@ public:
   };
 
   setjmp_svalue (const setjmp_record &setjmp_record,
-		  tree type)
-  : svalue (complexity (1, 1), type), m_setjmp_record (setjmp_record)
+		 symbol::id_t id,
+		 tree type)
+  : svalue (complexity (1, 1), id, type), m_setjmp_record (setjmp_record)
   {}
 
   enum svalue_kind get_kind () const final override { return SK_SETJMP; }
@@ -550,8 +548,8 @@ namespace ana {
 class initial_svalue : public svalue
 {
 public:
-  initial_svalue (tree type, const region *reg)
-  : svalue (complexity (reg), type), m_reg (reg)
+  initial_svalue (symbol::id_t id, tree type, const region *reg)
+  : svalue (complexity (reg), id, type), m_reg (reg)
   {
     gcc_assert (m_reg != NULL);
   }
@@ -624,8 +622,9 @@ public:
     const svalue *m_arg;
   };
 
-  unaryop_svalue (tree type, enum tree_code op, const svalue *arg)
-  : svalue (complexity (arg), type), m_op (op), m_arg (arg)
+  unaryop_svalue (symbol::id_t id, tree type, enum tree_code op,
+		  const svalue *arg)
+  : svalue (complexity (arg), id, type), m_op (op), m_arg (arg)
   {
     gcc_assert (arg->can_have_associated_state_p ());
   }
@@ -713,11 +712,12 @@ public:
     const svalue *m_arg1;
   };
 
-  binop_svalue (tree type, enum tree_code op,
-		 const svalue *arg0, const svalue *arg1)
+  binop_svalue (symbol::id_t id, tree type, enum tree_code op,
+		const svalue *arg0, const svalue *arg1)
   : svalue (complexity::from_pair (arg0->get_complexity (),
 				    arg1->get_complexity ()),
-	     type),
+	    id,
+	    type),
     m_op (op), m_arg0 (arg0), m_arg1 (arg1)
   {
     gcc_assert (arg0->can_have_associated_state_p ());
@@ -802,8 +802,8 @@ public:
     const svalue *m_parent_svalue;
     const region *m_subregion;
   };
-  sub_svalue (tree type, const svalue *parent_svalue,
-	       const region *subregion);
+  sub_svalue (symbol::id_t id, tree type, const svalue *parent_svalue,
+	      const region *subregion);
 
   enum svalue_kind get_kind () const final override { return SK_SUB; }
   const sub_svalue *dyn_cast_sub_svalue () const final override
@@ -883,7 +883,8 @@ public:
     const svalue *m_outer_size;
     const svalue *m_inner_svalue;
   };
-  repeated_svalue (tree type,
+  repeated_svalue (symbol::id_t id,
+		   tree type,
 		   const svalue *outer_size,
 		   const svalue *inner_svalue);
 
@@ -970,7 +971,8 @@ public:
     bit_range m_bits;
     const svalue *m_inner_svalue;
   };
-  bits_within_svalue (tree type,
+  bits_within_svalue (symbol::id_t id,
+		      tree type,
 		      const bit_range &bits,
 		      const svalue *inner_svalue);
 
@@ -1031,8 +1033,8 @@ namespace ana {
 class unmergeable_svalue : public svalue
 {
 public:
-  unmergeable_svalue (const svalue *arg)
-  : svalue (complexity (arg), arg->get_type ()), m_arg (arg)
+  unmergeable_svalue (symbol::id_t id, const svalue *arg)
+  : svalue (complexity (arg), id, arg->get_type ()), m_arg (arg)
   {
   }
 
@@ -1071,8 +1073,8 @@ namespace ana {
 class placeholder_svalue : public svalue
 {
 public:
-  placeholder_svalue (tree type, const char *name)
-  : svalue (complexity (1, 1), type), m_name (name)
+  placeholder_svalue (symbol::id_t id, tree type, const char *name)
+  : svalue (complexity (1, 1), id, type), m_name (name)
   {
   }
 
@@ -1155,10 +1157,11 @@ public:
      DIR_UNKNOWN
     };
 
-  widening_svalue (tree type, const function_point &point,
+  widening_svalue (symbol::id_t id, tree type, const function_point &point,
 		   const svalue *base_sval, const svalue *iter_sval)
   : svalue (complexity::from_pair (base_sval->get_complexity (),
 				   iter_sval->get_complexity ()),
+	    id,
 	    type),
     m_point (point),
     m_base_sval (base_sval), m_iter_sval (iter_sval)
@@ -1260,7 +1263,7 @@ public:
     const binding_map *m_map_ptr;
   };
 
-  compound_svalue (tree type, const binding_map &map);
+  compound_svalue (symbol::id_t id, tree type, const binding_map &map);
 
   enum svalue_kind get_kind () const final override { return SK_COMPOUND; }
   const compound_svalue *dyn_cast_compound_svalue () const final override
@@ -1389,8 +1392,9 @@ public:
     const region *m_id_reg;
   };
 
-  conjured_svalue (tree type, const gimple *stmt, const region *id_reg)
-  : svalue (complexity (id_reg), type),
+  conjured_svalue (symbol::id_t id, tree type, const gimple *stmt,
+		   const region *id_reg)
+  : svalue (complexity (id_reg), id, type),
     m_stmt (stmt), m_id_reg (id_reg)
   {
     gcc_assert (m_stmt != NULL);
@@ -1501,12 +1505,13 @@ public:
     const svalue *m_input_arr[MAX_INPUTS];
   };
 
-  asm_output_svalue (tree type,
+  asm_output_svalue (symbol::id_t id,
+		     tree type,
 		     const char *asm_string,
 		     unsigned output_idx,
 		     unsigned num_outputs,
 		     const vec<const svalue *> &inputs)
-  : svalue (complexity::from_vec_svalue (inputs), type),
+  : svalue (complexity::from_vec_svalue (inputs), id, type),
     m_asm_string (asm_string),
     m_output_idx (output_idx),
     m_num_outputs (num_outputs),
@@ -1634,10 +1639,11 @@ public:
     const svalue *m_input_arr[MAX_INPUTS];
   };
 
-  const_fn_result_svalue (tree type,
+  const_fn_result_svalue (symbol::id_t id,
+			  tree type,
 			  tree fndecl,
 			  const vec<const svalue *> &inputs)
-  : svalue (complexity::from_vec_svalue (inputs), type),
+  : svalue (complexity::from_vec_svalue (inputs), id, type),
     m_fndecl (fndecl),
     m_num_inputs (inputs.length ())
   {
diff --git a/gcc/analyzer/symbol.cc b/gcc/analyzer/symbol.cc
new file mode 100644
index 00000000000..2d8624508fb
--- /dev/null
+++ b/gcc/analyzer/symbol.cc
@@ -0,0 +1,43 @@
+/* Base class for svalues and regions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#include "config.h"
+#define INCLUDE_MEMORY
+#include "system.h"
+#include "coretypes.h"
+#include "tree.h"
+#include "analyzer/analyzer.h"
+#include "analyzer/symbol.h"
+
+#if ENABLE_ANALYZER
+
+namespace ana {
+
+/* Compare SYM1 and SYM2 by id.  */
+
+int
+symbol::cmp_ids (const symbol *sym1, const symbol *sym2)
+{
+  return (long)sym1->get_id () - (long)sym2->get_id ();
+}
+
+} // namespace ana
+
+#endif /* #if ENABLE_ANALYZER */
diff --git a/gcc/analyzer/symbol.h b/gcc/analyzer/symbol.h
new file mode 100644
index 00000000000..dbaf760f413
--- /dev/null
+++ b/gcc/analyzer/symbol.h
@@ -0,0 +1,53 @@
+/* Base class for svalues and regions.
+   Copyright (C) 2023 Free Software Foundation, Inc.
+   Contributed by David Malcolm <dmalcolm@redhat.com>.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
+
+#ifndef GCC_ANALYZER_SYMBOL_H
+#define GCC_ANALYZER_SYMBOL_H
+
+#include "analyzer/complexity.h"
+
+namespace ana {
+
+/* Base class for svalues and regions: has a complexity and a numeric ID.  */
+
+class symbol
+{
+ public:
+  typedef unsigned id_t;
+
+  const complexity &get_complexity () const { return m_complexity; }
+
+  id_t get_id () const { return m_id; }
+  static int cmp_ids (const symbol *s1, const symbol *s2);
+
+ protected:
+  symbol (complexity c, unsigned id)
+  : m_complexity (c),
+    m_id (id)
+  {}
+
+ private:
+  complexity m_complexity;
+  id_t m_id; // for deterministic sorting at this stage, for dumps
+};
+
+} // namespace ana
+
+#endif /* GCC_ANALYZER_SYMBOL_H */
-- 
2.26.3


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-07-26 14:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-07-26 14:33 [pushed] analyzer: add symbol base class, moving region id to there [PR104940] David Malcolm

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).