152284Sobrien/* Simple bitmaps. 2169689Skan Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc. 352284Sobrien 490075SobrienThis file is part of GCC. 552284Sobrien 690075SobrienGCC is free software; you can redistribute it and/or modify it under 790075Sobrienthe terms of the GNU General Public License as published by the Free 890075SobrienSoftware Foundation; either version 2, or (at your option) any later 990075Sobrienversion. 1052284Sobrien 1190075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1290075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or 1390075SobrienFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1490075Sobrienfor more details. 1552284Sobrien 1652284SobrienYou should have received a copy of the GNU General Public License 1790075Sobrienalong with GCC; see the file COPYING. If not, write to the Free 18169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 19169689Skan02110-1301, USA. */ 2052284Sobrien 2190075Sobrien#ifndef GCC_SBITMAP_H 22132718Skan#define GCC_SBITMAP_H 2390075Sobrien 2452284Sobrien/* It's not clear yet whether using bitmap.[ch] will be a win. 2552284Sobrien It should be straightforward to convert so for now we keep things simple 2652284Sobrien while more important issues are dealt with. */ 2752284Sobrien 28169689Skan#define SBITMAP_ELT_BITS ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT) 29169689Skan#define SBITMAP_ELT_TYPE unsigned HOST_WIDEST_FAST_INT 3052284Sobrien 3190075Sobrientypedef struct simple_bitmap_def 3290075Sobrien{ 3390075Sobrien unsigned int n_bits; /* Number of bits. */ 3490075Sobrien unsigned int size; /* Size in elements. */ 3590075Sobrien unsigned int bytes; /* Size in bytes. */ 3690075Sobrien SBITMAP_ELT_TYPE elms[1]; /* The elements. */ 3752284Sobrien} *sbitmap; 3852284Sobrien 3952284Sobrientypedef SBITMAP_ELT_TYPE *sbitmap_ptr; 4052284Sobrien 4152284Sobrien/* Return the set size needed for N elements. */ 4290075Sobrien#define SBITMAP_SET_SIZE(N) (((N) + SBITMAP_ELT_BITS - 1) / SBITMAP_ELT_BITS) 4352284Sobrien 4490075Sobrien/* Set bit number bitno in the bitmap. */ 4590075Sobrien#define SET_BIT(BITMAP, BITNO) \ 4690075Sobrien ((BITMAP)->elms [(BITNO) / SBITMAP_ELT_BITS] \ 4790075Sobrien |= (SBITMAP_ELT_TYPE) 1 << (BITNO) % SBITMAP_ELT_BITS) 4852284Sobrien 4990075Sobrien/* Test if bit number bitno in the bitmap is set. */ 5090075Sobrien#define TEST_BIT(BITMAP, BITNO) \ 5190075Sobrien((BITMAP)->elms [(BITNO) / SBITMAP_ELT_BITS] >> (BITNO) % SBITMAP_ELT_BITS & 1) 5252284Sobrien 5390075Sobrien/* Reset bit number bitno in the bitmap. */ 5490075Sobrien#define RESET_BIT(BITMAP, BITNO) \ 5590075Sobrien ((BITMAP)->elms [(BITNO) / SBITMAP_ELT_BITS] \ 5690075Sobrien &= ~((SBITMAP_ELT_TYPE) 1 << (BITNO) % SBITMAP_ELT_BITS)) 5752284Sobrien 58169689Skan/* The iterator for sbitmap. */ 59169689Skantypedef struct { 60169689Skan /* The pointer to the first word of the bitmap. */ 61169689Skan SBITMAP_ELT_TYPE *ptr; 6252284Sobrien 63169689Skan /* The size of the bitmap. */ 64169689Skan unsigned int size; 65169689Skan 66169689Skan /* The current word index. */ 67169689Skan unsigned int word_num; 68169689Skan 69169689Skan /* The current bit index (not modulo SBITMAP_ELT_BITS). */ 70169689Skan unsigned int bit_num; 71169689Skan 72169689Skan /* The words currently visited. */ 73169689Skan SBITMAP_ELT_TYPE word; 74169689Skan} sbitmap_iterator; 75169689Skan 76169689Skan/* Initialize the iterator I with sbitmap BMP and the initial index 77169689Skan MIN. */ 78169689Skan 79169689Skanstatic inline void 80169689Skansbitmap_iter_init (sbitmap_iterator *i, sbitmap bmp, unsigned int min) 81169689Skan{ 82169689Skan i->word_num = min / (unsigned int) SBITMAP_ELT_BITS; 83169689Skan i->bit_num = min; 84169689Skan i->size = bmp->size; 85169689Skan i->ptr = bmp->elms; 86169689Skan 87169689Skan if (i->word_num >= i->size) 88169689Skan i->word = 0; 89169689Skan else 90169689Skan i->word = (i->ptr[i->word_num] 91169689Skan >> (i->bit_num % (unsigned int) SBITMAP_ELT_BITS)); 92169689Skan} 93169689Skan 94169689Skan/* Return true if we have more bits to visit, in which case *N is set 95169689Skan to the index of the bit to be visited. Otherwise, return 96169689Skan false. */ 97169689Skan 98169689Skanstatic inline bool 99169689Skansbitmap_iter_cond (sbitmap_iterator *i, unsigned int *n) 100169689Skan{ 101169689Skan /* Skip words that are zeros. */ 102169689Skan for (; i->word == 0; i->word = i->ptr[i->word_num]) 103169689Skan { 104169689Skan i->word_num++; 105169689Skan 106169689Skan /* If we have reached the end, break. */ 107169689Skan if (i->word_num >= i->size) 108169689Skan return false; 109169689Skan 110169689Skan i->bit_num = i->word_num * SBITMAP_ELT_BITS; 111169689Skan } 112169689Skan 113169689Skan /* Skip bits that are zero. */ 114169689Skan for (; (i->word & 1) == 0; i->word >>= 1) 115169689Skan i->bit_num++; 116169689Skan 117169689Skan *n = i->bit_num; 118169689Skan 119169689Skan return true; 120169689Skan} 121169689Skan 122169689Skan/* Advance to the next bit. */ 123169689Skan 124169689Skanstatic inline void 125169689Skansbitmap_iter_next (sbitmap_iterator *i) 126169689Skan{ 127169689Skan i->word >>= 1; 128169689Skan i->bit_num++; 129169689Skan} 130169689Skan 131169689Skan/* Loop over all elements of SBITMAP, starting with MIN. In each 132169689Skan iteration, N is set to the index of the bit being visited. ITER is 133169689Skan an instance of sbitmap_iterator used to iterate the bitmap. */ 134169689Skan 135169689Skan#define EXECUTE_IF_SET_IN_SBITMAP(SBITMAP, MIN, N, ITER) \ 136169689Skan for (sbitmap_iter_init (&(ITER), (SBITMAP), (MIN)); \ 137169689Skan sbitmap_iter_cond (&(ITER), &(N)); \ 138169689Skan sbitmap_iter_next (&(ITER))) 139169689Skan 140117395Skan#define EXECUTE_IF_SET_IN_SBITMAP_REV(SBITMAP, N, CODE) \ 141117395Skando { \ 142117395Skan unsigned int word_num_; \ 143117395Skan unsigned int bit_num_; \ 144117395Skan unsigned int size_ = (SBITMAP)->size; \ 145117395Skan SBITMAP_ELT_TYPE *ptr_ = (SBITMAP)->elms; \ 146117395Skan \ 147117395Skan for (word_num_ = size_; word_num_ > 0; word_num_--) \ 148117395Skan { \ 149117395Skan SBITMAP_ELT_TYPE word_ = ptr_[word_num_ - 1]; \ 150117395Skan \ 151117395Skan if (word_ != 0) \ 152117395Skan for (bit_num_ = SBITMAP_ELT_BITS; bit_num_ > 0; bit_num_--) \ 153117395Skan { \ 154117395Skan SBITMAP_ELT_TYPE _mask = (SBITMAP_ELT_TYPE)1 << (bit_num_ - 1);\ 155117395Skan \ 156117395Skan if ((word_ & _mask) != 0) \ 157117395Skan { \ 158117395Skan word_ &= ~ _mask; \ 159117395Skan (N) = (word_num_ - 1) * SBITMAP_ELT_BITS + bit_num_ - 1;\ 160117395Skan CODE; \ 161117395Skan if (word_ == 0) \ 162117395Skan break; \ 163117395Skan } \ 164117395Skan } \ 165117395Skan } \ 166117395Skan} while (0) 167117395Skan 16890075Sobrien#define sbitmap_free(MAP) free(MAP) 16990075Sobrien#define sbitmap_vector_free(VEC) free(VEC) 17052284Sobrien 17190075Sobrienstruct int_list; 17252284Sobrien 173132718Skanextern void dump_sbitmap (FILE *, sbitmap); 174132718Skanextern void dump_sbitmap_file (FILE *, sbitmap); 175132718Skanextern void dump_sbitmap_vector (FILE *, const char *, const char *, sbitmap *, 176132718Skan int); 177132718Skanextern sbitmap sbitmap_alloc (unsigned int); 178132718Skanextern sbitmap *sbitmap_vector_alloc (unsigned int, unsigned int); 179132718Skanextern sbitmap sbitmap_resize (sbitmap, unsigned int, int); 180132718Skanextern void sbitmap_copy (sbitmap, sbitmap); 181132718Skanextern int sbitmap_equal (sbitmap, sbitmap); 182132718Skanextern void sbitmap_zero (sbitmap); 183132718Skanextern void sbitmap_ones (sbitmap); 184132718Skanextern void sbitmap_vector_zero (sbitmap *, unsigned int); 185132718Skanextern void sbitmap_vector_ones (sbitmap *, unsigned int); 18652284Sobrien 187132718Skanextern void sbitmap_union_of_diff (sbitmap, sbitmap, sbitmap, sbitmap); 188132718Skanextern bool sbitmap_union_of_diff_cg (sbitmap, sbitmap, sbitmap, sbitmap); 189132718Skanextern void sbitmap_difference (sbitmap, sbitmap, sbitmap); 190132718Skanextern void sbitmap_not (sbitmap, sbitmap); 191132718Skanextern void sbitmap_a_or_b_and_c (sbitmap, sbitmap, sbitmap, sbitmap); 192132718Skanextern bool sbitmap_a_or_b_and_c_cg (sbitmap, sbitmap, sbitmap, sbitmap); 193132718Skanextern void sbitmap_a_and_b_or_c (sbitmap, sbitmap, sbitmap, sbitmap); 194132718Skanextern bool sbitmap_a_and_b_or_c_cg (sbitmap, sbitmap, sbitmap, sbitmap); 195169689Skanextern bool sbitmap_any_common_bits (sbitmap, sbitmap); 196132718Skanextern void sbitmap_a_and_b (sbitmap, sbitmap, sbitmap); 197132718Skanextern bool sbitmap_a_and_b_cg (sbitmap, sbitmap, sbitmap); 198132718Skanextern void sbitmap_a_or_b (sbitmap, sbitmap, sbitmap); 199132718Skanextern bool sbitmap_a_or_b_cg (sbitmap, sbitmap, sbitmap); 200132718Skanextern void sbitmap_a_xor_b (sbitmap, sbitmap, sbitmap); 201132718Skanextern bool sbitmap_a_xor_b_cg (sbitmap, sbitmap, sbitmap); 202132718Skanextern bool sbitmap_a_subset_b_p (sbitmap, sbitmap); 20352284Sobrien 204132718Skanextern int sbitmap_first_set_bit (sbitmap); 205132718Skanextern int sbitmap_last_set_bit (sbitmap); 20652284Sobrien 207132718Skanextern void sbitmap_intersect_of_predsucc (sbitmap, sbitmap *, int, 208132718Skan struct int_list **); 20952284Sobrien#define sbitmap_intersect_of_predecessors sbitmap_intersect_of_predsucc 21052284Sobrien#define sbitmap_intersect_of_successors sbitmap_intersect_of_predsucc 21152284Sobrien 212132718Skanextern void sbitmap_union_of_predsucc (sbitmap, sbitmap *, int, 213132718Skan struct int_list **); 21452284Sobrien#define sbitmap_union_of_predecessors sbitmap_union_of_predsucc 21552284Sobrien#define sbitmap_union_of_successors sbitmap_union_of_predsucc 21690075Sobrien 217132718Skan/* Intersection and Union of preds/succs using the new flow graph 21890075Sobrien structure instead of the pred/succ arrays. */ 21990075Sobrien 220132718Skanextern void sbitmap_intersection_of_succs (sbitmap, sbitmap *, int); 221132718Skanextern void sbitmap_intersection_of_preds (sbitmap, sbitmap *, int); 222132718Skanextern void sbitmap_union_of_succs (sbitmap, sbitmap *, int); 223132718Skanextern void sbitmap_union_of_preds (sbitmap, sbitmap *, int); 22490075Sobrien 225132718Skanextern void debug_sbitmap (sbitmap); 226169689Skanextern sbitmap sbitmap_realloc (sbitmap, unsigned int); 22790075Sobrien#endif /* ! GCC_SBITMAP_H */ 228