This patch adds the `bitmap_all_bits_in_range_p` function in sbitmap,
which checks if all the bits in a range are set.

Helper function `bitmap_bit_in_range_p` has also been added, in order
to be used by `bitmap_all_bits_in_range_p` and `bitmap_any_bit_in_range_p`.
When the function's `any_inverted` parameter is true, the function checks
if any of the bits in the range is unset, otherwise it checks if any of
them is set.

Function `bitmap_any_bit_in_range_p` has been updated to call
`bitmap_bit_in_range_p` with the `any_inverted` parameter set to
false, retaining its previous functionality.

Function `bitmap_all_bits_in_range_p` calls `bitmap_bit_in_range_p`
with `any_inverted` set to true and returns the negation of the
result, i.e. true if all the bits in the range are set.

gcc/ChangeLog:

        * sbitmap.cc (bitmap_any_bit_in_range_p):
        Call and return the result of `bitmap_bit_in_range_p` with the
        `any_inverted` parameter set to false.
        (bitmap_bit_in_range_p): New function.
        (bitmap_all_bits_in_range_p): New function.
        * sbitmap.h (bitmap_all_bits_in_range_p): New function.

Signed-off-by: Konstantinos Eleftheriou <konstantinos.elefther...@vrull.eu>
---

Changes in v4:
- Merged previous 1/3 and 2/3 patches.
- Rename `bitmap_bit_in_range_p` to `bimap_any_bit_in_range_p`.
- Rename `bitmap_is_range_set_p` to `bitmap_all_bits_in_range_p`.
- Rename `bitmap_bit_in_range_p_1` to `bitmap_bit_in_range_p`.
- Make `bitmap_bit_in_range_p` static.

 gcc/sbitmap.cc | 40 ++++++++++++++++++++++++++++++++--------
 gcc/sbitmap.h  |  2 ++
 2 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/gcc/sbitmap.cc b/gcc/sbitmap.cc
index 64c7517397b3..075d0d35b810 100644
--- a/gcc/sbitmap.cc
+++ b/gcc/sbitmap.cc
@@ -326,12 +326,13 @@ bitmap_set_range (sbitmap bmap, unsigned int start, 
unsigned int count)
   bmap->elms[start_word] |= mask;
 }
 
-/* Return TRUE if any bit between START and END inclusive is set within
-   the simple bitmap BMAP.  Return FALSE otherwise.  */
+/* Helper function for bitmap_any_bit_in_range_p and
+   bitmap_all_bits_in_range_p.  If ANY_INVERTED is true, the function checks
+   if any bit in the range is unset.  */
 
-bool
-bitmap_any_bit_in_range_p (const_sbitmap bmap, unsigned int start,
-                          unsigned int end)
+static bool
+bitmap_bit_in_range_p (const_sbitmap bmap, unsigned int start,
+                      unsigned int end, bool any_inverted)
 {
   gcc_checking_assert (start <= end);
   bitmap_check_index (bmap, end);
@@ -351,7 +352,8 @@ bitmap_any_bit_in_range_p (const_sbitmap bmap, unsigned int 
start,
 
       SBITMAP_ELT_TYPE low_mask = ((SBITMAP_ELT_TYPE)1 << start_bitno) - 1;
       SBITMAP_ELT_TYPE mask = high_mask - low_mask;
-      if (bmap->elms[start_word] & mask)
+      const SBITMAP_ELT_TYPE expected_partial = any_inverted ? mask : 0;
+      if ((bmap->elms[start_word] & mask) != expected_partial)
        return true;
       start_word++;
     }
@@ -361,9 +363,10 @@ bitmap_any_bit_in_range_p (const_sbitmap bmap, unsigned 
int start,
 
   /* Now test words at a time until we hit a partial word.  */
   unsigned int nwords = (end_word - start_word);
+  const SBITMAP_ELT_TYPE expected = any_inverted ? ~(SBITMAP_ELT_TYPE)0 : 0;
   while (nwords)
     {
-      if (bmap->elms[start_word])
+      if (bmap->elms[start_word] != expected)
        return true;
       start_word++;
       nwords--;
@@ -373,7 +376,28 @@ bitmap_any_bit_in_range_p (const_sbitmap bmap, unsigned 
int start,
   SBITMAP_ELT_TYPE mask = ~(SBITMAP_ELT_TYPE)0;
   if (end_bitno + 1 < SBITMAP_ELT_BITS)
     mask = ((SBITMAP_ELT_TYPE)1 << (end_bitno + 1)) - 1;
-  return (bmap->elms[start_word] & mask) != 0;
+  const SBITMAP_ELT_TYPE expected_partial = any_inverted ? mask : 0;
+  return (bmap->elms[start_word] & mask) != expected_partial;
+}
+
+/* Return TRUE if all bits between START and END inclusive are set within
+   the simple bitmap BMAP.  Return FALSE otherwise.  */
+
+bool
+bitmap_all_bits_in_range_p (const_sbitmap bmap, unsigned int start,
+                           unsigned int end)
+{
+  return !bitmap_bit_in_range_p (bmap, start, end, true);
+}
+
+/* Return TRUE if any bit between START and END inclusive is set within
+   the simple bitmap BMAP.  Return FALSE otherwise.  */
+
+bool
+bitmap_any_bit_in_range_p (const_sbitmap bmap, unsigned int start,
+                          unsigned int end)
+{
+  return bitmap_bit_in_range_p (bmap, start, end, false);
 }
 
 #if GCC_VERSION < 3400
diff --git a/gcc/sbitmap.h b/gcc/sbitmap.h
index 927d296f4606..633d84fa1510 100644
--- a/gcc/sbitmap.h
+++ b/gcc/sbitmap.h
@@ -289,6 +289,8 @@ extern bool bitmap_xor (sbitmap, const_sbitmap, 
const_sbitmap);
 extern bool bitmap_subset_p (const_sbitmap, const_sbitmap);
 extern bool bitmap_any_bit_in_range_p (const_sbitmap, unsigned int,
                                       unsigned int);
+extern bool bitmap_all_bits_in_range_p (const_sbitmap, unsigned int,
+                                       unsigned int);
 
 extern int bitmap_first_set_bit (const_sbitmap);
 extern int bitmap_last_set_bit (const_sbitmap);
-- 
2.49.0

Reply via email to