LCOV - code coverage report
Current view: top level - gcc - sbitmap.h (source / functions) Hit Total Coverage
Test: gcc.info Lines: 16 16 100.0 %
Date: 2023-07-19 08:18:47 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /* Simple bitmaps.
       2             :    Copyright (C) 1999-2023 Free Software Foundation, Inc.
       3             : 
       4             : This file is part of GCC.
       5             : 
       6             : GCC is free software; you can redistribute it and/or modify it under
       7             : the terms of the GNU General Public License as published by the Free
       8             : Software Foundation; either version 3, or (at your option) any later
       9             : version.
      10             : 
      11             : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      12             : WARRANTY; without even the implied warranty of MERCHANTABILITY or
      13             : FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      14             : for more details.
      15             : 
      16             : You should have received a copy of the GNU General Public License
      17             : along with GCC; see the file COPYING3.  If not see
      18             : <http://www.gnu.org/licenses/>.  */
      19             : 
      20             : #ifndef GCC_SBITMAP_H
      21             : #define GCC_SBITMAP_H
      22             : 
      23             : /* Implementation of sets using simple bitmap vectors.
      24             : 
      25             :    This set representation is suitable for non-sparse sets with a known
      26             :    (a priori) universe.  The set is represented as a simple array of the
      27             :    host's fastest unsigned integer.  For a given member I in the set:
      28             :      - the element for I will be at sbitmap[I / (bits per element)]
      29             :      - the position for I within element is I % (bits per element)
      30             : 
      31             :    This representation is very space-efficient for large non-sparse sets
      32             :    with random access patterns.
      33             : 
      34             :    The following operations can be performed in O(1) time:
      35             : 
      36             :      * set_size                 : SBITMAP_SIZE
      37             :      * member_p                 : bitmap_bit_p
      38             :      * add_member               : bitmap_set_bit
      39             :      * remove_member            : bitmap_clear_bit
      40             : 
      41             :    Most other operations on this set representation are O(U) where U is
      42             :    the size of the set universe:
      43             : 
      44             :      * clear                    : bitmap_clear
      45             :      * choose_one               : bitmap_first_set_bit /
      46             :                                   bitmap_last_set_bit
      47             :      * forall                   : EXECUTE_IF_SET_IN_BITMAP
      48             :      * set_copy                 : bitmap_copy
      49             :      * set_intersection         : bitmap_and
      50             :      * set_union                : bitmap_ior
      51             :      * set_difference           : bitmap_and_compl
      52             :      * set_disjuction           : (not implemented)
      53             :      * set_compare              : bitmap_equal_p
      54             :      * bit_in_range_p           : bitmap_bit_in_range_p
      55             : 
      56             :    Some operations on 3 sets that occur frequently in data flow problems
      57             :    are also implemented:
      58             : 
      59             :       * A | (B & C)         : bitmap_or_and
      60             :       * A | (B & ~C)                : bitmap_ior_and_compl
      61             :       * A & (B | C)         : bitmap_and_or
      62             : 
      63             :    Most of the set functions have two variants: One that returns non-zero
      64             :    if members were added or removed from the target set, and one that just
      65             :    performs the operation without feedback.  The former operations are a
      66             :    bit more expensive but the result can often be used to avoid iterations
      67             :    on other sets.
      68             : 
      69             :    Allocating a bitmap is done with sbitmap_alloc, and resizing is
      70             :    performed with sbitmap_resize.
      71             : 
      72             :    The storage requirements for simple bitmap sets is O(U) where U is the
      73             :    size of the set universe (colloquially the number of bits in the bitmap).
      74             : 
      75             :    This set representation works well for relatively small data flow problems
      76             :    (there are special routines for that, see sbitmap_vector_*).  The set
      77             :    operations can be vectorized and there is almost no computating overhead,
      78             :    so that even sparse simple bitmap sets outperform dedicated sparse set
      79             :    representations like linked-list bitmaps.  For larger problems, the size
      80             :    overhead of simple bitmap sets gets too high and other set representations
      81             :    have to be used.  */
      82             : 
      83             : #define SBITMAP_ELT_BITS (HOST_BITS_PER_WIDEST_FAST_INT * 1u)
      84             : #define SBITMAP_ELT_TYPE unsigned HOST_WIDEST_FAST_INT
      85             : 
      86             : struct simple_bitmap_def
      87             : {
      88             :   unsigned int n_bits;          /* Number of bits.  */
      89             :   unsigned int size;            /* Size in elements.  */
      90             :   SBITMAP_ELT_TYPE elms[1];     /* The elements.  */
      91             : };
      92             : 
      93             : /* Return the set size needed for N elements.  */
      94             : #define SBITMAP_SET_SIZE(N) (((N) + SBITMAP_ELT_BITS - 1) / SBITMAP_ELT_BITS)
      95             : 
      96             : /* Return the number of bits in BITMAP.  */
      97             : #define SBITMAP_SIZE(BITMAP) ((BITMAP)->n_bits)
      98             : 
      99             : /* Verify that access at INDEX in bitmap MAP is valid.  */ 
     100             : 
     101             : inline void
     102          48 : bitmap_check_index (const_sbitmap map, int index)
     103             : {
     104          48 :   gcc_checking_assert (index >= 0);
     105          48 :   gcc_checking_assert ((unsigned int)index < map->n_bits);
     106          48 : }
     107             : 
     108             : /* Verify that bitmaps A and B have same size.  */ 
     109             : 
     110             : inline void
     111             : bitmap_check_sizes (const_sbitmap a, const_sbitmap b)
     112             : {
     113             :   gcc_checking_assert (a->n_bits == b->n_bits);
     114             : }
     115             : 
     116             : /* Test if bit number bitno in the bitmap is set.  */
     117             : inline bool
     118          32 : bitmap_bit_p (const_sbitmap map, int bitno)
     119             : {
     120          32 :   bitmap_check_index (map, bitno);
     121             : 
     122          32 :   size_t i = bitno / SBITMAP_ELT_BITS;
     123          32 :   unsigned int s = bitno % SBITMAP_ELT_BITS;
     124          32 :   return (map->elms[i] >> s) & (SBITMAP_ELT_TYPE) 1;
     125             : }
     126             : 
     127             : /* Set bit number BITNO in the sbitmap MAP.
     128             :    Return true if the bit changed.  */
     129             : 
     130             : inline bool
     131          16 : bitmap_set_bit (sbitmap map, int bitno)
     132             : {
     133          16 :   bitmap_check_index (map, bitno);
     134             : 
     135          16 :   size_t i = bitno / SBITMAP_ELT_BITS;
     136          16 :   unsigned int s = bitno % SBITMAP_ELT_BITS;
     137          16 :   if (map->elms[i] & ((SBITMAP_ELT_TYPE) 1 << s))
     138             :     return false;
     139          16 :   map->elms[i] |= (SBITMAP_ELT_TYPE) 1 << s;
     140          16 :   return true;
     141             : }
     142             : 
     143             : /* Reset bit number BITNO in the sbitmap MAP.
     144             :    Return true if the bit changed.  */
     145             : 
     146             : inline bool
     147             : bitmap_clear_bit (sbitmap map, int bitno)
     148             : {
     149             :   bitmap_check_index (map, bitno);
     150             : 
     151             :   size_t i = bitno / SBITMAP_ELT_BITS;
     152             :   unsigned int s = bitno % SBITMAP_ELT_BITS;
     153             :   if (!(map->elms[i] & ((SBITMAP_ELT_TYPE) 1 << s)))
     154             :     return false;
     155             :   map->elms[i] &= ~((SBITMAP_ELT_TYPE) 1 << s);
     156             :   return true;
     157             : }
     158             : 
     159             : /* The iterator for sbitmap.  */
     160             : struct sbitmap_iterator {
     161             :   /* The pointer to the first word of the bitmap.  */
     162             :   const SBITMAP_ELT_TYPE *ptr;
     163             : 
     164             :   /* The size of the bitmap.  */
     165             :   unsigned int size;
     166             : 
     167             :   /* The current word index.  */
     168             :   unsigned int word_num;
     169             : 
     170             :   /* The current bit index (not modulo SBITMAP_ELT_BITS).  */
     171             :   unsigned int bit_num;
     172             : 
     173             :   /* The words currently visited.  */
     174             :   SBITMAP_ELT_TYPE word;
     175             : };
     176             : 
     177             : /* Initialize the iterator I with sbitmap BMP and the initial index
     178             :    MIN.  */
     179             : 
     180             : inline void
     181             : bmp_iter_set_init (sbitmap_iterator *i, const_sbitmap bmp,
     182             :                    unsigned int min, unsigned *bit_no ATTRIBUTE_UNUSED)
     183             : {
     184             :   i->word_num = min / (unsigned int) SBITMAP_ELT_BITS;
     185             :   i->bit_num = min;
     186             :   i->size = bmp->size;
     187             :   i->ptr = bmp->elms;
     188             : 
     189             :   if (i->word_num >= i->size)
     190             :     i->word = 0;
     191             :   else
     192             :     i->word = (i->ptr[i->word_num]
     193             :                >> (i->bit_num % (unsigned int) SBITMAP_ELT_BITS));
     194             : }
     195             : 
     196             : /* Return true if we have more bits to visit, in which case *N is set
     197             :    to the index of the bit to be visited.  Otherwise, return
     198             :    false.  */
     199             : 
     200             : inline bool
     201             : bmp_iter_set (sbitmap_iterator *i, unsigned int *n)
     202             : {
     203             :   /* Skip words that are zeros.  */
     204             :   for (; i->word == 0; i->word = i->ptr[i->word_num])
     205             :     {
     206             :       i->word_num++;
     207             : 
     208             :       /* If we have reached the end, break.  */
     209             :       if (i->word_num >= i->size)
     210             :         return false;
     211             : 
     212             :       i->bit_num = i->word_num * SBITMAP_ELT_BITS;
     213             :     }
     214             : 
     215             :   /* Skip bits that are zero.  */
     216             :   for (; (i->word & 1) == 0; i->word >>= 1)
     217             :     i->bit_num++;
     218             : 
     219             :   *n = i->bit_num;
     220             : 
     221             :   return true;
     222             : }
     223             : 
     224             : /* Advance to the next bit.  */
     225             : 
     226             : inline void
     227             : bmp_iter_next (sbitmap_iterator *i, unsigned *bit_no ATTRIBUTE_UNUSED)
     228             : {
     229             :   i->word >>= 1;
     230             :   i->bit_num++;
     231             : }
     232             : 
     233             : /* Loop over all elements of SBITMAP, starting with MIN.  In each
     234             :    iteration, N is set to the index of the bit being visited.  ITER is
     235             :    an instance of sbitmap_iterator used to iterate the bitmap.  */
     236             : 
     237             : #ifndef EXECUTE_IF_SET_IN_BITMAP
     238             : /* See bitmap.h for the other definition of EXECUTE_IF_SET_IN_BITMAP.  */
     239             : #define EXECUTE_IF_SET_IN_BITMAP(BITMAP, MIN, BITNUM, ITER)     \
     240             :   for (bmp_iter_set_init (&(ITER), (BITMAP), (MIN), &(BITNUM)); \
     241             :        bmp_iter_set (&(ITER), &(BITNUM));                       \
     242             :        bmp_iter_next (&(ITER), &(BITNUM)))
     243             : #endif
     244             : 
     245             : inline void sbitmap_free (sbitmap map)
     246             : {
     247             :   free (map);
     248             : }
     249             : 
     250             : inline void sbitmap_vector_free (sbitmap * vec)
     251             : {
     252             :   free (vec);
     253             : }
     254             : 
     255             : extern void dump_bitmap (FILE *, const_sbitmap);
     256             : extern void debug_raw (const simple_bitmap_def &ref);
     257             : extern void debug_raw (const simple_bitmap_def *ptr);
     258             : extern void dump_bitmap_file (FILE *, const_sbitmap);
     259             : extern void debug (const simple_bitmap_def &ref);
     260             : extern void debug (const simple_bitmap_def *ptr);
     261             : extern void dump_bitmap_vector (FILE *, const char *, const char *, sbitmap *,
     262             :                                  int);
     263             : extern sbitmap sbitmap_alloc (unsigned int);
     264             : extern sbitmap *sbitmap_vector_alloc (unsigned int, unsigned int);
     265             : extern sbitmap sbitmap_resize (sbitmap, unsigned int, int);
     266             : extern void bitmap_copy (sbitmap, const_sbitmap);
     267             : extern bool bitmap_equal_p (const_sbitmap, const_sbitmap);
     268             : extern unsigned int bitmap_count_bits (const_sbitmap);
     269             : extern bool bitmap_empty_p (const_sbitmap);
     270             : extern void bitmap_clear (sbitmap);
     271             : extern void bitmap_clear_range (sbitmap, unsigned, unsigned);
     272             : extern void bitmap_set_range (sbitmap, unsigned, unsigned);
     273             : extern void bitmap_ones (sbitmap);
     274             : extern void bitmap_vector_clear (sbitmap *, unsigned int);
     275             : extern void bitmap_vector_ones (sbitmap *, unsigned int);
     276             : 
     277             : extern bool bitmap_ior_and_compl (sbitmap, const_sbitmap,
     278             :                                       const_sbitmap, const_sbitmap);
     279             : extern void bitmap_and_compl (sbitmap, const_sbitmap, const_sbitmap);
     280             : extern void bitmap_not (sbitmap, const_sbitmap);
     281             : extern bool bitmap_or_and (sbitmap, const_sbitmap,
     282             :                                      const_sbitmap, const_sbitmap);
     283             : extern bool bitmap_and_or (sbitmap, const_sbitmap,
     284             :                                      const_sbitmap, const_sbitmap);
     285             : extern bool bitmap_intersect_p (const_sbitmap, const_sbitmap);
     286             : extern bool bitmap_and (sbitmap, const_sbitmap, const_sbitmap);
     287             : extern bool bitmap_ior (sbitmap, const_sbitmap, const_sbitmap);
     288             : extern bool bitmap_xor (sbitmap, const_sbitmap, const_sbitmap);
     289             : extern bool bitmap_subset_p (const_sbitmap, const_sbitmap);
     290             : extern bool bitmap_bit_in_range_p (const_sbitmap, unsigned int, unsigned int);
     291             : 
     292             : extern int bitmap_first_set_bit (const_sbitmap);
     293             : extern int bitmap_last_set_bit (const_sbitmap);
     294             : 
     295             : extern void debug_bitmap (const_sbitmap);
     296             : extern sbitmap sbitmap_realloc (sbitmap, unsigned int);
     297             : 
     298             : /* a class that ties the lifetime of a sbitmap to its scope.  */
     299             : class auto_sbitmap
     300             : {
     301             : public:
     302             :   explicit auto_sbitmap (unsigned int size) :
     303             :     m_bitmap (sbitmap_alloc (size)) {}
     304             :   ~auto_sbitmap () { sbitmap_free (m_bitmap); }
     305             : 
     306             :   /* Allow calling sbitmap functions on our bitmap.  */
     307             :   operator sbitmap () { return m_bitmap; }
     308             :   operator const_sbitmap () const { return m_bitmap; }
     309             : 
     310             : private:
     311             :   /* Prevent making a copy that refers to our sbitmap.  */
     312             :   auto_sbitmap (const auto_sbitmap &);
     313             :   auto_sbitmap &operator = (const auto_sbitmap &);
     314             :   auto_sbitmap (auto_sbitmap &&);
     315             :   auto_sbitmap &operator = (auto_sbitmap &&);
     316             : 
     317             :   /* The bitmap we are managing.  */
     318             :   sbitmap m_bitmap;
     319             : };
     320             : 
     321             : #endif /* ! GCC_SBITMAP_H */

Generated by: LCOV version 1.16