sbitmap.h 9.93 KB
Newer Older
1
/* Simple bitmaps.
2
   Copyright (C) 1999-2020 Free Software Foundation, Inc.
3

4
This file is part of GCC.
5

6 7
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
8
Software Foundation; either version 3, or (at your option) any later
9
version.
10

11 12 13 14
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.
15 16

You should have received a copy of the GNU General Public License
17 18
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
19

20
#ifndef GCC_SBITMAP_H
21
#define GCC_SBITMAP_H
22

23 24 25 26 27 28 29 30 31 32 33 34 35 36
/* Implementation of sets using simple bitmap vectors.

   This set representation is suitable for non-sparse sets with a known
   (a priori) universe.  The set is represented as a simple array of the
   host's fastest unsigned integer.  For a given member I in the set:
     - the element for I will be at sbitmap[I / (bits per element)]
     - the position for I within element is I % (bits per element)

   This representation is very space-efficient for large non-sparse sets
   with random access patterns.

   The following operations can be performed in O(1) time:

     * set_size			: SBITMAP_SIZE
37 38 39
     * member_p			: bitmap_bit_p
     * add_member		: bitmap_set_bit
     * remove_member		: bitmap_clear_bit
40 41 42 43

   Most other operations on this set representation are O(U) where U is
   the size of the set universe:

44 45 46
     * clear			: bitmap_clear
     * choose_one		: bitmap_first_set_bit /
				  bitmap_last_set_bit
47
     * forall			: EXECUTE_IF_SET_IN_BITMAP
48
     * set_copy			: bitmap_copy
49 50 51
     * set_intersection		: bitmap_and
     * set_union		: bitmap_ior
     * 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 58
   are also implemented:

59 60 61
      * A | (B & C)		: bitmap_or_and
      * A | (B & ~C)		: bitmap_ior_and_compl
      * A & (B | C)		: bitmap_and_or
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

   Most of the set functions have two variants: One that returns non-zero
   if members were added or removed from the target set, and one that just
   performs the operation without feedback.  The former operations are a
   bit more expensive but the result can often be used to avoid iterations
   on other sets.

   Allocating a bitmap is done with sbitmap_alloc, and resizing is
   performed with sbitmap_resize.

   The storage requirements for simple bitmap sets is O(U) where U is the
   size of the set universe (colloquially the number of bits in the bitmap).

   This set representation works well for relatively small data flow problems
   (there are special routines for that, see sbitmap_vector_*).  The set
   operations can be vectorized and there is almost no computating overhead,
   so that even sparse simple bitmap sets outperform dedicated sparse set
   representations like linked-list bitmaps.  For larger problems, the size
   overhead of simple bitmap sets gets too high and other set representations
   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 89 90
{
  unsigned int n_bits;		/* Number of bits.  */
  unsigned int size;		/* Size in elements.  */
  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 97 98
/* Return the number of bits in BITMAP.  */
#define SBITMAP_SIZE(BITMAP) ((BITMAP)->n_bits)

99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
/* Verify that access at INDEX in bitmap MAP is valid.  */ 

static inline void
bitmap_check_index (const_sbitmap map, int index)
{
  gcc_checking_assert (index >= 0);
  gcc_checking_assert ((unsigned int)index < map->n_bits);
}

/* Verify that bitmaps A and B have same size.  */ 

static inline void
bitmap_check_sizes (const_sbitmap a, const_sbitmap b)
{
  gcc_checking_assert (a->n_bits == b->n_bits);
}

116
/* Test if bit number bitno in the bitmap is set.  */
117
static inline SBITMAP_ELT_TYPE
118
bitmap_bit_p (const_sbitmap map, int bitno)
119
{
120 121
  bitmap_check_index (map, bitno);

122 123 124 125
  size_t i = bitno / SBITMAP_ELT_BITS;
  unsigned int s = bitno % SBITMAP_ELT_BITS;
  return (map->elms[i] >> s) & (SBITMAP_ELT_TYPE) 1;
}
126

127
/* Set bit number BITNO in the sbitmap MAP.  */
128 129

static inline void
130
bitmap_set_bit (sbitmap map, int bitno)
131
{
132 133
  bitmap_check_index (map, bitno);

134 135 136 137
  map->elms[bitno / SBITMAP_ELT_BITS]
    |= (SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS;
}

138
/* Reset bit number BITNO in the sbitmap MAP.  */
139 140

static inline void
141
bitmap_clear_bit (sbitmap map, int bitno)
142
{
143 144
  bitmap_check_index (map, bitno);

145 146 147 148
  map->elms[bitno / SBITMAP_ELT_BITS]
    &= ~((SBITMAP_ELT_TYPE) 1 << (bitno) % SBITMAP_ELT_BITS);
}

149
/* The iterator for sbitmap.  */
150
struct sbitmap_iterator {
151
  /* The pointer to the first word of the bitmap.  */
152
  const SBITMAP_ELT_TYPE *ptr;
153 154 155 156 157 158 159

  /* The size of the bitmap.  */
  unsigned int size;

  /* The current word index.  */
  unsigned int word_num;

160
  /* The current bit index (not modulo SBITMAP_ELT_BITS).  */
161 162 163 164
  unsigned int bit_num;

  /* The words currently visited.  */
  SBITMAP_ELT_TYPE word;
165
};
166 167 168 169 170

/* Initialize the iterator I with sbitmap BMP and the initial index
   MIN.  */

static inline void
171 172
bmp_iter_set_init (sbitmap_iterator *i, const_sbitmap bmp,
		   unsigned int min, unsigned *bit_no ATTRIBUTE_UNUSED)
173 174
{
  i->word_num = min / (unsigned int) SBITMAP_ELT_BITS;
175
  i->bit_num = min;
176 177 178 179 180 181
  i->size = bmp->size;
  i->ptr = bmp->elms;

  if (i->word_num >= i->size)
    i->word = 0;
  else
182 183
    i->word = (i->ptr[i->word_num]
	       >> (i->bit_num % (unsigned int) SBITMAP_ELT_BITS));
184 185 186 187 188 189 190
}

/* Return true if we have more bits to visit, in which case *N is set
   to the index of the bit to be visited.  Otherwise, return
   false.  */

static inline bool
191
bmp_iter_set (sbitmap_iterator *i, unsigned int *n)
192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216
{
  /* Skip words that are zeros.  */
  for (; i->word == 0; i->word = i->ptr[i->word_num])
    {
      i->word_num++;

      /* If we have reached the end, break.  */
      if (i->word_num >= i->size)
	return false;

      i->bit_num = i->word_num * SBITMAP_ELT_BITS;
    }

  /* Skip bits that are zero.  */
  for (; (i->word & 1) == 0; i->word >>= 1)
    i->bit_num++;

  *n = i->bit_num;

  return true;
}

/* Advance to the next bit.  */

static inline void
217
bmp_iter_next (sbitmap_iterator *i, unsigned *bit_no ATTRIBUTE_UNUSED)
218 219 220 221 222 223 224 225 226
{
  i->word >>= 1;
  i->bit_num++;
}

/* Loop over all elements of SBITMAP, starting with MIN.  In each
   iteration, N is set to the index of the bit being visited.  ITER is
   an instance of sbitmap_iterator used to iterate the bitmap.  */

227 228 229 230 231 232 233
#ifndef EXECUTE_IF_SET_IN_BITMAP
/* See bitmap.h for the other definition of EXECUTE_IF_SET_IN_BITMAP.  */
#define EXECUTE_IF_SET_IN_BITMAP(BITMAP, MIN, BITNUM, ITER)	\
  for (bmp_iter_set_init (&(ITER), (BITMAP), (MIN), &(BITNUM));	\
       bmp_iter_set (&(ITER), &(BITNUM));			\
       bmp_iter_next (&(ITER), &(BITNUM)))
#endif
Michael Matz committed
234

235 236 237 238
inline void sbitmap_free (sbitmap map)
{
  free (map);
}
239

240 241 242 243 244 245
inline void sbitmap_vector_free (sbitmap * vec)
{
  free (vec);
}

extern void dump_bitmap (FILE *, const_sbitmap);
246 247
extern void debug_raw (const simple_bitmap_def &ref);
extern void debug_raw (const simple_bitmap_def *ptr);
248
extern void dump_bitmap_file (FILE *, const_sbitmap);
249 250
extern void debug (const simple_bitmap_def &ref);
extern void debug (const simple_bitmap_def *ptr);
251
extern void dump_bitmap_vector (FILE *, const char *, const char *, sbitmap *,
252 253 254 255
				 int);
extern sbitmap sbitmap_alloc (unsigned int);
extern sbitmap *sbitmap_vector_alloc (unsigned int, unsigned int);
extern sbitmap sbitmap_resize (sbitmap, unsigned int, int);
256 257
extern void bitmap_copy (sbitmap, const_sbitmap);
extern int bitmap_equal_p (const_sbitmap, const_sbitmap);
258
extern unsigned int bitmap_count_bits (const_sbitmap);
259 260
extern bool bitmap_empty_p (const_sbitmap);
extern void bitmap_clear (sbitmap);
261 262
extern void bitmap_clear_range (sbitmap, unsigned, unsigned);
extern void bitmap_set_range (sbitmap, unsigned, unsigned);
263 264 265 266 267
extern void bitmap_ones (sbitmap);
extern void bitmap_vector_clear (sbitmap *, unsigned int);
extern void bitmap_vector_ones (sbitmap *, unsigned int);

extern bool bitmap_ior_and_compl (sbitmap, const_sbitmap,
268
				      const_sbitmap, const_sbitmap);
269 270 271
extern void bitmap_and_compl (sbitmap, const_sbitmap, const_sbitmap);
extern void bitmap_not (sbitmap, const_sbitmap);
extern bool bitmap_or_and (sbitmap, const_sbitmap,
272
				     const_sbitmap, const_sbitmap);
273
extern bool bitmap_and_or (sbitmap, const_sbitmap,
274
				     const_sbitmap, const_sbitmap);
275 276 277 278 279
extern bool bitmap_intersect_p (const_sbitmap, const_sbitmap);
extern bool bitmap_and (sbitmap, const_sbitmap, const_sbitmap);
extern bool bitmap_ior (sbitmap, const_sbitmap, const_sbitmap);
extern bool bitmap_xor (sbitmap, const_sbitmap, const_sbitmap);
extern bool bitmap_subset_p (const_sbitmap, const_sbitmap);
280
extern bool bitmap_bit_in_range_p (const_sbitmap, unsigned int, unsigned int);
281 282 283 284 285

extern int bitmap_first_set_bit (const_sbitmap);
extern int bitmap_last_set_bit (const_sbitmap);

extern void debug_bitmap (const_sbitmap);
286
extern sbitmap sbitmap_realloc (sbitmap, unsigned int);
287 288 289 290 291 292 293 294 295 296 297

/* a class that ties the lifetime of a sbitmap to its scope.  */
class auto_sbitmap
{
public:
  explicit auto_sbitmap (unsigned int size) :
    m_bitmap (sbitmap_alloc (size)) {}
  ~auto_sbitmap () { sbitmap_free (m_bitmap); }

  /* Allow calling sbitmap functions on our bitmap.  */
  operator sbitmap () { return m_bitmap; }
298
  operator const_sbitmap () const { return m_bitmap; }
299 300 301 302 303 304 305 306 307 308 309 310 311 312

private:
  /* Prevent making a copy that refers to our sbitmap.  */
  auto_sbitmap (const auto_sbitmap &);
  auto_sbitmap &operator = (const auto_sbitmap &);
#if __cplusplus >= 201103L
  auto_sbitmap (auto_sbitmap &&);
  auto_sbitmap &operator = (auto_sbitmap &&);
#endif

  /* The bitmap we are managing.  */
  sbitmap m_bitmap;
};

313
#endif /* ! GCC_SBITMAP_H */