From 7c6b354b92b38f31cd2399fbdbc9d6f837881480 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Mon, 28 Jun 2021 19:18:06 -0400 Subject: [PATCH] analyzer: introduce byte_range and use to simplify dumps 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 --- 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 525eb06..f06b68c 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 3203703..d5f8798 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 ca9ff69..e0c60e1 100644 --- a/gcc/analyzer/store.h +++ b/gcc/analyzer/store.h @@ -196,6 +196,7 @@ private: hash_set 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.7.4