1 /* Functions to support expandable bitsets. 2 Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. 3 Contributed by Michael Hayes (m.hayes (at) elec.canterbury.ac.nz). 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software Foundation, 17 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 18 19 #ifdef HAVE_CONFIG_H 20 # include <config.h> 21 #endif 22 23 #include "ebitset.h" 24 #include "obstack.h" 25 #include <stdlib.h> 26 #include <string.h> 27 28 /* This file implements expandable bitsets. These bitsets can be of 29 arbitrary length and are more efficient than arrays of bits for 30 large sparse sets. 31 32 Empty elements are represented by a NULL pointer in the table of 33 element pointers. An alternative is to point to a special zero 34 element. Similarly, we could represent an all 1's element with 35 another special ones element pointer. 36 37 Bitsets are commonly empty so we need to ensure that this special 38 case is fast. A zero bitset is indicated when cdata is 0. This is 39 conservative since cdata may be non zero and the bitset may still 40 be zero. 41 42 The bitset cache can be disabled either by setting cindex to 43 BITSET_WINDEX_MAX or by setting csize to 0. Here 44 we use the former approach since cindex needs to be updated whenever 45 cdata is changed. 46 */ 47 48 49 /* Number of words to use for each element. */ 50 #define EBITSET_ELT_WORDS 2 51 52 /* Number of bits stored in each element. */ 53 #define EBITSET_ELT_BITS \ 54 ((unsigned int) (EBITSET_ELT_WORDS * BITSET_WORD_BITS)) 55 56 /* Ebitset element. We use an array of bits. */ 57 typedef struct ebitset_elt_struct 58 { 59 union 60 { 61 bitset_word words[EBITSET_ELT_WORDS]; /* Bits that are set. */ 62 struct ebitset_elt_struct *next; 63 } 64 u; 65 } 66 ebitset_elt; 67 68 69 typedef ebitset_elt *ebitset_elts; 70 71 72 /* Number of elements to initially allocate. */ 73 74 #ifndef EBITSET_INITIAL_SIZE 75 #define EBITSET_INITIAL_SIZE 2 76 #endif 77 78 79 enum ebitset_find_mode 80 { EBITSET_FIND, EBITSET_CREATE, EBITSET_SUBST }; 81 82 static ebitset_elt ebitset_zero_elts[1]; /* Elements of all zero bits. */ 83 84 /* Obstack to allocate bitset elements from. */ 85 static struct obstack ebitset_obstack; 86 static bool ebitset_obstack_init = false; 87 static ebitset_elt *ebitset_free_list; /* Free list of bitset elements. */ 88 89 #define EBITSET_N_ELTS(N) (((N) + EBITSET_ELT_BITS - 1) / EBITSET_ELT_BITS) 90 #define EBITSET_ELTS(BSET) ((BSET)->e.elts) 91 #define EBITSET_SIZE(BSET) EBITSET_N_ELTS (BITSET_NBITS_ (BSET)) 92 #define EBITSET_ASIZE(BSET) ((BSET)->e.size) 93 94 #define EBITSET_NEXT(ELT) ((ELT)->u.next) 95 #define EBITSET_WORDS(ELT) ((ELT)->u.words) 96 97 /* Disable bitset cache and mark BSET as being zero. */ 98 #define EBITSET_ZERO_SET(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX, \ 99 (BSET)->b.cdata = 0) 100 101 #define EBITSET_CACHE_DISABLE(BSET) ((BSET)->b.cindex = BITSET_WINDEX_MAX) 102 103 /* Disable bitset cache and mark BSET as being possibly non-zero. */ 104 #define EBITSET_NONZERO_SET(BSET) \ 105 (EBITSET_CACHE_DISABLE (BSET), (BSET)->b.cdata = (bitset_word *)~0) 106 107 /* A conservative estimate of whether the bitset is zero. 108 This is non-zero only if we know for sure that the bitset is zero. */ 109 #define EBITSET_ZERO_P(BSET) ((BSET)->b.cdata == 0) 110 111 /* Enable cache to point to element with table index EINDEX. 112 The element must exist. */ 113 #define EBITSET_CACHE_SET(BSET, EINDEX) \ 114 ((BSET)->b.cindex = (EINDEX) * EBITSET_ELT_WORDS, \ 115 (BSET)->b.cdata = EBITSET_WORDS (EBITSET_ELTS (BSET) [EINDEX])) 116 117 #undef min 118 #undef max 119 #define min(a, b) ((a) > (b) ? (b) : (a)) 120 #define max(a, b) ((a) > (b) ? (a) : (b)) 121 122 static bitset_bindex 123 ebitset_resize (bitset src, bitset_bindex n_bits) 124 { 125 bitset_windex oldsize; 126 bitset_windex newsize; 127 128 if (n_bits == BITSET_NBITS_ (src)) 129 return n_bits; 130 131 oldsize = EBITSET_SIZE (src); 132 newsize = EBITSET_N_ELTS (n_bits); 133 134 if (oldsize < newsize) 135 { 136 bitset_windex size; 137 138 /* The bitset needs to grow. If we already have enough memory 139 allocated, then just zero what we need. */ 140 if (newsize > EBITSET_ASIZE (src)) 141 { 142 /* We need to allocate more memory. When oldsize is 143 non-zero this means that we are changing the size, so 144 grow the bitset 25% larger than requested to reduce 145 number of reallocations. */ 146 147 if (oldsize == 0) 148 size = newsize; 149 else 150 size = newsize + newsize / 4; 151 152 EBITSET_ELTS (src) 153 = realloc (EBITSET_ELTS (src), size * sizeof (ebitset_elt *)); 154 EBITSET_ASIZE (src) = size; 155 } 156 157 memset (EBITSET_ELTS (src) + oldsize, 0, 158 (newsize - oldsize) * sizeof (ebitset_elt *)); 159 } 160 else 161 { 162 /* The bitset needs to shrink. There's no point deallocating 163 the memory unless it is shrinking by a reasonable amount. */ 164 if ((oldsize - newsize) >= oldsize / 2) 165 { 166 EBITSET_ELTS (src) 167 = realloc (EBITSET_ELTS (src), newsize * sizeof (ebitset_elt *)); 168 EBITSET_ASIZE (src) = newsize; 169 } 170 171 /* Need to prune any excess bits. FIXME. */ 172 } 173 174 BITSET_NBITS_ (src) = n_bits; 175 return n_bits; 176 } 177 178 179 /* Allocate a ebitset element. The bits are not cleared. */ 180 static inline ebitset_elt * 181 ebitset_elt_alloc (void) 182 { 183 ebitset_elt *elt; 184 185 if (ebitset_free_list != 0) 186 { 187 elt = ebitset_free_list; 188 ebitset_free_list = EBITSET_NEXT (elt); 189 } 190 else 191 { 192 if (!ebitset_obstack_init) 193 { 194 ebitset_obstack_init = true; 195 196 /* Let particular systems override the size of a chunk. */ 197 198 #ifndef OBSTACK_CHUNK_SIZE 199 #define OBSTACK_CHUNK_SIZE 0 200 #endif 201 202 /* Let them override the alloc and free routines too. */ 203 204 #ifndef OBSTACK_CHUNK_ALLOC 205 #define OBSTACK_CHUNK_ALLOC xmalloc 206 #endif 207 208 #ifndef OBSTACK_CHUNK_FREE 209 #define OBSTACK_CHUNK_FREE free 210 #endif 211 212 #if ! defined __GNUC__ || __GNUC__ < 2 213 #define __alignof__(type) 0 214 #endif 215 216 obstack_specify_allocation (&ebitset_obstack, OBSTACK_CHUNK_SIZE, 217 __alignof__ (ebitset_elt), 218 OBSTACK_CHUNK_ALLOC, 219 OBSTACK_CHUNK_FREE); 220 } 221 222 /* Perhaps we should add a number of new elements to the free 223 list. */ 224 elt = (ebitset_elt *) obstack_alloc (&ebitset_obstack, 225 sizeof (ebitset_elt)); 226 } 227 228 return elt; 229 } 230 231 232 /* Allocate a ebitset element. The bits are cleared. */ 233 static inline ebitset_elt * 234 ebitset_elt_calloc (void) 235 { 236 ebitset_elt *elt; 237 238 elt = ebitset_elt_alloc (); 239 memset (EBITSET_WORDS (elt), 0, sizeof (EBITSET_WORDS (elt))); 240 return elt; 241 } 242 243 244 static inline void 245 ebitset_elt_free (ebitset_elt *elt) 246 { 247 EBITSET_NEXT (elt) = ebitset_free_list; 248 ebitset_free_list = elt; 249 } 250 251 252 /* Remove element with index EINDEX from bitset BSET. */ 253 static inline void 254 ebitset_elt_remove (bitset bset, bitset_windex eindex) 255 { 256 ebitset_elts *elts; 257 ebitset_elt *elt; 258 259 elts = EBITSET_ELTS (bset); 260 261 elt = elts[eindex]; 262 263 elts[eindex] = 0; 264 ebitset_elt_free (elt); 265 } 266 267 268 /* Add ELT into elts at index EINDEX of bitset BSET. */ 269 static inline void 270 ebitset_elt_add (bitset bset, ebitset_elt *elt, bitset_windex eindex) 271 { 272 ebitset_elts *elts; 273 274 elts = EBITSET_ELTS (bset); 275 /* Assume that the elts entry not allocated. */ 276 elts[eindex] = elt; 277 } 278 279 280 /* Are all bits in an element zero? */ 281 static inline bool 282 ebitset_elt_zero_p (ebitset_elt *elt) 283 { 284 int i; 285 286 for (i = 0; i < EBITSET_ELT_WORDS; i++) 287 if (EBITSET_WORDS (elt)[i]) 288 return false; 289 290 return true; 291 } 292 293 294 static ebitset_elt * 295 ebitset_elt_find (bitset bset, bitset_bindex bindex, 296 enum ebitset_find_mode mode) 297 { 298 ebitset_elt *elt; 299 bitset_windex size; 300 bitset_windex eindex; 301 ebitset_elts *elts; 302 303 eindex = bindex / EBITSET_ELT_BITS; 304 305 elts = EBITSET_ELTS (bset); 306 size = EBITSET_SIZE (bset); 307 308 if (eindex < size) 309 { 310 if ((elt = elts[eindex])) 311 { 312 if (EBITSET_WORDS (elt) == bset->b.cdata) 313 return elt; 314 315 EBITSET_CACHE_SET (bset, eindex); 316 return elt; 317 } 318 } 319 320 /* The element could not be found. */ 321 322 switch (mode) 323 { 324 default: 325 abort (); 326 327 case EBITSET_FIND: 328 return 0; 329 330 case EBITSET_CREATE: 331 if (eindex >= size) 332 ebitset_resize (bset, bindex); 333 334 /* Create a new element. */ 335 elt = ebitset_elt_calloc (); 336 ebitset_elt_add (bset, elt, eindex); 337 EBITSET_CACHE_SET (bset, eindex); 338 return elt; 339 340 case EBITSET_SUBST: 341 return &ebitset_zero_elts[0]; 342 } 343 } 344 345 346 /* Weed out the zero elements from the elts. */ 347 static inline bitset_windex 348 ebitset_weed (bitset bset) 349 { 350 ebitset_elts *elts; 351 bitset_windex j; 352 bitset_windex count; 353 354 if (EBITSET_ZERO_P (bset)) 355 return 0; 356 357 elts = EBITSET_ELTS (bset); 358 count = 0; 359 for (j = 0; j < EBITSET_SIZE (bset); j++) 360 { 361 ebitset_elt *elt = elts[j]; 362 363 if (elt) 364 { 365 if (ebitset_elt_zero_p (elt)) 366 { 367 ebitset_elt_remove (bset, j); 368 count++; 369 } 370 } 371 else 372 count++; 373 } 374 375 count = j - count; 376 if (!count) 377 { 378 /* All the bits are zero. We could shrink the elts. 379 For now just mark BSET as known to be zero. */ 380 EBITSET_ZERO_SET (bset); 381 } 382 else 383 EBITSET_NONZERO_SET (bset); 384 385 return count; 386 } 387 388 389 /* Set all bits in the bitset to zero. */ 390 static inline void 391 ebitset_zero (bitset bset) 392 { 393 ebitset_elts *elts; 394 bitset_windex j; 395 396 if (EBITSET_ZERO_P (bset)) 397 return; 398 399 elts = EBITSET_ELTS (bset); 400 for (j = 0; j < EBITSET_SIZE (bset); j++) 401 { 402 ebitset_elt *elt = elts[j]; 403 404 if (elt) 405 ebitset_elt_remove (bset, j); 406 } 407 408 /* All the bits are zero. We could shrink the elts. 409 For now just mark BSET as known to be zero. */ 410 EBITSET_ZERO_SET (bset); 411 } 412 413 414 static inline bool 415 ebitset_equal_p (bitset dst, bitset src) 416 { 417 ebitset_elts *selts; 418 ebitset_elts *delts; 419 bitset_windex j; 420 421 if (src == dst) 422 return true; 423 424 ebitset_weed (dst); 425 ebitset_weed (src); 426 427 if (EBITSET_SIZE (src) != EBITSET_SIZE (dst)) 428 return false; 429 430 selts = EBITSET_ELTS (src); 431 delts = EBITSET_ELTS (dst); 432 433 for (j = 0; j < EBITSET_SIZE (src); j++) 434 { 435 unsigned int i; 436 ebitset_elt *selt = selts[j]; 437 ebitset_elt *delt = delts[j]; 438 439 if (!selt && !delt) 440 continue; 441 if ((selt && !delt) || (!selt && delt)) 442 return false; 443 444 for (i = 0; i < EBITSET_ELT_WORDS; i++) 445 if (EBITSET_WORDS (selt)[i] != EBITSET_WORDS (delt)[i]) 446 return false; 447 } 448 return true; 449 } 450 451 452 /* Copy bits from bitset SRC to bitset DST. */ 453 static inline void 454 ebitset_copy_ (bitset dst, bitset src) 455 { 456 ebitset_elts *selts; 457 ebitset_elts *delts; 458 bitset_windex j; 459 460 if (src == dst) 461 return; 462 463 ebitset_zero (dst); 464 465 if (BITSET_NBITS_ (dst) != BITSET_NBITS_ (src)) 466 ebitset_resize (dst, BITSET_NBITS_ (src)); 467 468 selts = EBITSET_ELTS (src); 469 delts = EBITSET_ELTS (dst); 470 for (j = 0; j < EBITSET_SIZE (src); j++) 471 { 472 ebitset_elt *selt = selts[j]; 473 474 if (selt) 475 { 476 ebitset_elt *tmp; 477 478 tmp = ebitset_elt_alloc (); 479 delts[j] = tmp; 480 memcpy (EBITSET_WORDS (tmp), EBITSET_WORDS (selt), 481 sizeof (EBITSET_WORDS (selt))); 482 } 483 } 484 EBITSET_NONZERO_SET (dst); 485 } 486 487 488 /* Copy bits from bitset SRC to bitset DST. Return true if 489 bitsets different. */ 490 static inline bool 491 ebitset_copy_cmp (bitset dst, bitset src) 492 { 493 if (src == dst) 494 return false; 495 496 if (EBITSET_ZERO_P (dst)) 497 { 498 ebitset_copy_ (dst, src); 499 return !EBITSET_ZERO_P (src); 500 } 501 502 if (ebitset_equal_p (dst, src)) 503 return false; 504 505 ebitset_copy_ (dst, src); 506 return true; 507 } 508 509 510 /* Set bit BITNO in bitset DST. */ 511 static void 512 ebitset_set (bitset dst, bitset_bindex bitno) 513 { 514 bitset_windex windex = bitno / BITSET_WORD_BITS; 515 516 ebitset_elt_find (dst, bitno, EBITSET_CREATE); 517 518 dst->b.cdata[windex - dst->b.cindex] |= 519 (bitset_word) 1 << (bitno % BITSET_WORD_BITS); 520 } 521 522 523 /* Reset bit BITNO in bitset DST. */ 524 static void 525 ebitset_reset (bitset dst, bitset_bindex bitno) 526 { 527 bitset_windex windex = bitno / BITSET_WORD_BITS; 528 529 if (!ebitset_elt_find (dst, bitno, EBITSET_FIND)) 530 return; 531 532 dst->b.cdata[windex - dst->b.cindex] &= 533 ~((bitset_word) 1 << (bitno % BITSET_WORD_BITS)); 534 535 /* If all the data is zero, perhaps we should remove it now... 536 However, there is a good chance that the element will be needed 537 again soon. */ 538 } 539 540 541 /* Test bit BITNO in bitset SRC. */ 542 static bool 543 ebitset_test (bitset src, bitset_bindex bitno) 544 { 545 bitset_windex windex = bitno / BITSET_WORD_BITS; 546 547 return (ebitset_elt_find (src, bitno, EBITSET_FIND) 548 && ((src->b.cdata[windex - src->b.cindex] 549 >> (bitno % BITSET_WORD_BITS)) 550 & 1)); 551 } 552 553 554 static void 555 ebitset_free (bitset bset) 556 { 557 ebitset_zero (bset); 558 free (EBITSET_ELTS (bset)); 559 } 560 561 562 /* Find list of up to NUM bits set in BSET starting from and including 563 *NEXT and store in array LIST. Return with actual number of bits 564 found and with *NEXT indicating where search stopped. */ 565 static bitset_bindex 566 ebitset_list_reverse (bitset bset, bitset_bindex *list, 567 bitset_bindex num, bitset_bindex *next) 568 { 569 bitset_bindex n_bits; 570 bitset_bindex bitno; 571 bitset_bindex rbitno; 572 unsigned int bcount; 573 bitset_bindex boffset; 574 bitset_windex windex; 575 bitset_windex eindex; 576 bitset_windex woffset; 577 bitset_bindex count; 578 bitset_windex size; 579 ebitset_elts *elts; 580 581 if (EBITSET_ZERO_P (bset)) 582 return 0; 583 584 size = EBITSET_SIZE (bset); 585 n_bits = size * EBITSET_ELT_BITS; 586 rbitno = *next; 587 588 if (rbitno >= n_bits) 589 return 0; 590 591 elts = EBITSET_ELTS (bset); 592 593 bitno = n_bits - (rbitno + 1); 594 595 windex = bitno / BITSET_WORD_BITS; 596 eindex = bitno / EBITSET_ELT_BITS; 597 woffset = windex - eindex * EBITSET_ELT_WORDS; 598 599 /* If num is 1, we could speed things up with a binary search 600 of the word of interest. */ 601 602 count = 0; 603 bcount = bitno % BITSET_WORD_BITS; 604 boffset = windex * BITSET_WORD_BITS; 605 606 do 607 { 608 ebitset_elt *elt; 609 bitset_word *srcp; 610 611 elt = elts[eindex]; 612 if (elt) 613 { 614 srcp = EBITSET_WORDS (elt); 615 616 do 617 { 618 bitset_word word; 619 620 word = srcp[woffset] << (BITSET_WORD_BITS - 1 - bcount); 621 622 for (; word; bcount--) 623 { 624 if (word & BITSET_MSB) 625 { 626 list[count++] = boffset + bcount; 627 if (count >= num) 628 { 629 *next = n_bits - (boffset + bcount); 630 return count; 631 } 632 } 633 word <<= 1; 634 } 635 boffset -= BITSET_WORD_BITS; 636 bcount = BITSET_WORD_BITS - 1; 637 } 638 while (woffset--); 639 } 640 641 woffset = EBITSET_ELT_WORDS - 1; 642 boffset = eindex * EBITSET_ELT_BITS - BITSET_WORD_BITS; 643 } 644 while (eindex--); 645 646 *next = n_bits - (boffset + 1); 647 return count; 648 } 649 650 651 /* Find list of up to NUM bits set in BSET starting from and including 652 *NEXT and store in array LIST. Return with actual number of bits 653 found and with *NEXT indicating where search stopped. */ 654 static bitset_bindex 655 ebitset_list (bitset bset, bitset_bindex *list, 656 bitset_bindex num, bitset_bindex *next) 657 { 658 bitset_bindex bitno; 659 bitset_windex windex; 660 bitset_windex eindex; 661 bitset_bindex count; 662 bitset_windex size; 663 ebitset_elt *elt; 664 bitset_word word; 665 ebitset_elts *elts; 666 667 if (EBITSET_ZERO_P (bset)) 668 return 0; 669 670 bitno = *next; 671 count = 0; 672 673 elts = EBITSET_ELTS (bset); 674 size = EBITSET_SIZE (bset); 675 eindex = bitno / EBITSET_ELT_BITS; 676 677 if (bitno % EBITSET_ELT_BITS) 678 { 679 /* We need to start within an element. This is not very common. */ 680 681 elt = elts[eindex]; 682 if (elt) 683 { 684 bitset_windex woffset; 685 bitset_word *srcp = EBITSET_WORDS (elt); 686 687 windex = bitno / BITSET_WORD_BITS; 688 woffset = eindex * EBITSET_ELT_WORDS; 689 690 for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++) 691 { 692 word = srcp[windex - woffset] >> (bitno % BITSET_WORD_BITS); 693 694 for (; word; bitno++) 695 { 696 if (word & 1) 697 { 698 list[count++] = bitno; 699 if (count >= num) 700 { 701 *next = bitno + 1; 702 return count; 703 } 704 } 705 word >>= 1; 706 } 707 bitno = (windex + 1) * BITSET_WORD_BITS; 708 } 709 } 710 711 /* Skip to next element. */ 712 eindex++; 713 } 714 715 /* If num is 1, we could speed things up with a binary search 716 of the word of interest. */ 717 718 for (; eindex < size; eindex++) 719 { 720 int i; 721 bitset_word *srcp; 722 723 elt = elts[eindex]; 724 if (!elt) 725 continue; 726 727 srcp = EBITSET_WORDS (elt); 728 windex = eindex * EBITSET_ELT_WORDS; 729 730 if ((count + EBITSET_ELT_BITS) < num) 731 { 732 /* The coast is clear, plant boot! */ 733 734 #if EBITSET_ELT_WORDS == 2 735 word = srcp[0]; 736 if (word) 737 { 738 if (!(word & 0xffff)) 739 { 740 word >>= 16; 741 bitno += 16; 742 } 743 if (!(word & 0xff)) 744 { 745 word >>= 8; 746 bitno += 8; 747 } 748 for (; word; bitno++) 749 { 750 if (word & 1) 751 list[count++] = bitno; 752 word >>= 1; 753 } 754 } 755 windex++; 756 bitno = windex * BITSET_WORD_BITS; 757 758 word = srcp[1]; 759 if (word) 760 { 761 if (!(word & 0xffff)) 762 { 763 word >>= 16; 764 bitno += 16; 765 } 766 for (; word; bitno++) 767 { 768 if (word & 1) 769 list[count++] = bitno; 770 word >>= 1; 771 } 772 } 773 windex++; 774 bitno = windex * BITSET_WORD_BITS; 775 #else 776 for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++) 777 { 778 bitno = windex * BITSET_WORD_BITS; 779 780 word = srcp[i]; 781 if (word) 782 { 783 if (!(word & 0xffff)) 784 { 785 word >>= 16; 786 bitno += 16; 787 } 788 if (!(word & 0xff)) 789 { 790 word >>= 8; 791 bitno += 8; 792 } 793 for (; word; bitno++) 794 { 795 if (word & 1) 796 list[count++] = bitno; 797 word >>= 1; 798 } 799 } 800 } 801 #endif 802 } 803 else 804 { 805 /* Tread more carefully since we need to check 806 if array overflows. */ 807 808 for (i = 0; i < EBITSET_ELT_WORDS; i++, windex++) 809 { 810 bitno = windex * BITSET_WORD_BITS; 811 812 for (word = srcp[i]; word; bitno++) 813 { 814 if (word & 1) 815 { 816 list[count++] = bitno; 817 if (count >= num) 818 { 819 *next = bitno + 1; 820 return count; 821 } 822 } 823 word >>= 1; 824 } 825 } 826 } 827 } 828 829 *next = bitno; 830 return count; 831 } 832 833 834 /* Ensure that any unused bits within the last element are clear. */ 835 static inline void 836 ebitset_unused_clear (bitset dst) 837 { 838 unsigned int last_bit; 839 bitset_bindex n_bits; 840 841 n_bits = BITSET_NBITS_ (dst); 842 last_bit = n_bits % EBITSET_ELT_BITS; 843 844 if (last_bit) 845 { 846 bitset_windex eindex; 847 ebitset_elts *elts; 848 ebitset_elt *elt; 849 850 elts = EBITSET_ELTS (dst); 851 852 eindex = n_bits / EBITSET_ELT_BITS; 853 854 elt = elts[eindex]; 855 if (elt) 856 { 857 bitset_windex windex; 858 bitset_windex woffset; 859 bitset_word *srcp = EBITSET_WORDS (elt); 860 861 windex = n_bits / BITSET_WORD_BITS; 862 woffset = eindex * EBITSET_ELT_WORDS; 863 864 srcp[windex - woffset] &= ((bitset_word) 1 << last_bit) - 1; 865 windex++; 866 for (; (windex - woffset) < EBITSET_ELT_WORDS; windex++) 867 srcp[windex - woffset] = 0; 868 } 869 } 870 } 871 872 873 static void 874 ebitset_ones (bitset dst) 875 { 876 bitset_windex j; 877 ebitset_elt *elt; 878 879 for (j = 0; j < EBITSET_SIZE (dst); j++) 880 { 881 /* Create new elements if they cannot be found. Perhaps 882 we should just add pointers to a ones element? */ 883 elt = 884 ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_CREATE); 885 memset (EBITSET_WORDS (elt), -1, sizeof (EBITSET_WORDS (elt))); 886 } 887 EBITSET_NONZERO_SET (dst); 888 ebitset_unused_clear (dst); 889 } 890 891 892 static bool 893 ebitset_empty_p (bitset dst) 894 { 895 ebitset_elts *elts; 896 bitset_windex j; 897 898 if (EBITSET_ZERO_P (dst)) 899 return 1; 900 901 elts = EBITSET_ELTS (dst); 902 for (j = 0; j < EBITSET_SIZE (dst); j++) 903 { 904 ebitset_elt *elt = elts[j]; 905 906 if (elt) 907 { 908 if (!ebitset_elt_zero_p (elt)) 909 return 0; 910 /* Do some weeding as we go. */ 911 ebitset_elt_remove (dst, j); 912 } 913 } 914 915 /* All the bits are zero. We could shrink the elts. 916 For now just mark DST as known to be zero. */ 917 EBITSET_ZERO_SET (dst); 918 return 1; 919 } 920 921 922 static void 923 ebitset_not (bitset dst, bitset src) 924 { 925 unsigned int i; 926 ebitset_elt *selt; 927 ebitset_elt *delt; 928 bitset_windex j; 929 930 ebitset_resize (dst, BITSET_NBITS_ (src)); 931 932 for (j = 0; j < EBITSET_SIZE (src); j++) 933 { 934 /* Create new elements for dst if they cannot be found 935 or substitute zero elements if src elements not found. */ 936 selt = 937 ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_SUBST); 938 delt = 939 ebitset_elt_find (dst, j * EBITSET_ELT_BITS, EBITSET_CREATE); 940 941 for (i = 0; i < EBITSET_ELT_WORDS; i++) 942 EBITSET_WORDS (delt)[i] = ~EBITSET_WORDS (selt)[i]; 943 } 944 EBITSET_NONZERO_SET (dst); 945 ebitset_unused_clear (dst); 946 } 947 948 949 /* Is DST == DST | SRC? */ 950 static bool 951 ebitset_subset_p (bitset dst, bitset src) 952 { 953 bitset_windex j; 954 ebitset_elts *selts; 955 ebitset_elts *delts; 956 bitset_windex ssize; 957 bitset_windex dsize; 958 959 selts = EBITSET_ELTS (src); 960 delts = EBITSET_ELTS (dst); 961 962 ssize = EBITSET_SIZE (src); 963 dsize = EBITSET_SIZE (dst); 964 965 for (j = 0; j < ssize; j++) 966 { 967 unsigned int i; 968 ebitset_elt *selt; 969 ebitset_elt *delt; 970 971 selt = j < ssize ? selts[j] : 0; 972 delt = j < dsize ? delts[j] : 0; 973 974 if (!selt && !delt) 975 continue; 976 977 if (!selt) 978 selt = &ebitset_zero_elts[0]; 979 if (!delt) 980 delt = &ebitset_zero_elts[0]; 981 982 for (i = 0; i < EBITSET_ELT_WORDS; i++) 983 if (EBITSET_WORDS (delt)[i] 984 != (EBITSET_WORDS (selt)[i] | EBITSET_WORDS (delt)[i])) 985 return false; 986 } 987 return true; 988 } 989 990 991 /* Is DST & SRC == 0? */ 992 static bool 993 ebitset_disjoint_p (bitset dst, bitset src) 994 { 995 bitset_windex j; 996 ebitset_elts *selts; 997 ebitset_elts *delts; 998 bitset_windex ssize; 999 bitset_windex dsize; 1000 1001 selts = EBITSET_ELTS (src); 1002 delts = EBITSET_ELTS (dst); 1003 1004 ssize = EBITSET_SIZE (src); 1005 dsize = EBITSET_SIZE (dst); 1006 1007 for (j = 0; j < ssize; j++) 1008 { 1009 unsigned int i; 1010 ebitset_elt *selt; 1011 ebitset_elt *delt; 1012 1013 selt = j < ssize ? selts[j] : 0; 1014 delt = j < dsize ? delts[j] : 0; 1015 1016 if (!selt || !delt) 1017 continue; 1018 1019 for (i = 0; i < EBITSET_ELT_WORDS; i++) 1020 if ((EBITSET_WORDS (selt)[i] & EBITSET_WORDS (delt)[i])) 1021 return false; 1022 } 1023 return true; 1024 } 1025 1026 1027 1028 static bool 1029 ebitset_op3_cmp (bitset dst, bitset src1, bitset src2, enum bitset_ops op) 1030 { 1031 bitset_windex ssize1; 1032 bitset_windex ssize2; 1033 bitset_windex dsize; 1034 bitset_windex size; 1035 ebitset_elts *selts1; 1036 ebitset_elts *selts2; 1037 ebitset_elts *delts; 1038 bitset_word *srcp1; 1039 bitset_word *srcp2; 1040 bitset_word *dstp; 1041 bool changed = false; 1042 unsigned int i; 1043 bitset_windex j; 1044 1045 ebitset_resize (dst, max (BITSET_NBITS_ (src1), BITSET_NBITS_ (src2))); 1046 1047 ssize1 = EBITSET_SIZE (src1); 1048 ssize2 = EBITSET_SIZE (src2); 1049 dsize = EBITSET_SIZE (dst); 1050 size = ssize1; 1051 if (size < ssize2) 1052 size = ssize2; 1053 1054 selts1 = EBITSET_ELTS (src1); 1055 selts2 = EBITSET_ELTS (src2); 1056 delts = EBITSET_ELTS (dst); 1057 1058 for (j = 0; j < size; j++) 1059 { 1060 ebitset_elt *selt1; 1061 ebitset_elt *selt2; 1062 ebitset_elt *delt; 1063 1064 selt1 = j < ssize1 ? selts1[j] : 0; 1065 selt2 = j < ssize2 ? selts2[j] : 0; 1066 delt = j < dsize ? delts[j] : 0; 1067 1068 if (!selt1 && !selt2) 1069 { 1070 if (delt) 1071 { 1072 changed = true; 1073 ebitset_elt_remove (dst, j); 1074 } 1075 continue; 1076 } 1077 1078 if (!selt1) 1079 selt1 = &ebitset_zero_elts[0]; 1080 if (!selt2) 1081 selt2 = &ebitset_zero_elts[0]; 1082 if (!delt) 1083 delt = ebitset_elt_calloc (); 1084 else 1085 delts[j] = 0; 1086 1087 srcp1 = EBITSET_WORDS (selt1); 1088 srcp2 = EBITSET_WORDS (selt2); 1089 dstp = EBITSET_WORDS (delt); 1090 switch (op) 1091 { 1092 default: 1093 abort (); 1094 1095 case BITSET_OP_OR: 1096 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++) 1097 { 1098 bitset_word tmp = *srcp1++ | *srcp2++; 1099 1100 if (*dstp != tmp) 1101 { 1102 changed = true; 1103 *dstp = tmp; 1104 } 1105 } 1106 break; 1107 1108 case BITSET_OP_AND: 1109 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++) 1110 { 1111 bitset_word tmp = *srcp1++ & *srcp2++; 1112 1113 if (*dstp != tmp) 1114 { 1115 changed = true; 1116 *dstp = tmp; 1117 } 1118 } 1119 break; 1120 1121 case BITSET_OP_XOR: 1122 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++) 1123 { 1124 bitset_word tmp = *srcp1++ ^ *srcp2++; 1125 1126 if (*dstp != tmp) 1127 { 1128 changed = true; 1129 *dstp = tmp; 1130 } 1131 } 1132 break; 1133 1134 case BITSET_OP_ANDN: 1135 for (i = 0; i < EBITSET_ELT_WORDS; i++, dstp++) 1136 { 1137 bitset_word tmp = *srcp1++ & ~(*srcp2++); 1138 1139 if (*dstp != tmp) 1140 { 1141 changed = true; 1142 *dstp = tmp; 1143 } 1144 } 1145 break; 1146 } 1147 1148 if (!ebitset_elt_zero_p (delt)) 1149 { 1150 ebitset_elt_add (dst, delt, j); 1151 } 1152 else 1153 { 1154 ebitset_elt_free (delt); 1155 } 1156 } 1157 1158 /* If we have elements of DST left over, free them all. */ 1159 for (; j < dsize; j++) 1160 { 1161 ebitset_elt *delt; 1162 1163 changed = true; 1164 1165 delt = delts[j]; 1166 1167 if (delt) 1168 ebitset_elt_remove (dst, j); 1169 } 1170 1171 EBITSET_NONZERO_SET (dst); 1172 return changed; 1173 } 1174 1175 1176 static bool 1177 ebitset_and_cmp (bitset dst, bitset src1, bitset src2) 1178 { 1179 bool changed; 1180 1181 if (EBITSET_ZERO_P (src2)) 1182 { 1183 ebitset_weed (dst); 1184 changed = EBITSET_ZERO_P (dst); 1185 ebitset_zero (dst); 1186 return changed; 1187 } 1188 else if (EBITSET_ZERO_P (src1)) 1189 { 1190 ebitset_weed (dst); 1191 changed = EBITSET_ZERO_P (dst); 1192 ebitset_zero (dst); 1193 return changed; 1194 } 1195 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_AND); 1196 } 1197 1198 1199 static void 1200 ebitset_and (bitset dst, bitset src1, bitset src2) 1201 { 1202 ebitset_and_cmp (dst, src1, src2); 1203 } 1204 1205 1206 static bool 1207 ebitset_andn_cmp (bitset dst, bitset src1, bitset src2) 1208 { 1209 bool changed; 1210 1211 if (EBITSET_ZERO_P (src2)) 1212 { 1213 return ebitset_copy_cmp (dst, src1); 1214 } 1215 else if (EBITSET_ZERO_P (src1)) 1216 { 1217 ebitset_weed (dst); 1218 changed = EBITSET_ZERO_P (dst); 1219 ebitset_zero (dst); 1220 return changed; 1221 } 1222 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_ANDN); 1223 } 1224 1225 1226 static void 1227 ebitset_andn (bitset dst, bitset src1, bitset src2) 1228 { 1229 ebitset_andn_cmp (dst, src1, src2); 1230 } 1231 1232 1233 static bool 1234 ebitset_or_cmp (bitset dst, bitset src1, bitset src2) 1235 { 1236 if (EBITSET_ZERO_P (src2)) 1237 { 1238 return ebitset_copy_cmp (dst, src1); 1239 } 1240 else if (EBITSET_ZERO_P (src1)) 1241 { 1242 return ebitset_copy_cmp (dst, src2); 1243 } 1244 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_OR); 1245 } 1246 1247 1248 static void 1249 ebitset_or (bitset dst, bitset src1, bitset src2) 1250 { 1251 ebitset_or_cmp (dst, src1, src2); 1252 } 1253 1254 1255 static bool 1256 ebitset_xor_cmp (bitset dst, bitset src1, bitset src2) 1257 { 1258 if (EBITSET_ZERO_P (src2)) 1259 { 1260 return ebitset_copy_cmp (dst, src1); 1261 } 1262 else if (EBITSET_ZERO_P (src1)) 1263 { 1264 return ebitset_copy_cmp (dst, src2); 1265 } 1266 return ebitset_op3_cmp (dst, src1, src2, BITSET_OP_XOR); 1267 } 1268 1269 1270 static void 1271 ebitset_xor (bitset dst, bitset src1, bitset src2) 1272 { 1273 ebitset_xor_cmp (dst, src1, src2); 1274 } 1275 1276 1277 static void 1278 ebitset_copy (bitset dst, bitset src) 1279 { 1280 if (BITSET_COMPATIBLE_ (dst, src)) 1281 ebitset_copy_ (dst, src); 1282 else 1283 bitset_copy_ (dst, src); 1284 } 1285 1286 1287 /* Vector of operations for linked-list bitsets. */ 1288 struct bitset_vtable ebitset_vtable = { 1289 ebitset_set, 1290 ebitset_reset, 1291 bitset_toggle_, 1292 ebitset_test, 1293 ebitset_resize, 1294 bitset_size_, 1295 bitset_count_, 1296 ebitset_empty_p, 1297 ebitset_ones, 1298 ebitset_zero, 1299 ebitset_copy, 1300 ebitset_disjoint_p, 1301 ebitset_equal_p, 1302 ebitset_not, 1303 ebitset_subset_p, 1304 ebitset_and, 1305 ebitset_and_cmp, 1306 ebitset_andn, 1307 ebitset_andn_cmp, 1308 ebitset_or, 1309 ebitset_or_cmp, 1310 ebitset_xor, 1311 ebitset_xor_cmp, 1312 bitset_and_or_, 1313 bitset_and_or_cmp_, 1314 bitset_andn_or_, 1315 bitset_andn_or_cmp_, 1316 bitset_or_and_, 1317 bitset_or_and_cmp_, 1318 ebitset_list, 1319 ebitset_list_reverse, 1320 ebitset_free, 1321 BITSET_TABLE 1322 }; 1323 1324 1325 /* Return size of initial structure. */ 1326 size_t 1327 ebitset_bytes (bitset_bindex n_bits ATTRIBUTE_UNUSED) 1328 { 1329 return sizeof (struct ebitset_struct); 1330 } 1331 1332 1333 /* Initialize a bitset. */ 1334 1335 bitset 1336 ebitset_init (bitset bset, bitset_bindex n_bits) 1337 { 1338 bitset_windex size; 1339 1340 bset->b.vtable = &ebitset_vtable; 1341 1342 bset->b.csize = EBITSET_ELT_WORDS; 1343 1344 EBITSET_ZERO_SET (bset); 1345 1346 size = n_bits ? (n_bits + EBITSET_ELT_BITS - 1) / EBITSET_ELT_BITS 1347 : EBITSET_INITIAL_SIZE; 1348 1349 EBITSET_ASIZE (bset) = 0; 1350 EBITSET_ELTS (bset) = 0; 1351 ebitset_resize (bset, n_bits); 1352 1353 return bset; 1354 } 1355 1356 1357 void 1358 ebitset_release_memory (void) 1359 { 1360 ebitset_free_list = 0; 1361 if (ebitset_obstack_init) 1362 { 1363 ebitset_obstack_init = false; 1364 obstack_free (&ebitset_obstack, NULL); 1365 } 1366 } 1367