|  | /* Simple bitmaps. | 
|  | Copyright (C) 1999-2025 Free Software Foundation, Inc. | 
|  |  | 
|  | This file is part of GCC. | 
|  |  | 
|  | 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 | 
|  | Software Foundation; either version 3, or (at your option) any later | 
|  | version. | 
|  |  | 
|  | 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. | 
|  |  | 
|  | You should have received a copy of the GNU General Public License | 
|  | along with GCC; see the file COPYING3.  If not see | 
|  | <http://www.gnu.org/licenses/>.  */ | 
|  |  | 
|  | #ifndef GCC_SBITMAP_H | 
|  | #define GCC_SBITMAP_H | 
|  |  | 
|  | /* 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 | 
|  | * member_p			: bitmap_bit_p | 
|  | * add_member		: bitmap_set_bit | 
|  | * remove_member		: bitmap_clear_bit | 
|  |  | 
|  | Most other operations on this set representation are O(U) where U is | 
|  | the size of the set universe: | 
|  |  | 
|  | * clear			: bitmap_clear | 
|  | * choose_one		: bitmap_first_set_bit / | 
|  | bitmap_last_set_bit | 
|  | * forall			: EXECUTE_IF_SET_IN_BITMAP | 
|  | * set_copy			: bitmap_copy | 
|  | * set_intersection		: bitmap_and | 
|  | * set_union		: bitmap_ior | 
|  | * set_difference		: bitmap_and_compl | 
|  | * set_disjuction		: (not implemented) | 
|  | * set_compare		: bitmap_equal_p | 
|  | * any_bit_in_range_p	: bitmap_any_bit_in_range_p | 
|  |  | 
|  | Some operations on 3 sets that occur frequently in data flow problems | 
|  | are also implemented: | 
|  |  | 
|  | * A | (B & C)		: bitmap_or_and | 
|  | * A | (B & ~C)		: bitmap_ior_and_compl | 
|  | * A & (B | C)		: bitmap_and_or | 
|  |  | 
|  | 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.  */ | 
|  |  | 
|  | #define SBITMAP_ELT_BITS (HOST_BITS_PER_WIDEST_FAST_INT * 1u) | 
|  | #define SBITMAP_ELT_TYPE unsigned HOST_WIDEST_FAST_INT | 
|  |  | 
|  | struct simple_bitmap_def | 
|  | { | 
|  | unsigned int n_bits;		/* Number of bits.  */ | 
|  | unsigned int size;		/* Size in elements.  */ | 
|  | SBITMAP_ELT_TYPE elms[1];	/* The elements.  */ | 
|  | }; | 
|  |  | 
|  | /* Return the set size needed for N elements.  */ | 
|  | #define SBITMAP_SET_SIZE(N) (((N) + SBITMAP_ELT_BITS - 1) / SBITMAP_ELT_BITS) | 
|  |  | 
|  | /* Return the number of bits in BITMAP.  */ | 
|  | #define SBITMAP_SIZE(BITMAP) ((BITMAP)->n_bits) | 
|  |  | 
|  | /* Verify that access at INDEX in bitmap MAP is valid.  */ | 
|  |  | 
|  | 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.  */ | 
|  |  | 
|  | inline void | 
|  | bitmap_check_sizes (const_sbitmap a, const_sbitmap b) | 
|  | { | 
|  | gcc_checking_assert (a->n_bits == b->n_bits); | 
|  | } | 
|  |  | 
|  | /* Test if bit number bitno in the bitmap is set.  */ | 
|  | inline bool | 
|  | bitmap_bit_p (const_sbitmap map, int bitno) | 
|  | { | 
|  | bitmap_check_index (map, bitno); | 
|  |  | 
|  | size_t i = bitno / SBITMAP_ELT_BITS; | 
|  | unsigned int s = bitno % SBITMAP_ELT_BITS; | 
|  | return (map->elms[i] >> s) & (SBITMAP_ELT_TYPE) 1; | 
|  | } | 
|  |  | 
|  | /* Set bit number BITNO in the sbitmap MAP. | 
|  | Return true if the bit changed.  */ | 
|  |  | 
|  | inline bool | 
|  | bitmap_set_bit (sbitmap map, int bitno) | 
|  | { | 
|  | bitmap_check_index (map, bitno); | 
|  |  | 
|  | size_t i = bitno / SBITMAP_ELT_BITS; | 
|  | unsigned int s = bitno % SBITMAP_ELT_BITS; | 
|  | if (map->elms[i] & ((SBITMAP_ELT_TYPE) 1 << s)) | 
|  | return false; | 
|  | map->elms[i] |= (SBITMAP_ELT_TYPE) 1 << s; | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /* Reset bit number BITNO in the sbitmap MAP. | 
|  | Return true if the bit changed.  */ | 
|  |  | 
|  | inline bool | 
|  | bitmap_clear_bit (sbitmap map, int bitno) | 
|  | { | 
|  | bitmap_check_index (map, bitno); | 
|  |  | 
|  | size_t i = bitno / SBITMAP_ELT_BITS; | 
|  | unsigned int s = bitno % SBITMAP_ELT_BITS; | 
|  | if (!(map->elms[i] & ((SBITMAP_ELT_TYPE) 1 << s))) | 
|  | return false; | 
|  | map->elms[i] &= ~((SBITMAP_ELT_TYPE) 1 << s); | 
|  | return true; | 
|  | } | 
|  |  | 
|  | /* The iterator for sbitmap.  */ | 
|  | struct sbitmap_iterator { | 
|  | /* The pointer to the first word of the bitmap.  */ | 
|  | const SBITMAP_ELT_TYPE *ptr; | 
|  |  | 
|  | /* The size of the bitmap.  */ | 
|  | unsigned int size; | 
|  |  | 
|  | /* The current word index.  */ | 
|  | unsigned int word_num; | 
|  |  | 
|  | /* The current bit index (not modulo SBITMAP_ELT_BITS).  */ | 
|  | unsigned int bit_num; | 
|  |  | 
|  | /* The words currently visited.  */ | 
|  | SBITMAP_ELT_TYPE word; | 
|  | }; | 
|  |  | 
|  | /* Initialize the iterator I with sbitmap BMP and the initial index | 
|  | MIN.  */ | 
|  |  | 
|  | inline void | 
|  | bmp_iter_set_init (sbitmap_iterator *i, const_sbitmap bmp, | 
|  | unsigned int min, unsigned *bit_no ATTRIBUTE_UNUSED) | 
|  | { | 
|  | i->word_num = min / (unsigned int) SBITMAP_ELT_BITS; | 
|  | i->bit_num = min; | 
|  | i->size = bmp->size; | 
|  | i->ptr = bmp->elms; | 
|  |  | 
|  | if (i->word_num >= i->size) | 
|  | i->word = 0; | 
|  | else | 
|  | i->word = (i->ptr[i->word_num] | 
|  | >> (i->bit_num % (unsigned int) SBITMAP_ELT_BITS)); | 
|  | } | 
|  |  | 
|  | /* 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.  */ | 
|  |  | 
|  | inline bool | 
|  | bmp_iter_set (sbitmap_iterator *i, unsigned int *n) | 
|  | { | 
|  | /* 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.  */ | 
|  |  | 
|  | inline void | 
|  | bmp_iter_next (sbitmap_iterator *i, unsigned *bit_no ATTRIBUTE_UNUSED) | 
|  | { | 
|  | 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.  */ | 
|  |  | 
|  | #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 | 
|  |  | 
|  | inline void sbitmap_free (sbitmap map) | 
|  | { | 
|  | free (map); | 
|  | } | 
|  |  | 
|  | inline void sbitmap_vector_free (sbitmap * vec) | 
|  | { | 
|  | free (vec); | 
|  | } | 
|  |  | 
|  | extern void dump_bitmap (FILE *, const_sbitmap); | 
|  | extern void debug_raw (const simple_bitmap_def &ref); | 
|  | extern void debug_raw (const simple_bitmap_def *ptr); | 
|  | extern void dump_bitmap_file (FILE *, const_sbitmap); | 
|  | extern void debug (const simple_bitmap_def &ref); | 
|  | extern void debug (const simple_bitmap_def *ptr); | 
|  | extern void dump_bitmap_vector (FILE *, const char *, const char *, sbitmap *, | 
|  | int); | 
|  | extern sbitmap sbitmap_alloc (unsigned int); | 
|  | extern sbitmap *sbitmap_vector_alloc (unsigned int, unsigned int); | 
|  | extern sbitmap sbitmap_resize (sbitmap, unsigned int, int); | 
|  | extern void bitmap_copy (sbitmap, const_sbitmap); | 
|  | extern bool bitmap_equal_p (const_sbitmap, const_sbitmap); | 
|  | extern unsigned int bitmap_count_bits (const_sbitmap); | 
|  | extern bool bitmap_empty_p (const_sbitmap); | 
|  | extern void bitmap_clear (sbitmap); | 
|  | extern void bitmap_clear_range (sbitmap, unsigned, unsigned); | 
|  | extern void bitmap_set_range (sbitmap, unsigned, unsigned); | 
|  | 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, | 
|  | const_sbitmap, const_sbitmap); | 
|  | 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, | 
|  | const_sbitmap, const_sbitmap); | 
|  | extern bool bitmap_and_or (sbitmap, const_sbitmap, | 
|  | const_sbitmap, const_sbitmap); | 
|  | 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); | 
|  | 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); | 
|  |  | 
|  | extern void debug_bitmap (const_sbitmap); | 
|  | extern sbitmap sbitmap_realloc (sbitmap, unsigned int); | 
|  |  | 
|  | /* 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; } | 
|  | operator const_sbitmap () const { return m_bitmap; } | 
|  |  | 
|  | private: | 
|  | /* Prevent making a copy that refers to our sbitmap.  */ | 
|  | auto_sbitmap (const auto_sbitmap &); | 
|  | auto_sbitmap &operator = (const auto_sbitmap &); | 
|  | auto_sbitmap (auto_sbitmap &&); | 
|  | auto_sbitmap &operator = (auto_sbitmap &&); | 
|  |  | 
|  | /* The bitmap we are managing.  */ | 
|  | sbitmap m_bitmap; | 
|  | }; | 
|  |  | 
|  | #endif /* ! GCC_SBITMAP_H */ |