[committed] analyzer: introduce byte_range and use to simplify dumps

David Malcolm dmalcolm@redhat.com
Mon Jun 28 23:21:52 GMT 2021


Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.
Pushed to trunk as 7c6b354b92b38f31cd2399fbdbc9d6f837881480.

gcc/analyzer/ChangeLog:
	* analyzer.h (byte_offset_t): New typedef.
	* store.cc (bit_range::dump_to_pp): Dump as a byte range if
	possible.
	(bit_range::as_byte_range): New.
	(byte_range::dump_to_pp): New.
	* store.h (class byte_range): New forward decl.
	(struct bit_range): Add comment.
	(bit_range::as_byte_range): New decl.
	(struct byte_range): New.

Signed-off-by: David Malcolm <dmalcolm@redhat.com>
---
 gcc/analyzer/analyzer.h |  1 +
 gcc/analyzer/store.cc   | 54 ++++++++++++++++++++++++++++++++++++-----
 gcc/analyzer/store.h    | 25 +++++++++++++++++++
 3 files changed, 74 insertions(+), 6 deletions(-)

diff --git a/gcc/analyzer/analyzer.h b/gcc/analyzer/analyzer.h
index 525eb06c3b5..f06b68c1814 100644
--- a/gcc/analyzer/analyzer.h
+++ b/gcc/analyzer/analyzer.h
@@ -142,6 +142,7 @@ public:
 
 typedef offset_int bit_offset_t;
 typedef offset_int bit_size_t;
+typedef offset_int byte_offset_t;
 typedef offset_int byte_size_t;
 
 extern bool int_size_in_bits (const_tree type, bit_size_t *out);
diff --git a/gcc/analyzer/store.cc b/gcc/analyzer/store.cc
index 320370326bd..d5f879835a0 100644
--- a/gcc/analyzer/store.cc
+++ b/gcc/analyzer/store.cc
@@ -241,12 +241,18 @@ binding_key::cmp (const binding_key *k1, const binding_key *k2)
 void
 bit_range::dump_to_pp (pretty_printer *pp) const
 {
-  pp_string (pp, "start: ");
-  pp_wide_int (pp, m_start_bit_offset, SIGNED);
-  pp_string (pp, ", size: ");
-  pp_wide_int (pp, m_size_in_bits, SIGNED);
-  pp_string (pp, ", next: ");
-  pp_wide_int (pp, get_next_bit_offset (), SIGNED);
+  byte_range bytes (0, 0);
+  if (as_byte_range (&bytes))
+    bytes.dump_to_pp (pp);
+  else
+    {
+      pp_string (pp, "start: ");
+      pp_wide_int (pp, m_start_bit_offset, SIGNED);
+      pp_string (pp, ", size: ");
+      pp_wide_int (pp, m_size_in_bits, SIGNED);
+      pp_string (pp, ", next: ");
+      pp_wide_int (pp, get_next_bit_offset (), SIGNED);
+    }
 }
 
 /* Dump this object to stderr.  */
@@ -329,6 +335,42 @@ bit_range::from_mask (unsigned HOST_WIDE_INT mask, bit_range *out)
   return true;
 }
 
+/* Attempt to convert this bit_range to a byte_range.
+   Return true if it is possible, writing the result to *OUT.
+   Otherwise return false.  */
+
+bool
+bit_range::as_byte_range (byte_range *out) const
+{
+  if (m_start_bit_offset % BITS_PER_UNIT == 0
+      && m_size_in_bits % BITS_PER_UNIT == 0)
+    {
+      out->m_start_byte_offset = m_start_bit_offset / BITS_PER_UNIT;
+      out->m_size_in_bytes = m_size_in_bits / BITS_PER_UNIT;
+      return true;
+    }
+  return false;
+}
+
+/* Dump this object to PP.  */
+
+void
+byte_range::dump_to_pp (pretty_printer *pp) const
+{
+  if (m_size_in_bytes == 1)
+    {
+      pp_string (pp, "byte ");
+      pp_wide_int (pp, m_start_byte_offset, SIGNED);
+    }
+  else
+    {
+      pp_string (pp, "bytes ");
+      pp_wide_int (pp, m_start_byte_offset, SIGNED);
+      pp_string (pp, "-");
+      pp_wide_int (pp, get_last_byte_offset (), SIGNED);
+    }
+}
+
 /* class concrete_binding : public binding_key.  */
 
 /* Implementation of binding_key::dump_to_pp vfunc for concrete_binding.  */
diff --git a/gcc/analyzer/store.h b/gcc/analyzer/store.h
index ca9ff696bca..e0c60e128fa 100644
--- a/gcc/analyzer/store.h
+++ b/gcc/analyzer/store.h
@@ -196,6 +196,7 @@ private:
   hash_set<const svalue *> m_mutable_at_unknown_call_svals;
 };
 
+class byte_range;
 class concrete_binding;
 
 /* An enum for discriminating between "direct" vs "default" levels of
@@ -267,6 +268,8 @@ private:
   enum binding_kind m_kind;
 };
 
+/* A concrete range of bits.  */
+
 struct bit_range
 {
   bit_range (bit_offset_t start_bit_offset, bit_size_t size_in_bits)
@@ -308,10 +311,32 @@ struct bit_range
 
   static bool from_mask (unsigned HOST_WIDE_INT mask, bit_range *out);
 
+  bool as_byte_range (byte_range *out) const;
+
   bit_offset_t m_start_bit_offset;
   bit_size_t m_size_in_bits;
 };
 
+/* A concrete range of bytes.  */
+
+struct byte_range
+{
+  byte_range (byte_offset_t start_byte_offset, byte_size_t size_in_bytes)
+  : m_start_byte_offset (start_byte_offset),
+    m_size_in_bytes (size_in_bytes)
+  {}
+
+  void dump_to_pp (pretty_printer *pp) const;
+
+  byte_offset_t get_last_byte_offset () const
+  {
+    return m_start_byte_offset + m_size_in_bytes - 1;
+  }
+
+  byte_offset_t m_start_byte_offset;
+  byte_size_t m_size_in_bytes;
+};
+
 /* Concrete subclass of binding_key, for describing a concrete range of
    bits within the binding_map (e.g. "bits 8-15").  */
 
-- 
2.26.3



More information about the Gcc-patches mailing list