00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "rtl.h"
00025 #include "flags.h"
00026 #include "obstack.h"
00027 #include "ggc.h"
00028 #include "bitmap.h"
00029
00030
00031 static struct obstack bitmap_obstack;
00032 static int bitmap_obstack_init = FALSE;
00033
00034 #ifndef INLINE
00035 #ifndef __GNUC__
00036 #define INLINE
00037 #else
00038 #define INLINE __inline__
00039 #endif
00040 #endif
00041
00042
00043 bitmap_element bitmap_zero_bits;
00044 static bitmap_element *bitmap_free;
00045 static GTY((deletable (""))) bitmap_element *bitmap_ggc_free;
00046
00047 static void bitmap_elem_to_freelist PARAMS ((bitmap, bitmap_element *));
00048 static void bitmap_element_free PARAMS ((bitmap, bitmap_element *));
00049 static bitmap_element *bitmap_element_allocate PARAMS ((bitmap));
00050 static int bitmap_element_zerop PARAMS ((bitmap_element *));
00051 static void bitmap_element_link PARAMS ((bitmap, bitmap_element *));
00052 static bitmap_element *bitmap_find_bit PARAMS ((bitmap, unsigned int));
00053
00054
00055 static INLINE void
00056 bitmap_elem_to_freelist (head, elt)
00057 bitmap head;
00058 bitmap_element *elt;
00059 {
00060 if (head->using_obstack)
00061 {
00062 elt->next = bitmap_free;
00063 bitmap_free = elt;
00064 }
00065 else
00066 {
00067 elt->next = bitmap_ggc_free;
00068 bitmap_ggc_free = elt;
00069 }
00070 }
00071
00072
00073
00074
00075 static INLINE void
00076 bitmap_element_free (head, elt)
00077 bitmap head;
00078 bitmap_element *elt;
00079 {
00080 bitmap_element *next = elt->next;
00081 bitmap_element *prev = elt->prev;
00082
00083 if (prev)
00084 prev->next = next;
00085
00086 if (next)
00087 next->prev = prev;
00088
00089 if (head->first == elt)
00090 head->first = next;
00091
00092
00093
00094 if (head->current == elt)
00095 {
00096 head->current = next != 0 ? next : prev;
00097 if (head->current)
00098 head->indx = head->current->indx;
00099 }
00100 bitmap_elem_to_freelist (head, elt);
00101 }
00102
00103
00104
00105 static INLINE bitmap_element *
00106 bitmap_element_allocate (head)
00107 bitmap head;
00108 {
00109 bitmap_element *element;
00110
00111 if (head->using_obstack)
00112 {
00113 if (bitmap_free != 0)
00114 {
00115 element = bitmap_free;
00116 bitmap_free = element->next;
00117 }
00118 else
00119 {
00120
00121
00122
00123 if (!bitmap_obstack_init)
00124 {
00125 bitmap_obstack_init = TRUE;
00126
00127
00128 #ifndef OBSTACK_CHUNK_SIZE
00129 #define OBSTACK_CHUNK_SIZE 0
00130 #endif
00131
00132 #ifndef OBSTACK_CHUNK_ALLOC
00133 #define OBSTACK_CHUNK_ALLOC xmalloc
00134 #endif
00135 #ifndef OBSTACK_CHUNK_FREE
00136 #define OBSTACK_CHUNK_FREE free
00137 #endif
00138
00139 #if !defined(__GNUC__) || (__GNUC__ < 2)
00140 #define __alignof__(type) 0
00141 #endif
00142
00143 obstack_specify_allocation (&bitmap_obstack, OBSTACK_CHUNK_SIZE,
00144 __alignof__ (bitmap_element),
00145 (void *(*) PARAMS ((long))) OBSTACK_CHUNK_ALLOC,
00146 (void (*) PARAMS ((void *))) OBSTACK_CHUNK_FREE);
00147 }
00148
00149 element = (bitmap_element *) obstack_alloc (&bitmap_obstack,
00150 sizeof (bitmap_element));
00151 }
00152 }
00153 else
00154 {
00155 if (bitmap_ggc_free != NULL)
00156 {
00157 element = bitmap_ggc_free;
00158 bitmap_ggc_free = element->next;
00159 }
00160 else
00161 element = ggc_alloc (sizeof (bitmap_element));
00162 }
00163
00164 memset (element->bits, 0, sizeof (element->bits));
00165
00166 return element;
00167 }
00168
00169
00170
00171 void
00172 bitmap_release_memory ()
00173 {
00174 bitmap_free = 0;
00175 if (bitmap_obstack_init)
00176 {
00177 bitmap_obstack_init = FALSE;
00178 obstack_free (&bitmap_obstack, NULL);
00179 }
00180 }
00181
00182
00183
00184 static INLINE int
00185 bitmap_element_zerop (element)
00186 bitmap_element *element;
00187 {
00188 #if BITMAP_ELEMENT_WORDS == 2
00189 return (element->bits[0] | element->bits[1]) == 0;
00190 #else
00191 int i;
00192
00193 for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
00194 if (element->bits[i] != 0)
00195 return 0;
00196
00197 return 1;
00198 #endif
00199 }
00200
00201
00202
00203 static INLINE void
00204 bitmap_element_link (head, element)
00205 bitmap head;
00206 bitmap_element *element;
00207 {
00208 unsigned int indx = element->indx;
00209 bitmap_element *ptr;
00210
00211
00212 if (head->first == 0)
00213 {
00214 element->next = element->prev = 0;
00215 head->first = element;
00216 }
00217
00218
00219
00220 else if (indx < head->indx)
00221 {
00222 for (ptr = head->current;
00223 ptr->prev != 0 && ptr->prev->indx > indx;
00224 ptr = ptr->prev)
00225 ;
00226
00227 if (ptr->prev)
00228 ptr->prev->next = element;
00229 else
00230 head->first = element;
00231
00232 element->prev = ptr->prev;
00233 element->next = ptr;
00234 ptr->prev = element;
00235 }
00236
00237
00238 else
00239 {
00240 for (ptr = head->current;
00241 ptr->next != 0 && ptr->next->indx < indx;
00242 ptr = ptr->next)
00243 ;
00244
00245 if (ptr->next)
00246 ptr->next->prev = element;
00247
00248 element->next = ptr->next;
00249 element->prev = ptr;
00250 ptr->next = element;
00251 }
00252
00253
00254 head->current = element;
00255 head->indx = indx;
00256 }
00257
00258
00259
00260 #ifndef KEY
00261 INLINE
00262 #endif
00263 void
00264 bitmap_clear (head)
00265 bitmap head;
00266 {
00267 bitmap_element *element, *next;
00268
00269 for (element = head->first; element != 0; element = next)
00270 {
00271 next = element->next;
00272 bitmap_elem_to_freelist (head, element);
00273 }
00274
00275 head->first = head->current = 0;
00276 }
00277
00278
00279
00280 void
00281 bitmap_copy (to, from)
00282 bitmap to;
00283 bitmap from;
00284 {
00285 bitmap_element *from_ptr, *to_ptr = 0;
00286 #if BITMAP_ELEMENT_WORDS != 2
00287 int i;
00288 #endif
00289
00290 bitmap_clear (to);
00291
00292
00293 for (from_ptr = from->first; from_ptr; from_ptr = from_ptr->next)
00294 {
00295 bitmap_element *to_elt = bitmap_element_allocate (to);
00296
00297 to_elt->indx = from_ptr->indx;
00298
00299 #if BITMAP_ELEMENT_WORDS == 2
00300 to_elt->bits[0] = from_ptr->bits[0];
00301 to_elt->bits[1] = from_ptr->bits[1];
00302 #else
00303 for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
00304 to_elt->bits[i] = from_ptr->bits[i];
00305 #endif
00306
00307
00308
00309 if (to_ptr == 0)
00310 {
00311 to->first = to->current = to_elt;
00312 to->indx = from_ptr->indx;
00313 to_elt->next = to_elt->prev = 0;
00314 }
00315 else
00316 {
00317 to_elt->prev = to_ptr;
00318 to_elt->next = 0;
00319 to_ptr->next = to_elt;
00320 }
00321
00322 to_ptr = to_elt;
00323 }
00324 }
00325
00326
00327
00328
00329
00330
00331 static INLINE bitmap_element *
00332 bitmap_find_bit (head, bit)
00333 bitmap head;
00334 unsigned int bit;
00335 {
00336 bitmap_element *element;
00337 unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
00338
00339 if (head->current == 0
00340 || head->indx == indx)
00341 return head->current;
00342
00343 if (head->indx > indx)
00344 for (element = head->current;
00345 element->prev != 0 && element->indx > indx;
00346 element = element->prev)
00347 ;
00348
00349 else
00350 for (element = head->current;
00351 element->next != 0 && element->indx < indx;
00352 element = element->next)
00353 ;
00354
00355
00356
00357 head->current = element;
00358 head->indx = element->indx;
00359 if (element != 0 && element->indx != indx)
00360 element = 0;
00361
00362 return element;
00363 }
00364
00365
00366
00367 void
00368 bitmap_clear_bit (head, bit)
00369 bitmap head;
00370 int bit;
00371 {
00372 bitmap_element *ptr = bitmap_find_bit (head, bit);
00373
00374 if (ptr != 0)
00375 {
00376 unsigned bit_num = bit % BITMAP_WORD_BITS;
00377 unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
00378 ptr->bits[word_num] &= ~ (((BITMAP_WORD) 1) << bit_num);
00379
00380
00381 if (bitmap_element_zerop (ptr))
00382 bitmap_element_free (head, ptr);
00383 }
00384 }
00385
00386
00387
00388 void
00389 bitmap_set_bit (head, bit)
00390 bitmap head;
00391 int bit;
00392 {
00393 bitmap_element *ptr = bitmap_find_bit (head, bit);
00394 unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
00395 unsigned bit_num = bit % BITMAP_WORD_BITS;
00396 BITMAP_WORD bit_val = ((BITMAP_WORD) 1) << bit_num;
00397
00398 if (ptr == 0)
00399 {
00400 ptr = bitmap_element_allocate (head);
00401 ptr->indx = bit / BITMAP_ELEMENT_ALL_BITS;
00402 ptr->bits[word_num] = bit_val;
00403 bitmap_element_link (head, ptr);
00404 }
00405 else
00406 ptr->bits[word_num] |= bit_val;
00407 }
00408
00409
00410
00411 int
00412 bitmap_bit_p (head, bit)
00413 bitmap head;
00414 int bit;
00415 {
00416 bitmap_element *ptr;
00417 unsigned bit_num;
00418 unsigned word_num;
00419
00420 ptr = bitmap_find_bit (head, bit);
00421 if (ptr == 0)
00422 return 0;
00423
00424 bit_num = bit % BITMAP_WORD_BITS;
00425 word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
00426
00427 return (ptr->bits[word_num] >> bit_num) & 1;
00428 }
00429
00430
00431
00432
00433 int
00434 bitmap_first_set_bit (a)
00435 bitmap a;
00436 {
00437 bitmap_element *ptr = a->first;
00438 BITMAP_WORD word;
00439 unsigned word_num, bit_num;
00440
00441 if (ptr == NULL)
00442 return -1;
00443
00444 #if BITMAP_ELEMENT_WORDS == 2
00445 word_num = 0, word = ptr->bits[0];
00446 if (word == 0)
00447 word_num = 1, word = ptr->bits[1];
00448 #else
00449 for (word_num = 0; word_num < BITMAP_ELEMENT_WORDS; ++word_num)
00450 if ((word = ptr->bits[word_num]) != 0)
00451 break;
00452 #endif
00453
00454
00455
00456
00457 bit_num = 0;
00458 word = word & -word;
00459
00460 #if nBITMAP_WORD_BITS > 64
00461 #error "Fill out the table."
00462 #endif
00463 #if nBITMAP_WORD_BITS > 32
00464 if ((word & 0xffffffff) == 0)
00465 word >>= 32, bit_num += 32;
00466 #endif
00467 if ((word & 0xffff) == 0)
00468 word >>= 16, bit_num += 16;
00469 if ((word & 0xff) == 0)
00470 word >>= 8, bit_num += 8;
00471 if (word & 0xf0)
00472 bit_num += 4;
00473 if (word & 0xcc)
00474 bit_num += 2;
00475 if (word & 0xaa)
00476 bit_num += 1;
00477
00478 return (ptr->indx * BITMAP_ELEMENT_ALL_BITS
00479 + word_num * BITMAP_WORD_BITS
00480 + bit_num);
00481 }
00482
00483
00484
00485
00486 int
00487 bitmap_last_set_bit (a)
00488 bitmap a;
00489 {
00490 bitmap_element *ptr = a->first;
00491 BITMAP_WORD word;
00492 unsigned word_num, bit_num;
00493
00494 if (ptr == NULL)
00495 return -1;
00496
00497 while (ptr->next != NULL)
00498 ptr = ptr->next;
00499
00500 #if BITMAP_ELEMENT_WORDS == 2
00501 word_num = 1, word = ptr->bits[1];
00502 if (word == 0)
00503 word_num = 0, word = ptr->bits[0];
00504 #else
00505 for (word_num = BITMAP_ELEMENT_WORDS; word_num-- > 0; )
00506 if ((word = ptr->bits[word_num]) != 0)
00507 break;
00508 #endif
00509
00510
00511
00512 bit_num = 0;
00513 #if nBITMAP_WORD_BITS > 64
00514 #error "Fill out the table."
00515 #endif
00516 #if nBITMAP_WORD_BITS > 32
00517 if (word & ~(BITMAP_WORD)0xffffffff)
00518 word >>= 32, bit_num += 32;
00519 #endif
00520 if (word & 0xffff0000)
00521 word >>= 16, bit_num += 16;
00522 if (word & 0xff00)
00523 word >>= 8, bit_num += 8;
00524 if (word & 0xf0)
00525 word >>= 4, bit_num += 4;
00526 if (word & 0xc)
00527 word >>= 2, bit_num += 2;
00528 if (word & 0x2)
00529 bit_num += 1;
00530
00531 return (ptr->indx * BITMAP_ELEMENT_ALL_BITS
00532 + word_num * BITMAP_WORD_BITS
00533 + bit_num);
00534 }
00535
00536
00537
00538
00539 int
00540 bitmap_operation (to, from1, from2, operation)
00541 bitmap to;
00542 bitmap from1;
00543 bitmap from2;
00544 enum bitmap_bits operation;
00545 {
00546 #define HIGHEST_INDEX (unsigned int) ~0
00547
00548 bitmap_element *from1_ptr = from1->first;
00549 bitmap_element *from2_ptr = from2->first;
00550 unsigned int indx1 = (from1_ptr) ? from1_ptr->indx : HIGHEST_INDEX;
00551 unsigned int indx2 = (from2_ptr) ? from2_ptr->indx : HIGHEST_INDEX;
00552 bitmap_element *to_ptr = to->first;
00553 bitmap_element *from1_tmp;
00554 bitmap_element *from2_tmp;
00555 bitmap_element *to_tmp;
00556 unsigned int indx;
00557 int changed = 0;
00558
00559 #if BITMAP_ELEMENT_WORDS == 2
00560 #define DOIT(OP) \
00561 do { \
00562 BITMAP_WORD t0, t1, f10, f11, f20, f21; \
00563 f10 = from1_tmp->bits[0]; \
00564 f20 = from2_tmp->bits[0]; \
00565 t0 = f10 OP f20; \
00566 changed |= (t0 != to_tmp->bits[0]); \
00567 f11 = from1_tmp->bits[1]; \
00568 f21 = from2_tmp->bits[1]; \
00569 t1 = f11 OP f21; \
00570 changed |= (t1 != to_tmp->bits[1]); \
00571 to_tmp->bits[0] = t0; \
00572 to_tmp->bits[1] = t1; \
00573 } while (0)
00574 #else
00575 #define DOIT(OP) \
00576 do { \
00577 BITMAP_WORD t, f1, f2; \
00578 int i; \
00579 for (i = 0; i < BITMAP_ELEMENT_WORDS; ++i) \
00580 { \
00581 f1 = from1_tmp->bits[i]; \
00582 f2 = from2_tmp->bits[i]; \
00583 t = f1 OP f2; \
00584 changed |= (t != to_tmp->bits[i]); \
00585 to_tmp->bits[i] = t; \
00586 } \
00587 } while (0)
00588 #endif
00589
00590 to->first = to->current = 0;
00591
00592 while (from1_ptr != 0 || from2_ptr != 0)
00593 {
00594
00595
00596 if (indx1 == indx2)
00597 {
00598 indx = indx1;
00599 from1_tmp = from1_ptr;
00600 from2_tmp = from2_ptr;
00601 from1_ptr = from1_ptr->next;
00602 indx1 = (from1_ptr) ? from1_ptr->indx : HIGHEST_INDEX;
00603 from2_ptr = from2_ptr->next;
00604 indx2 = (from2_ptr) ? from2_ptr->indx : HIGHEST_INDEX;
00605 }
00606 else if (indx1 < indx2)
00607 {
00608 indx = indx1;
00609 from1_tmp = from1_ptr;
00610 from2_tmp = &bitmap_zero_bits;
00611 from1_ptr = from1_ptr->next;
00612 indx1 = (from1_ptr) ? from1_ptr->indx : HIGHEST_INDEX;
00613 }
00614 else
00615 {
00616 indx = indx2;
00617 from1_tmp = &bitmap_zero_bits;
00618 from2_tmp = from2_ptr;
00619 from2_ptr = from2_ptr->next;
00620 indx2 = (from2_ptr) ? from2_ptr->indx : HIGHEST_INDEX;
00621 }
00622
00623
00624
00625 while (to_ptr && to_ptr->indx < indx)
00626 {
00627 changed = 1;
00628 to_tmp = to_ptr;
00629 to_ptr = to_ptr->next;
00630 bitmap_elem_to_freelist (to, to_tmp);
00631 }
00632 if (to_ptr && to_ptr->indx == indx)
00633 {
00634 to_tmp = to_ptr;
00635 to_ptr = to_ptr->next;
00636 }
00637 else
00638 to_tmp = bitmap_element_allocate (to);
00639
00640
00641
00642 switch (operation)
00643 {
00644 default:
00645 abort ();
00646
00647 case BITMAP_AND:
00648 DOIT (&);
00649 break;
00650
00651 case BITMAP_AND_COMPL:
00652 DOIT (&~);
00653 break;
00654
00655 case BITMAP_IOR:
00656 DOIT (|);
00657 break;
00658 case BITMAP_IOR_COMPL:
00659 DOIT (|~);
00660 break;
00661 case BITMAP_XOR:
00662 DOIT (^);
00663 break;
00664 }
00665
00666 if (! bitmap_element_zerop (to_tmp))
00667 {
00668 to_tmp->indx = indx;
00669 bitmap_element_link (to, to_tmp);
00670 }
00671 else
00672 {
00673 bitmap_elem_to_freelist (to, to_tmp);
00674 }
00675 }
00676
00677
00678 if (to_ptr)
00679 {
00680 changed = 1;
00681 for (to_tmp = to_ptr; to_tmp->next ; to_tmp = to_tmp->next)
00682 continue;
00683 if (to->using_obstack)
00684 {
00685 to_tmp->next = bitmap_free;
00686 bitmap_free = to_ptr;
00687 }
00688 else
00689 {
00690 to_tmp->next = bitmap_ggc_free;
00691 bitmap_ggc_free = to_ptr;
00692 }
00693 }
00694
00695 #undef DOIT
00696
00697 return changed;
00698 }
00699
00700
00701
00702 int
00703 bitmap_equal_p (a, b)
00704 bitmap a;
00705 bitmap b;
00706 {
00707 bitmap_head c;
00708 int ret;
00709
00710 memset (&c, 0, sizeof (c));
00711 ret = ! bitmap_operation (&c, a, b, BITMAP_XOR);
00712 bitmap_clear (&c);
00713
00714 return ret;
00715 }
00716
00717
00718
00719
00720 void
00721 bitmap_ior_and_compl (to, from1, from2)
00722 bitmap to;
00723 bitmap from1;
00724 bitmap from2;
00725 {
00726 bitmap_head tmp;
00727
00728 tmp.first = tmp.current = 0;
00729 tmp.using_obstack = 0;
00730
00731 bitmap_operation (&tmp, from1, from2, BITMAP_AND_COMPL);
00732 bitmap_operation (to, to, &tmp, BITMAP_IOR);
00733 bitmap_clear (&tmp);
00734 }
00735
00736 int
00737 bitmap_union_of_diff (dst, a, b, c)
00738 bitmap dst;
00739 bitmap a;
00740 bitmap b;
00741 bitmap c;
00742 {
00743 bitmap_head tmp;
00744 int changed;
00745
00746 tmp.first = tmp.current = 0;
00747 tmp.using_obstack = 0;
00748
00749 bitmap_operation (&tmp, b, c, BITMAP_AND_COMPL);
00750 changed = bitmap_operation (dst, &tmp, a, BITMAP_IOR);
00751 bitmap_clear (&tmp);
00752
00753 return changed;
00754 }
00755
00756
00757
00758 bitmap
00759 bitmap_initialize (head, using_obstack)
00760 bitmap head;
00761 int using_obstack;
00762 {
00763 if (head == NULL && ! using_obstack)
00764 head = ggc_alloc (sizeof (*head));
00765
00766 head->first = head->current = 0;
00767 head->using_obstack = using_obstack;
00768
00769 return head;
00770 }
00771
00772
00773
00774 void
00775 debug_bitmap_file (file, head)
00776 FILE *file;
00777 bitmap head;
00778 {
00779 bitmap_element *ptr;
00780
00781 fprintf (file, "\nfirst = ");
00782 fprintf (file, HOST_PTR_PRINTF, (PTR) head->first);
00783 fprintf (file, " current = ");
00784 fprintf (file, HOST_PTR_PRINTF, (PTR) head->current);
00785 fprintf (file, " indx = %u\n", head->indx);
00786
00787 for (ptr = head->first; ptr; ptr = ptr->next)
00788 {
00789 unsigned int i, j, col = 26;
00790
00791 fprintf (file, "\t");
00792 fprintf (file, HOST_PTR_PRINTF, (PTR) ptr);
00793 fprintf (file, " next = ");
00794 fprintf (file, HOST_PTR_PRINTF, (PTR) ptr->next);
00795 fprintf (file, " prev = ");
00796 fprintf (file, HOST_PTR_PRINTF, (PTR) ptr->prev);
00797 fprintf (file, " indx = %u\n\t\tbits = {", ptr->indx);
00798
00799 for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
00800 for (j = 0; j < BITMAP_WORD_BITS; j++)
00801 if ((ptr->bits[i] >> j) & 1)
00802 {
00803 if (col > 70)
00804 {
00805 fprintf (file, "\n\t\t\t");
00806 col = 24;
00807 }
00808
00809 fprintf (file, " %u", (ptr->indx * BITMAP_ELEMENT_ALL_BITS
00810 + i * BITMAP_WORD_BITS + j));
00811 col += 4;
00812 }
00813
00814 fprintf (file, " }\n");
00815 }
00816 }
00817
00818
00819
00820
00821 void
00822 debug_bitmap (head)
00823 bitmap head;
00824 {
00825 debug_bitmap_file (stdout, head);
00826 }
00827
00828
00829
00830
00831 void
00832 bitmap_print (file, head, prefix, suffix)
00833 FILE *file;
00834 bitmap head;
00835 const char *prefix;
00836 const char *suffix;
00837 {
00838 const char *comma = "";
00839 int i;
00840
00841 fputs (prefix, file);
00842 EXECUTE_IF_SET_IN_BITMAP (head, 0, i,
00843 {
00844 fprintf (file, "%s%d", comma, i);
00845 comma = ", ";
00846 });
00847 fputs (suffix, file);
00848 }
00849
00850 #include "gt-bitmap.h"