1 /* Functions to support general ended bitmaps.
2 Copyright (C) 1997-2024 Free Software Foundation, Inc.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it under
7 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
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
22 #include "coretypes.h"
26 /* Memory allocation statistics purpose instance. */
27 mem_alloc_description
<bitmap_usage
> bitmap_mem_desc
;
29 /* Static zero-initialized bitmap obstack used for default initialization
31 bitmap_obstack
bitmap_head::crashme
;
33 static bitmap_element
*bitmap_tree_listify_from (bitmap
, bitmap_element
*);
35 /* Register new bitmap. */
37 bitmap_register (bitmap b MEM_STAT_DECL
)
39 static unsigned alloc_descriptor_max_uid
= 1;
40 gcc_assert (b
->alloc_descriptor
== 0);
41 b
->alloc_descriptor
= alloc_descriptor_max_uid
++;
43 bitmap_mem_desc
.register_descriptor (b
->get_descriptor (), BITMAP_ORIGIN
,
44 false FINAL_PASS_MEM_STAT
);
47 /* Account the overhead. */
49 register_overhead (bitmap b
, size_t amount
)
51 unsigned *d
= b
->get_descriptor ();
52 if (bitmap_mem_desc
.contains_descriptor_for_instance (d
))
53 bitmap_mem_desc
.register_instance_overhead (amount
, d
);
56 /* Release the overhead. */
58 release_overhead (bitmap b
, size_t amount
, bool remove_from_map
)
60 unsigned *d
= b
->get_descriptor ();
61 if (bitmap_mem_desc
.contains_descriptor_for_instance (d
))
62 bitmap_mem_desc
.release_instance_overhead (d
, amount
, remove_from_map
);
67 bitmap_element bitmap_zero_bits
; /* An element of all zero bits. */
68 bitmap_obstack bitmap_default_obstack
; /* The default bitmap obstack. */
69 static int bitmap_default_obstack_depth
;
70 static GTY((deletable
)) bitmap_element
*bitmap_ggc_free
; /* Freelist of
74 /* Bitmap memory management. */
76 /* Add ELT to the appropriate freelist. */
78 bitmap_elem_to_freelist (bitmap head
, bitmap_element
*elt
)
80 bitmap_obstack
*bit_obstack
= head
->obstack
;
82 if (GATHER_STATISTICS
)
83 release_overhead (head
, sizeof (bitmap_element
), false);
89 elt
->prev
= bit_obstack
->elements
;
90 bit_obstack
->elements
= elt
;
94 elt
->prev
= bitmap_ggc_free
;
95 bitmap_ggc_free
= elt
;
99 /* Allocate a bitmap element. The bits are cleared, but nothing else is. */
101 static inline bitmap_element
*
102 bitmap_element_allocate (bitmap head
)
104 bitmap_element
*element
;
105 bitmap_obstack
*bit_obstack
= head
->obstack
;
109 element
= bit_obstack
->elements
;
112 /* Use up the inner list first before looking at the next
113 element of the outer list. */
116 bit_obstack
->elements
= element
->next
;
117 bit_obstack
->elements
->prev
= element
->prev
;
120 /* Inner list was just a singleton. */
121 bit_obstack
->elements
= element
->prev
;
123 element
= XOBNEW (&bit_obstack
->obstack
, bitmap_element
);
127 element
= bitmap_ggc_free
;
129 /* Use up the inner list first before looking at the next
130 element of the outer list. */
133 bitmap_ggc_free
= element
->next
;
134 bitmap_ggc_free
->prev
= element
->prev
;
137 /* Inner list was just a singleton. */
138 bitmap_ggc_free
= element
->prev
;
140 element
= ggc_alloc
<bitmap_element
> ();
143 if (GATHER_STATISTICS
)
144 register_overhead (head
, sizeof (bitmap_element
));
146 memset (element
->bits
, 0, sizeof (element
->bits
));
151 /* Remove ELT and all following elements from bitmap HEAD.
152 Put the released elements in the freelist for HEAD. */
155 bitmap_elt_clear_from (bitmap head
, bitmap_element
*elt
)
157 bitmap_element
*prev
;
158 bitmap_obstack
*bit_obstack
= head
->obstack
;
164 elt
= bitmap_tree_listify_from (head
, elt
);
166 if (GATHER_STATISTICS
)
169 for (prev
= elt
; prev
; prev
= prev
->next
)
171 release_overhead (head
, sizeof (bitmap_element
) * n
, false);
178 if (head
->current
->indx
> prev
->indx
)
180 head
->current
= prev
;
181 head
->indx
= prev
->indx
;
187 head
->current
= NULL
;
191 /* Put the entire list onto the freelist in one operation. */
194 elt
->prev
= bit_obstack
->elements
;
195 bit_obstack
->elements
= elt
;
199 elt
->prev
= bitmap_ggc_free
;
200 bitmap_ggc_free
= elt
;
204 /* Linked-list view of bitmaps.
206 In this representation, the bitmap elements form a double-linked list
207 with elements sorted by increasing index. */
209 /* Link the bitmap element into the current bitmap linked list. */
212 bitmap_list_link_element (bitmap head
, bitmap_element
*element
)
214 unsigned int indx
= element
->indx
;
217 gcc_checking_assert (!head
->tree_form
);
219 /* If this is the first and only element, set it in. */
220 if (head
->first
== 0)
222 element
->next
= element
->prev
= 0;
223 head
->first
= element
;
226 /* If this index is less than that of the current element, it goes someplace
227 before the current element. */
228 else if (indx
< head
->indx
)
230 for (ptr
= head
->current
;
231 ptr
->prev
!= 0 && ptr
->prev
->indx
> indx
;
236 ptr
->prev
->next
= element
;
238 head
->first
= element
;
240 element
->prev
= ptr
->prev
;
245 /* Otherwise, it must go someplace after the current element. */
248 for (ptr
= head
->current
;
249 ptr
->next
!= 0 && ptr
->next
->indx
< indx
;
254 ptr
->next
->prev
= element
;
256 element
->next
= ptr
->next
;
261 /* Set up so this is the first element searched. */
262 head
->current
= element
;
266 /* Unlink the bitmap element from the current bitmap linked list,
267 and return it to the freelist. */
270 bitmap_list_unlink_element (bitmap head
, bitmap_element
*element
,
271 bool to_freelist
= true)
273 bitmap_element
*next
= element
->next
;
274 bitmap_element
*prev
= element
->prev
;
276 gcc_checking_assert (!head
->tree_form
);
284 if (head
->first
== element
)
287 /* Since the first thing we try is to insert before current,
288 make current the next entry in preference to the previous. */
289 if (head
->current
== element
)
291 head
->current
= next
!= 0 ? next
: prev
;
293 head
->indx
= head
->current
->indx
;
299 bitmap_elem_to_freelist (head
, element
);
302 /* Insert a new uninitialized element (or NODE if not NULL) into bitmap
303 HEAD after element ELT. If ELT is NULL, insert the element at the start.
304 Return the new element. */
306 static bitmap_element
*
307 bitmap_list_insert_element_after (bitmap head
,
308 bitmap_element
*elt
, unsigned int indx
,
309 bitmap_element
*node
= NULL
)
312 node
= bitmap_element_allocate (head
);
315 gcc_checking_assert (!head
->tree_form
);
321 head
->current
= node
;
324 node
->next
= head
->first
;
326 node
->next
->prev
= node
;
332 gcc_checking_assert (head
->current
);
333 node
->next
= elt
->next
;
335 node
->next
->prev
= node
;
342 /* Return the element for INDX, or NULL if the element doesn't exist.
343 Update the `current' field even if we can't find an element that
344 would hold the bitmap's bit to make eventual allocation
347 static inline bitmap_element
*
348 bitmap_list_find_element (bitmap head
, unsigned int indx
)
350 bitmap_element
*element
;
352 if (head
->current
== NULL
353 || head
->indx
== indx
)
354 return head
->current
;
356 if (head
->current
== head
->first
357 && head
->first
->next
== NULL
)
360 /* Usage can be NULL due to allocated bitmaps for which we do not
361 call initialize function. */
362 bitmap_usage
*usage
= NULL
;
363 if (GATHER_STATISTICS
)
364 usage
= bitmap_mem_desc
.get_descriptor_for_instance (head
);
366 /* This bitmap has more than one element, and we're going to look
367 through the elements list. Count that as a search. */
368 if (GATHER_STATISTICS
&& usage
)
369 usage
->m_nsearches
++;
371 if (head
->indx
< indx
)
372 /* INDX is beyond head->indx. Search from head->current
374 for (element
= head
->current
;
375 element
->next
!= 0 && element
->indx
< indx
;
376 element
= element
->next
)
378 if (GATHER_STATISTICS
&& usage
)
379 usage
->m_search_iter
++;
382 else if (head
->indx
/ 2 < indx
)
383 /* INDX is less than head->indx and closer to head->indx than to
384 0. Search from head->current backward. */
385 for (element
= head
->current
;
386 element
->prev
!= 0 && element
->indx
> indx
;
387 element
= element
->prev
)
389 if (GATHER_STATISTICS
&& usage
)
390 usage
->m_search_iter
++;
394 /* INDX is less than head->indx and closer to 0 than to
395 head->indx. Search from head->first forward. */
396 for (element
= head
->first
;
397 element
->next
!= 0 && element
->indx
< indx
;
398 element
= element
->next
)
400 if (GATHER_STATISTICS
&& usage
)
401 usage
->m_search_iter
++;
404 /* `element' is the nearest to the one we want. If it's not the one we
405 want, the one we want doesn't exist. */
406 gcc_checking_assert (element
!= NULL
);
407 head
->current
= element
;
408 head
->indx
= element
->indx
;
409 if (element
->indx
!= indx
)
415 /* Splay-tree view of bitmaps.
417 This is an almost one-to-one the implementatin of the simple top-down
418 splay tree in Sleator and Tarjan's "Self-adjusting Binary Search Trees".
419 It is probably not the most efficient form of splay trees, but it should
420 be good enough to experiment with this idea of bitmaps-as-trees.
422 For all functions below, the variable or function argument "t" is a node
423 in the tree, and "e" is a temporary or new node in the tree. The rest
424 is sufficiently straigh-forward (and very well explained in the paper)
425 that comment would only clutter things. */
428 bitmap_tree_link_left (bitmap_element
* &t
, bitmap_element
* &l
)
436 bitmap_tree_link_right (bitmap_element
* &t
, bitmap_element
* &r
)
444 bitmap_tree_rotate_left (bitmap_element
* &t
)
446 bitmap_element
*e
= t
->next
;
447 t
->next
= t
->next
->prev
;
453 bitmap_tree_rotate_right (bitmap_element
* &t
)
455 bitmap_element
*e
= t
->prev
;
456 t
->prev
= t
->prev
->next
;
461 static bitmap_element
*
462 bitmap_tree_splay (bitmap head
, bitmap_element
*t
, unsigned int indx
)
464 bitmap_element N
, *l
, *r
;
469 bitmap_usage
*usage
= NULL
;
470 if (GATHER_STATISTICS
)
471 usage
= bitmap_mem_desc
.get_descriptor_for_instance (head
);
473 N
.prev
= N
.next
= NULL
;
476 while (indx
!= t
->indx
)
478 if (GATHER_STATISTICS
&& usage
)
479 usage
->m_search_iter
++;
483 if (t
->prev
!= NULL
&& indx
< t
->prev
->indx
)
484 bitmap_tree_rotate_right (t
);
487 bitmap_tree_link_right (t
, r
);
489 else if (indx
> t
->indx
)
491 if (t
->next
!= NULL
&& indx
> t
->next
->indx
)
492 bitmap_tree_rotate_left (t
);
495 bitmap_tree_link_left (t
, l
);
506 /* Link bitmap element E into the current bitmap splay tree. */
509 bitmap_tree_link_element (bitmap head
, bitmap_element
*e
)
511 if (head
->first
== NULL
)
512 e
->prev
= e
->next
= NULL
;
515 bitmap_element
*t
= bitmap_tree_splay (head
, head
->first
, e
->indx
);
516 if (e
->indx
< t
->indx
)
522 else if (e
->indx
> t
->indx
)
533 head
->indx
= e
->indx
;
536 /* Unlink bitmap element E from the current bitmap splay tree,
537 and return it to the freelist. */
540 bitmap_tree_unlink_element (bitmap head
, bitmap_element
*e
)
542 bitmap_element
*t
= bitmap_tree_splay (head
, head
->first
, e
->indx
);
544 gcc_checking_assert (t
== e
);
550 t
= bitmap_tree_splay (head
, e
->prev
, e
->indx
);
555 head
->indx
= (t
!= NULL
) ? t
->indx
: 0;
557 bitmap_elem_to_freelist (head
, e
);
560 /* Return the element for INDX, or NULL if the element doesn't exist. */
562 static inline bitmap_element
*
563 bitmap_tree_find_element (bitmap head
, unsigned int indx
)
565 if (head
->current
== NULL
566 || head
->indx
== indx
)
567 return head
->current
;
569 /* Usage can be NULL due to allocated bitmaps for which we do not
570 call initialize function. */
571 bitmap_usage
*usage
= NULL
;
572 if (GATHER_STATISTICS
)
573 usage
= bitmap_mem_desc
.get_descriptor_for_instance (head
);
575 /* This bitmap has more than one element, and we're going to look
576 through the elements list. Count that as a search. */
577 if (GATHER_STATISTICS
&& usage
)
578 usage
->m_nsearches
++;
580 bitmap_element
*element
= bitmap_tree_splay (head
, head
->first
, indx
);
581 gcc_checking_assert (element
!= NULL
);
582 head
->first
= element
;
583 head
->current
= element
;
584 head
->indx
= element
->indx
;
585 if (element
->indx
!= indx
)
590 /* Converting bitmap views from linked-list to tree and vice versa. */
592 /* Splice element E and all elements with a larger index from
593 bitmap HEAD, convert the spliced elements to the linked-list
594 view, and return the head of the list (which should be E again), */
596 static bitmap_element
*
597 bitmap_tree_listify_from (bitmap head
, bitmap_element
*e
)
599 bitmap_element
*t
, *erb
;
601 /* Detach the right branch from E (all elements with indx > E->indx),
602 and splay E to the root. */
605 t
= bitmap_tree_splay (head
, head
->first
, e
->indx
);
606 gcc_checking_assert (t
== e
);
608 /* Because E has no right branch, and we rotated it to the root,
609 the left branch is the new root. */
613 head
->indx
= (t
!= NULL
) ? t
->indx
: 0;
615 /* Detach the tree from E, and re-attach the right branch of E. */
619 /* The tree is now valid again. Now we need to "un-tree" E.
620 It is imperative that a non-recursive implementation is used
621 for this, because splay trees have a worst case depth of O(N)
622 for a tree with N nodes. A recursive implementation could
623 result in a stack overflow for a sufficiently large, unbalanced
626 auto_vec
<bitmap_element
*, 32> stack
;
627 auto_vec
<bitmap_element
*, 32> sorted_elements
;
628 bitmap_element
*n
= e
;
638 if (stack
.is_empty ())
642 sorted_elements
.safe_push (n
);
646 gcc_assert (sorted_elements
[0] == e
);
648 bitmap_element
*prev
= NULL
;
650 FOR_EACH_VEC_ELT (sorted_elements
, ix
, n
)
662 /* Convert bitmap HEAD from splay-tree view to linked-list view. */
665 bitmap_list_view (bitmap head
)
669 gcc_assert (head
->tree_form
);
675 bitmap_tree_rotate_right (ptr
);
677 head
->first
= bitmap_tree_listify_from (head
, ptr
);
680 head
->tree_form
= false;
683 head
->current
= head
->first
;
684 head
->indx
= head
->current
? head
->current
->indx
: 0;
688 /* Convert bitmap HEAD from linked-list view to splay-tree view.
689 This is simply a matter of dropping the prev or next pointers
690 and setting the tree_form flag. The tree will balance itself
691 if and when it is used. */
694 bitmap_tree_view (bitmap head
)
698 gcc_assert (! head
->tree_form
);
707 head
->tree_form
= true;
710 /* Clear a bitmap by freeing all its elements. */
713 bitmap_clear (bitmap head
)
715 if (head
->first
== NULL
)
719 bitmap_element
*e
, *t
;
720 for (e
= head
->first
; e
->prev
; e
= e
->prev
)
721 /* Loop to find the element with the smallest index. */ ;
722 t
= bitmap_tree_splay (head
, head
->first
, e
->indx
);
723 gcc_checking_assert (t
== e
);
726 bitmap_elt_clear_from (head
, head
->first
);
729 /* Initialize a bitmap obstack. If BIT_OBSTACK is NULL, initialize
730 the default bitmap obstack. */
733 bitmap_obstack_initialize (bitmap_obstack
*bit_obstack
)
737 if (bitmap_default_obstack_depth
++)
739 bit_obstack
= &bitmap_default_obstack
;
742 #if !defined(__GNUC__) || (__GNUC__ < 2)
743 #define __alignof__(type) 0
746 bit_obstack
->elements
= NULL
;
747 bit_obstack
->heads
= NULL
;
748 obstack_specify_allocation (&bit_obstack
->obstack
, OBSTACK_CHUNK_SIZE
,
749 __alignof__ (bitmap_element
),
754 /* Release the memory from a bitmap obstack. If BIT_OBSTACK is NULL,
755 release the default bitmap obstack. */
758 bitmap_obstack_release (bitmap_obstack
*bit_obstack
)
762 if (--bitmap_default_obstack_depth
)
764 gcc_assert (bitmap_default_obstack_depth
> 0);
767 bit_obstack
= &bitmap_default_obstack
;
770 bit_obstack
->elements
= NULL
;
771 bit_obstack
->heads
= NULL
;
772 obstack_free (&bit_obstack
->obstack
, NULL
);
775 /* Create a new bitmap on an obstack. If BIT_OBSTACK is NULL, create
776 it on the default bitmap obstack. */
779 bitmap_alloc (bitmap_obstack
*bit_obstack MEM_STAT_DECL
)
785 gcc_assert (bitmap_default_obstack_depth
> 0);
786 bit_obstack
= &bitmap_default_obstack
;
788 map
= bit_obstack
->heads
;
790 bit_obstack
->heads
= (class bitmap_head
*) map
->first
;
792 map
= XOBNEW (&bit_obstack
->obstack
, bitmap_head
);
793 bitmap_initialize (map
, bit_obstack PASS_MEM_STAT
);
795 if (GATHER_STATISTICS
)
796 register_overhead (map
, sizeof (bitmap_head
));
801 /* Create a new GCd bitmap. */
804 bitmap_gc_alloc (ALONE_MEM_STAT_DECL
)
808 map
= ggc_alloc
<bitmap_head
> ();
809 bitmap_initialize (map
, NULL PASS_MEM_STAT
);
811 if (GATHER_STATISTICS
)
812 register_overhead (map
, sizeof (bitmap_head
));
817 /* Release an obstack allocated bitmap. */
820 bitmap_obstack_free (bitmap map
)
825 map
->first
= (bitmap_element
*) map
->obstack
->heads
;
827 if (GATHER_STATISTICS
)
828 release_overhead (map
, sizeof (bitmap_head
), true);
830 map
->obstack
->heads
= map
;
835 /* Return nonzero if all bits in an element are zero. */
838 bitmap_element_zerop (const bitmap_element
*element
)
840 #if BITMAP_ELEMENT_WORDS == 2
841 return (element
->bits
[0] | element
->bits
[1]) == 0;
845 for (i
= 0; i
< BITMAP_ELEMENT_WORDS
; i
++)
846 if (element
->bits
[i
] != 0)
853 /* Copy a bitmap to another bitmap. */
856 bitmap_copy (bitmap to
, const_bitmap from
)
858 const bitmap_element
*from_ptr
;
859 bitmap_element
*to_ptr
= 0;
861 gcc_checking_assert (!to
->tree_form
&& !from
->tree_form
);
865 /* Copy elements in forward direction one at a time. */
866 for (from_ptr
= from
->first
; from_ptr
; from_ptr
= from_ptr
->next
)
868 bitmap_element
*to_elt
= bitmap_element_allocate (to
);
870 to_elt
->indx
= from_ptr
->indx
;
871 memcpy (to_elt
->bits
, from_ptr
->bits
, sizeof (to_elt
->bits
));
873 /* Here we have a special case of bitmap_list_link_element,
874 for the case where we know the links are being entered
878 to
->first
= to
->current
= to_elt
;
879 to
->indx
= from_ptr
->indx
;
880 to_elt
->next
= to_elt
->prev
= 0;
884 to_elt
->prev
= to_ptr
;
886 to_ptr
->next
= to_elt
;
893 /* Move a bitmap to another bitmap. */
896 bitmap_move (bitmap to
, bitmap from
)
898 gcc_assert (to
->obstack
== from
->obstack
);
903 if (GATHER_STATISTICS
)
905 for (bitmap_element
*e
= to
->first
; e
; e
= e
->next
)
906 sz
+= sizeof (bitmap_element
);
907 register_overhead (to
, sz
);
912 if (GATHER_STATISTICS
)
913 release_overhead (from
, sz
, false);
916 /* Clear a single bit in a bitmap. Return true if the bit changed. */
919 bitmap_clear_bit (bitmap head
, int bit
)
921 unsigned int indx
= bit
/ BITMAP_ELEMENT_ALL_BITS
;
924 if (!head
->tree_form
)
925 ptr
= bitmap_list_find_element (head
, indx
);
927 ptr
= bitmap_tree_find_element (head
, indx
);
930 unsigned bit_num
= bit
% BITMAP_WORD_BITS
;
931 unsigned word_num
= bit
/ BITMAP_WORD_BITS
% BITMAP_ELEMENT_WORDS
;
932 BITMAP_WORD bit_val
= ((BITMAP_WORD
) 1) << bit_num
;
933 bool res
= (ptr
->bits
[word_num
] & bit_val
) != 0;
936 ptr
->bits
[word_num
] &= ~bit_val
;
937 /* If we cleared the entire word, free up the element. */
938 if (!ptr
->bits
[word_num
]
939 && bitmap_element_zerop (ptr
))
941 if (!head
->tree_form
)
942 bitmap_list_unlink_element (head
, ptr
);
944 bitmap_tree_unlink_element (head
, ptr
);
954 /* Set a single bit in a bitmap. Return true if the bit changed. */
957 bitmap_set_bit (bitmap head
, int bit
)
959 unsigned indx
= bit
/ BITMAP_ELEMENT_ALL_BITS
;
961 if (!head
->tree_form
)
962 ptr
= bitmap_list_find_element (head
, indx
);
964 ptr
= bitmap_tree_find_element (head
, indx
);
965 unsigned word_num
= bit
/ BITMAP_WORD_BITS
% BITMAP_ELEMENT_WORDS
;
966 unsigned bit_num
= bit
% BITMAP_WORD_BITS
;
967 BITMAP_WORD bit_val
= ((BITMAP_WORD
) 1) << bit_num
;
971 bool res
= (ptr
->bits
[word_num
] & bit_val
) == 0;
973 ptr
->bits
[word_num
] |= bit_val
;
977 ptr
= bitmap_element_allocate (head
);
978 ptr
->indx
= bit
/ BITMAP_ELEMENT_ALL_BITS
;
979 ptr
->bits
[word_num
] = bit_val
;
980 if (!head
->tree_form
)
981 bitmap_list_link_element (head
, ptr
);
983 bitmap_tree_link_element (head
, ptr
);
987 /* Return whether a bit is set within a bitmap. */
990 bitmap_bit_p (const_bitmap head
, int bit
)
992 unsigned int indx
= bit
/ BITMAP_ELEMENT_ALL_BITS
;
993 const bitmap_element
*ptr
;
997 if (!head
->tree_form
)
998 ptr
= bitmap_list_find_element (const_cast<bitmap
> (head
), indx
);
1000 ptr
= bitmap_tree_find_element (const_cast<bitmap
> (head
), indx
);
1004 bit_num
= bit
% BITMAP_WORD_BITS
;
1005 word_num
= bit
/ BITMAP_WORD_BITS
% BITMAP_ELEMENT_WORDS
;
1007 return (ptr
->bits
[word_num
] >> bit_num
) & 1;
1010 /* Set CHUNK_SIZE bits at a time in bitmap HEAD.
1011 Store CHUNK_VALUE starting at bits CHUNK * chunk_size.
1012 This is the set routine for viewing bitmap as a multi-bit sparse array. */
1015 bitmap_set_aligned_chunk (bitmap head
, unsigned int chunk
,
1016 unsigned int chunk_size
, BITMAP_WORD chunk_value
)
1018 // Ensure chunk size is a power of 2 and fits in BITMAP_WORD.
1019 gcc_checking_assert (pow2p_hwi (chunk_size
));
1020 gcc_checking_assert (chunk_size
< (sizeof (BITMAP_WORD
) * CHAR_BIT
));
1022 // Ensure chunk_value is within range of chunk_size bits.
1023 BITMAP_WORD max_value
= (1 << chunk_size
) - 1;
1024 gcc_checking_assert (chunk_value
<= max_value
);
1026 unsigned bit
= chunk
* chunk_size
;
1027 unsigned indx
= bit
/ BITMAP_ELEMENT_ALL_BITS
;
1028 bitmap_element
*ptr
;
1029 if (!head
->tree_form
)
1030 ptr
= bitmap_list_find_element (head
, indx
);
1032 ptr
= bitmap_tree_find_element (head
, indx
);
1033 unsigned word_num
= bit
/ BITMAP_WORD_BITS
% BITMAP_ELEMENT_WORDS
;
1034 unsigned bit_num
= bit
% BITMAP_WORD_BITS
;
1035 BITMAP_WORD bit_val
= chunk_value
<< bit_num
;
1036 BITMAP_WORD mask
= ~(max_value
<< bit_num
);
1040 ptr
->bits
[word_num
] &= mask
;
1041 ptr
->bits
[word_num
] |= bit_val
;
1045 ptr
= bitmap_element_allocate (head
);
1046 ptr
->indx
= bit
/ BITMAP_ELEMENT_ALL_BITS
;
1047 ptr
->bits
[word_num
] = bit_val
;
1048 if (!head
->tree_form
)
1049 bitmap_list_link_element (head
, ptr
);
1051 bitmap_tree_link_element (head
, ptr
);
1054 /* This is the get routine for viewing bitmap as a multi-bit sparse array.
1055 Return a set of CHUNK_SIZE consecutive bits from HEAD, starting at bit
1056 CHUNK * chunk_size. */
1059 bitmap_get_aligned_chunk (const_bitmap head
, unsigned int chunk
,
1060 unsigned int chunk_size
)
1062 // Ensure chunk size is a power of 2, fits in BITMAP_WORD and is in range.
1063 gcc_checking_assert (pow2p_hwi (chunk_size
));
1064 gcc_checking_assert (chunk_size
< (sizeof (BITMAP_WORD
) * CHAR_BIT
));
1066 BITMAP_WORD max_value
= (1 << chunk_size
) - 1;
1067 unsigned bit
= chunk
* chunk_size
;
1068 unsigned int indx
= bit
/ BITMAP_ELEMENT_ALL_BITS
;
1069 const bitmap_element
*ptr
;
1073 if (!head
->tree_form
)
1074 ptr
= bitmap_list_find_element (const_cast<bitmap
> (head
), indx
);
1076 ptr
= bitmap_tree_find_element (const_cast<bitmap
> (head
), indx
);
1080 bit_num
= bit
% BITMAP_WORD_BITS
;
1081 word_num
= bit
/ BITMAP_WORD_BITS
% BITMAP_ELEMENT_WORDS
;
1084 return (ptr
->bits
[word_num
] >> bit_num
) & max_value
;
1087 #if GCC_VERSION < 3400
1088 /* Table of number of set bits in a character, indexed by value of char. */
1089 static const unsigned char popcount_table
[] =
1091 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,
1092 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1093 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1094 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1095 1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,
1096 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1097 2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,
1098 3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8,
1101 static unsigned long
1102 bitmap_popcount (BITMAP_WORD a
)
1104 unsigned long ret
= 0;
1107 /* Just do this the table way for now */
1108 for (i
= 0; i
< BITMAP_WORD_BITS
; i
+= 8)
1109 ret
+= popcount_table
[(a
>> i
) & 0xff];
1114 /* Count and return the number of bits set in the bitmap word BITS. */
1115 static unsigned long
1116 bitmap_count_bits_in_word (const BITMAP_WORD
*bits
)
1118 unsigned long count
= 0;
1120 for (unsigned ix
= 0; ix
!= BITMAP_ELEMENT_WORDS
; ix
++)
1122 #if GCC_VERSION >= 3400
1123 /* Note that popcountl matches BITMAP_WORD in type, so the actual size
1124 of BITMAP_WORD is not material. */
1125 count
+= __builtin_popcountl (bits
[ix
]);
1127 count
+= bitmap_popcount (bits
[ix
]);
1133 /* Count the number of bits set in the bitmap, and return it. */
1136 bitmap_count_bits (const_bitmap a
)
1138 unsigned long count
= 0;
1139 const bitmap_element
*elt
;
1141 gcc_checking_assert (!a
->tree_form
);
1142 for (elt
= a
->first
; elt
; elt
= elt
->next
)
1143 count
+= bitmap_count_bits_in_word (elt
->bits
);
1148 /* Count the number of unique bits set in A and B and return it. */
1151 bitmap_count_unique_bits (const_bitmap a
, const_bitmap b
)
1153 unsigned long count
= 0;
1154 const bitmap_element
*elt_a
, *elt_b
;
1156 for (elt_a
= a
->first
, elt_b
= b
->first
; elt_a
&& elt_b
; )
1158 /* If we're at different indices, then count all the bits
1159 in the lower element. If we're at the same index, then
1160 count the bits in the IOR of the two elements. */
1161 if (elt_a
->indx
< elt_b
->indx
)
1163 count
+= bitmap_count_bits_in_word (elt_a
->bits
);
1164 elt_a
= elt_a
->next
;
1166 else if (elt_b
->indx
< elt_a
->indx
)
1168 count
+= bitmap_count_bits_in_word (elt_b
->bits
);
1169 elt_b
= elt_b
->next
;
1173 BITMAP_WORD bits
[BITMAP_ELEMENT_WORDS
];
1174 for (unsigned ix
= 0; ix
!= BITMAP_ELEMENT_WORDS
; ix
++)
1175 bits
[ix
] = elt_a
->bits
[ix
] | elt_b
->bits
[ix
];
1176 count
+= bitmap_count_bits_in_word (bits
);
1177 elt_a
= elt_a
->next
;
1178 elt_b
= elt_b
->next
;
1184 /* Return true if the bitmap has a single bit set. Otherwise return
1188 bitmap_single_bit_set_p (const_bitmap a
)
1190 unsigned long count
= 0;
1191 const bitmap_element
*elt
;
1194 if (bitmap_empty_p (a
))
1199 /* As there are no completely empty bitmap elements, a second one
1200 means we have more than one bit set. */
1201 if (elt
->next
!= NULL
1202 && (!a
->tree_form
|| elt
->prev
!= NULL
))
1205 for (ix
= 0; ix
!= BITMAP_ELEMENT_WORDS
; ix
++)
1207 #if GCC_VERSION >= 3400
1208 /* Note that popcountl matches BITMAP_WORD in type, so the actual size
1209 of BITMAP_WORD is not material. */
1210 count
+= __builtin_popcountl (elt
->bits
[ix
]);
1212 count
+= bitmap_popcount (elt
->bits
[ix
]);
1222 /* Return the bit number of the first set bit in the bitmap. The
1223 bitmap must be non-empty. When CLEAR is true it clears the bit. */
1226 bitmap_first_set_bit_worker (bitmap a
, bool clear
)
1228 bitmap_element
*elt
= a
->first
;
1233 gcc_checking_assert (elt
);
1239 bit_no
= elt
->indx
* BITMAP_ELEMENT_ALL_BITS
;
1240 for (ix
= 0; ix
!= BITMAP_ELEMENT_WORDS
; ix
++)
1242 word
= elt
->bits
[ix
];
1248 bit_no
+= ix
* BITMAP_WORD_BITS
;
1250 #if GCC_VERSION >= 3004
1251 gcc_assert (sizeof (long) == sizeof (word
));
1252 bit_no
+= __builtin_ctzl (word
);
1254 /* Binary search for the first set bit. */
1255 #if BITMAP_WORD_BITS > 64
1256 #error "Fill out the table."
1258 #if BITMAP_WORD_BITS > 32
1259 if (!(word
& 0xffffffff))
1260 word
>>= 32, bit_no
+= 32;
1262 if (!(word
& 0xffff))
1263 word
>>= 16, bit_no
+= 16;
1265 word
>>= 8, bit_no
+= 8;
1267 word
>>= 4, bit_no
+= 4;
1269 word
>>= 2, bit_no
+= 2;
1271 word
>>= 1, bit_no
+= 1;
1273 gcc_checking_assert (word
& 1);
1278 elt
->bits
[ix
] &= ~((BITMAP_WORD
) 1 << (bit_no
% BITMAP_WORD_BITS
));
1279 /* If we cleared the entire word, free up the element. */
1281 && bitmap_element_zerop (elt
))
1284 bitmap_list_unlink_element (a
, elt
);
1286 bitmap_tree_unlink_element (a
, elt
);
1293 /* Return the bit number of the first set bit in the bitmap. The
1294 bitmap must be non-empty. */
1297 bitmap_first_set_bit (const_bitmap a
)
1299 return bitmap_first_set_bit_worker (const_cast<bitmap
> (a
), false);
1302 /* Return and clear the bit number of the first set bit in the bitmap. The
1303 bitmap must be non-empty. */
1306 bitmap_clear_first_set_bit (bitmap a
)
1308 return bitmap_first_set_bit_worker (a
, true);
1311 /* Return the bit number of the first set bit in the bitmap. The
1312 bitmap must be non-empty. */
1315 bitmap_last_set_bit (const_bitmap a
)
1317 const bitmap_element
*elt
;
1325 elt
= a
->current
? a
->current
: a
->first
;
1326 gcc_checking_assert (elt
);
1331 bit_no
= elt
->indx
* BITMAP_ELEMENT_ALL_BITS
;
1332 for (ix
= BITMAP_ELEMENT_WORDS
- 1; ix
>= 1; ix
--)
1334 word
= elt
->bits
[ix
];
1338 gcc_assert (elt
->bits
[ix
] != 0);
1340 bit_no
+= ix
* BITMAP_WORD_BITS
;
1341 #if GCC_VERSION >= 3004
1342 gcc_assert (sizeof (long) == sizeof (word
));
1343 bit_no
+= BITMAP_WORD_BITS
- __builtin_clzl (word
) - 1;
1345 /* Hopefully this is a twos-complement host... */
1346 BITMAP_WORD x
= word
;
1352 #if BITMAP_WORD_BITS > 32
1355 bit_no
+= bitmap_popcount (x
) - 1;
1365 bitmap_and (bitmap dst
, const_bitmap a
, const_bitmap b
)
1367 bitmap_element
*dst_elt
= dst
->first
;
1368 const bitmap_element
*a_elt
= a
->first
;
1369 const bitmap_element
*b_elt
= b
->first
;
1370 bitmap_element
*dst_prev
= NULL
;
1372 gcc_checking_assert (!dst
->tree_form
&& !a
->tree_form
&& !b
->tree_form
);
1373 gcc_assert (dst
!= a
&& dst
!= b
);
1377 bitmap_copy (dst
, a
);
1381 while (a_elt
&& b_elt
)
1383 if (a_elt
->indx
< b_elt
->indx
)
1384 a_elt
= a_elt
->next
;
1385 else if (b_elt
->indx
< a_elt
->indx
)
1386 b_elt
= b_elt
->next
;
1389 /* Matching elts, generate A & B. */
1391 BITMAP_WORD ior
= 0;
1394 dst_elt
= bitmap_list_insert_element_after (dst
, dst_prev
,
1397 dst_elt
->indx
= a_elt
->indx
;
1398 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
1400 BITMAP_WORD r
= a_elt
->bits
[ix
] & b_elt
->bits
[ix
];
1402 dst_elt
->bits
[ix
] = r
;
1408 dst_elt
= dst_elt
->next
;
1410 a_elt
= a_elt
->next
;
1411 b_elt
= b_elt
->next
;
1414 /* Ensure that dst->current is valid. */
1415 dst
->current
= dst
->first
;
1416 bitmap_elt_clear_from (dst
, dst_elt
);
1417 gcc_checking_assert (!dst
->current
== !dst
->first
);
1419 dst
->indx
= dst
->current
->indx
;
1422 /* A &= B. Return true if A changed. */
1425 bitmap_and_into (bitmap a
, const_bitmap b
)
1427 bitmap_element
*a_elt
= a
->first
;
1428 const bitmap_element
*b_elt
= b
->first
;
1429 bitmap_element
*next
;
1430 bool changed
= false;
1432 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
);
1437 while (a_elt
&& b_elt
)
1439 if (a_elt
->indx
< b_elt
->indx
)
1442 bitmap_list_unlink_element (a
, a_elt
);
1446 else if (b_elt
->indx
< a_elt
->indx
)
1447 b_elt
= b_elt
->next
;
1450 /* Matching elts, generate A &= B. */
1452 BITMAP_WORD ior
= 0;
1454 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
1456 BITMAP_WORD r
= a_elt
->bits
[ix
] & b_elt
->bits
[ix
];
1457 if (a_elt
->bits
[ix
] != r
)
1459 a_elt
->bits
[ix
] = r
;
1464 bitmap_list_unlink_element (a
, a_elt
);
1466 b_elt
= b_elt
->next
;
1473 bitmap_elt_clear_from (a
, a_elt
);
1476 gcc_checking_assert (!a
->current
== !a
->first
1477 && (!a
->current
|| a
->indx
== a
->current
->indx
));
1483 /* Insert an element equal to SRC_ELT after DST_PREV, overwriting DST_ELT
1484 if non-NULL. CHANGED is true if the destination bitmap had already been
1485 changed; the new value of CHANGED is returned. */
1488 bitmap_elt_copy (bitmap dst
, bitmap_element
*dst_elt
, bitmap_element
*dst_prev
,
1489 const bitmap_element
*src_elt
, bool changed
)
1491 if (!changed
&& dst_elt
&& dst_elt
->indx
== src_elt
->indx
)
1495 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
1496 if (src_elt
->bits
[ix
] != dst_elt
->bits
[ix
])
1498 dst_elt
->bits
[ix
] = src_elt
->bits
[ix
];
1506 dst_elt
= bitmap_list_insert_element_after (dst
, dst_prev
,
1509 dst_elt
->indx
= src_elt
->indx
;
1510 memcpy (dst_elt
->bits
, src_elt
->bits
, sizeof (dst_elt
->bits
));
1520 bitmap_and_compl (bitmap dst
, const_bitmap a
, const_bitmap b
)
1522 bitmap_element
*dst_elt
= dst
->first
;
1523 const bitmap_element
*a_elt
= a
->first
;
1524 const bitmap_element
*b_elt
= b
->first
;
1525 bitmap_element
*dst_prev
= NULL
;
1526 bitmap_element
**dst_prev_pnext
= &dst
->first
;
1527 bool changed
= false;
1529 gcc_checking_assert (!dst
->tree_form
&& !a
->tree_form
&& !b
->tree_form
);
1530 gcc_assert (dst
!= a
&& dst
!= b
);
1534 changed
= !bitmap_empty_p (dst
);
1541 while (b_elt
&& b_elt
->indx
< a_elt
->indx
)
1542 b_elt
= b_elt
->next
;
1544 if (!b_elt
|| b_elt
->indx
> a_elt
->indx
)
1546 changed
= bitmap_elt_copy (dst
, dst_elt
, dst_prev
, a_elt
, changed
);
1547 dst_prev
= *dst_prev_pnext
;
1548 dst_prev_pnext
= &dst_prev
->next
;
1549 dst_elt
= *dst_prev_pnext
;
1550 a_elt
= a_elt
->next
;
1555 /* Matching elts, generate A & ~B. */
1557 BITMAP_WORD ior
= 0;
1559 if (!changed
&& dst_elt
&& dst_elt
->indx
== a_elt
->indx
)
1561 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
1563 BITMAP_WORD r
= a_elt
->bits
[ix
] & ~b_elt
->bits
[ix
];
1565 if (dst_elt
->bits
[ix
] != r
)
1568 dst_elt
->bits
[ix
] = r
;
1576 if (!dst_elt
|| dst_elt
->indx
> a_elt
->indx
)
1578 dst_elt
= bitmap_list_insert_element_after (dst
, dst_prev
,
1584 dst_elt
->indx
= a_elt
->indx
;
1585 new_element
= false;
1588 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
1590 BITMAP_WORD r
= a_elt
->bits
[ix
] & ~b_elt
->bits
[ix
];
1592 dst_elt
->bits
[ix
] = r
;
1600 changed
|= !new_element
;
1601 bitmap_list_unlink_element (dst
, dst_elt
);
1602 dst_elt
= *dst_prev_pnext
;
1608 dst_prev
= *dst_prev_pnext
;
1609 dst_prev_pnext
= &dst_prev
->next
;
1610 dst_elt
= *dst_prev_pnext
;
1612 a_elt
= a_elt
->next
;
1613 b_elt
= b_elt
->next
;
1617 /* Ensure that dst->current is valid. */
1618 dst
->current
= dst
->first
;
1623 bitmap_elt_clear_from (dst
, dst_elt
);
1625 gcc_checking_assert (!dst
->current
== !dst
->first
);
1627 dst
->indx
= dst
->current
->indx
;
1632 /* A &= ~B. Returns true if A changes */
1635 bitmap_and_compl_into (bitmap a
, const_bitmap b
)
1637 bitmap_element
*a_elt
= a
->first
;
1638 const bitmap_element
*b_elt
= b
->first
;
1639 bitmap_element
*next
;
1640 BITMAP_WORD changed
= 0;
1642 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
);
1646 if (bitmap_empty_p (a
))
1655 while (a_elt
&& b_elt
)
1657 if (a_elt
->indx
< b_elt
->indx
)
1658 a_elt
= a_elt
->next
;
1659 else if (b_elt
->indx
< a_elt
->indx
)
1660 b_elt
= b_elt
->next
;
1663 /* Matching elts, generate A &= ~B. */
1665 BITMAP_WORD ior
= 0;
1667 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
1669 BITMAP_WORD cleared
= a_elt
->bits
[ix
] & b_elt
->bits
[ix
];
1670 BITMAP_WORD r
= a_elt
->bits
[ix
] ^ cleared
;
1672 a_elt
->bits
[ix
] = r
;
1678 bitmap_list_unlink_element (a
, a_elt
);
1680 b_elt
= b_elt
->next
;
1683 gcc_checking_assert (!a
->current
== !a
->first
1684 && (!a
->current
|| a
->indx
== a
->current
->indx
));
1685 return changed
!= 0;
1688 /* Set COUNT bits from START in HEAD. */
1690 bitmap_set_range (bitmap head
, unsigned int start
, unsigned int count
)
1692 unsigned int first_index
, end_bit_plus1
, last_index
;
1693 bitmap_element
*elt
, *elt_prev
;
1696 gcc_checking_assert (!head
->tree_form
);
1703 bitmap_set_bit (head
, start
);
1707 first_index
= start
/ BITMAP_ELEMENT_ALL_BITS
;
1708 end_bit_plus1
= start
+ count
;
1709 last_index
= (end_bit_plus1
- 1) / BITMAP_ELEMENT_ALL_BITS
;
1710 elt
= bitmap_list_find_element (head
, first_index
);
1712 /* If bitmap_list_find_element returns zero, the current is the closest block
1713 to the result. Otherwise, just use bitmap_element_allocate to
1714 ensure ELT is set; in the loop below, ELT == NULL means "insert
1715 at the end of the bitmap". */
1718 elt
= bitmap_element_allocate (head
);
1719 elt
->indx
= first_index
;
1720 bitmap_list_link_element (head
, elt
);
1723 gcc_checking_assert (elt
->indx
== first_index
);
1724 elt_prev
= elt
->prev
;
1725 for (i
= first_index
; i
<= last_index
; i
++)
1727 unsigned elt_start_bit
= i
* BITMAP_ELEMENT_ALL_BITS
;
1728 unsigned elt_end_bit_plus1
= elt_start_bit
+ BITMAP_ELEMENT_ALL_BITS
;
1730 unsigned int first_word_to_mod
;
1731 BITMAP_WORD first_mask
;
1732 unsigned int last_word_to_mod
;
1733 BITMAP_WORD last_mask
;
1736 if (!elt
|| elt
->indx
!= i
)
1737 elt
= bitmap_list_insert_element_after (head
, elt_prev
, i
);
1739 if (elt_start_bit
<= start
)
1741 /* The first bit to turn on is somewhere inside this
1743 first_word_to_mod
= (start
- elt_start_bit
) / BITMAP_WORD_BITS
;
1745 /* This mask should have 1s in all bits >= start position. */
1747 (((BITMAP_WORD
) 1) << ((start
% BITMAP_WORD_BITS
))) - 1;
1748 first_mask
= ~first_mask
;
1752 /* The first bit to turn on is below this start of this elt. */
1753 first_word_to_mod
= 0;
1754 first_mask
= ~(BITMAP_WORD
) 0;
1757 if (elt_end_bit_plus1
<= end_bit_plus1
)
1759 /* The last bit to turn on is beyond this elt. */
1760 last_word_to_mod
= BITMAP_ELEMENT_WORDS
- 1;
1761 last_mask
= ~(BITMAP_WORD
) 0;
1765 /* The last bit to turn on is inside to this elt. */
1767 (end_bit_plus1
- elt_start_bit
) / BITMAP_WORD_BITS
;
1769 /* The last mask should have 1s below the end bit. */
1771 (((BITMAP_WORD
) 1) << ((end_bit_plus1
% BITMAP_WORD_BITS
))) - 1;
1774 if (first_word_to_mod
== last_word_to_mod
)
1776 BITMAP_WORD mask
= first_mask
& last_mask
;
1777 elt
->bits
[first_word_to_mod
] |= mask
;
1781 elt
->bits
[first_word_to_mod
] |= first_mask
;
1782 if (BITMAP_ELEMENT_WORDS
> 2)
1783 for (ix
= first_word_to_mod
+ 1; ix
< last_word_to_mod
; ix
++)
1784 elt
->bits
[ix
] = ~(BITMAP_WORD
) 0;
1785 elt
->bits
[last_word_to_mod
] |= last_mask
;
1792 head
->current
= elt
? elt
: elt_prev
;
1793 head
->indx
= head
->current
->indx
;
1796 /* Clear COUNT bits from START in HEAD. */
1798 bitmap_clear_range (bitmap head
, unsigned int start
, unsigned int count
)
1800 unsigned int first_index
, end_bit_plus1
, last_index
;
1801 bitmap_element
*elt
;
1803 gcc_checking_assert (!head
->tree_form
);
1810 bitmap_clear_bit (head
, start
);
1814 first_index
= start
/ BITMAP_ELEMENT_ALL_BITS
;
1815 end_bit_plus1
= start
+ count
;
1816 last_index
= (end_bit_plus1
- 1) / BITMAP_ELEMENT_ALL_BITS
;
1817 elt
= bitmap_list_find_element (head
, first_index
);
1819 /* If bitmap_list_find_element returns zero, the current is the closest block
1820 to the result. If the current is less than first index, find the
1821 next one. Otherwise, just set elt to be current. */
1826 if (head
->indx
< first_index
)
1828 elt
= head
->current
->next
;
1833 elt
= head
->current
;
1839 while (elt
&& (elt
->indx
<= last_index
))
1841 bitmap_element
* next_elt
= elt
->next
;
1842 unsigned elt_start_bit
= (elt
->indx
) * BITMAP_ELEMENT_ALL_BITS
;
1843 unsigned elt_end_bit_plus1
= elt_start_bit
+ BITMAP_ELEMENT_ALL_BITS
;
1846 if (elt_start_bit
>= start
&& elt_end_bit_plus1
<= end_bit_plus1
)
1847 /* Get rid of the entire elt and go to the next one. */
1848 bitmap_list_unlink_element (head
, elt
);
1851 /* Going to have to knock out some bits in this elt. */
1852 unsigned int first_word_to_mod
;
1853 BITMAP_WORD first_mask
;
1854 unsigned int last_word_to_mod
;
1855 BITMAP_WORD last_mask
;
1859 if (elt_start_bit
<= start
)
1861 /* The first bit to turn off is somewhere inside this
1863 first_word_to_mod
= (start
- elt_start_bit
) / BITMAP_WORD_BITS
;
1865 /* This mask should have 1s in all bits >= start position. */
1867 (((BITMAP_WORD
) 1) << ((start
% BITMAP_WORD_BITS
))) - 1;
1868 first_mask
= ~first_mask
;
1872 /* The first bit to turn off is below this start of this elt. */
1873 first_word_to_mod
= 0;
1875 first_mask
= ~first_mask
;
1878 if (elt_end_bit_plus1
<= end_bit_plus1
)
1880 /* The last bit to turn off is beyond this elt. */
1881 last_word_to_mod
= BITMAP_ELEMENT_WORDS
- 1;
1883 last_mask
= ~last_mask
;
1887 /* The last bit to turn off is inside to this elt. */
1889 (end_bit_plus1
- elt_start_bit
) / BITMAP_WORD_BITS
;
1891 /* The last mask should have 1s below the end bit. */
1893 (((BITMAP_WORD
) 1) << (((end_bit_plus1
) % BITMAP_WORD_BITS
))) - 1;
1897 if (first_word_to_mod
== last_word_to_mod
)
1899 BITMAP_WORD mask
= first_mask
& last_mask
;
1900 elt
->bits
[first_word_to_mod
] &= ~mask
;
1904 elt
->bits
[first_word_to_mod
] &= ~first_mask
;
1905 if (BITMAP_ELEMENT_WORDS
> 2)
1906 for (i
= first_word_to_mod
+ 1; i
< last_word_to_mod
; i
++)
1908 elt
->bits
[last_word_to_mod
] &= ~last_mask
;
1910 for (i
= 0; i
< BITMAP_ELEMENT_WORDS
; i
++)
1916 /* Check to see if there are any bits left. */
1918 bitmap_list_unlink_element (head
, elt
);
1925 head
->current
= elt
;
1926 head
->indx
= head
->current
->indx
;
1933 bitmap_compl_and_into (bitmap a
, const_bitmap b
)
1935 bitmap_element
*a_elt
= a
->first
;
1936 const bitmap_element
*b_elt
= b
->first
;
1937 bitmap_element
*a_prev
= NULL
;
1938 bitmap_element
*next
;
1940 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
);
1941 gcc_assert (a
!= b
);
1943 if (bitmap_empty_p (a
))
1948 if (bitmap_empty_p (b
))
1954 while (a_elt
|| b_elt
)
1956 if (!b_elt
|| (a_elt
&& a_elt
->indx
< b_elt
->indx
))
1958 /* A is before B. Remove A */
1960 a_prev
= a_elt
->prev
;
1961 bitmap_list_unlink_element (a
, a_elt
);
1964 else if (!a_elt
|| b_elt
->indx
< a_elt
->indx
)
1966 /* B is before A. Copy B. */
1967 next
= bitmap_list_insert_element_after (a
, a_prev
, b_elt
->indx
);
1968 memcpy (next
->bits
, b_elt
->bits
, sizeof (next
->bits
));
1970 b_elt
= b_elt
->next
;
1974 /* Matching elts, generate A = ~A & B. */
1976 BITMAP_WORD ior
= 0;
1978 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
1980 BITMAP_WORD cleared
= a_elt
->bits
[ix
] & b_elt
->bits
[ix
];
1981 BITMAP_WORD r
= b_elt
->bits
[ix
] ^ cleared
;
1983 a_elt
->bits
[ix
] = r
;
1988 bitmap_list_unlink_element (a
, a_elt
);
1992 b_elt
= b_elt
->next
;
1995 gcc_checking_assert (!a
->current
== !a
->first
1996 && (!a
->current
|| a
->indx
== a
->current
->indx
));
2001 /* Insert an element corresponding to A_ELT | B_ELT after DST_PREV,
2002 overwriting DST_ELT if non-NULL. CHANGED is true if the destination bitmap
2003 had already been changed; the new value of CHANGED is returned. */
2006 bitmap_elt_ior (bitmap dst
, bitmap_element
*dst_elt
, bitmap_element
*dst_prev
,
2007 const bitmap_element
*a_elt
, const bitmap_element
*b_elt
,
2010 gcc_assert (a_elt
|| b_elt
);
2012 if (a_elt
&& b_elt
&& a_elt
->indx
== b_elt
->indx
)
2014 /* Matching elts, generate A | B. */
2017 if (!changed
&& dst_elt
&& dst_elt
->indx
== a_elt
->indx
)
2019 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
2021 BITMAP_WORD r
= a_elt
->bits
[ix
] | b_elt
->bits
[ix
];
2022 if (r
!= dst_elt
->bits
[ix
])
2024 dst_elt
->bits
[ix
] = r
;
2033 dst_elt
= bitmap_list_insert_element_after (dst
, dst_prev
,
2036 dst_elt
->indx
= a_elt
->indx
;
2037 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
2039 BITMAP_WORD r
= a_elt
->bits
[ix
] | b_elt
->bits
[ix
];
2040 dst_elt
->bits
[ix
] = r
;
2046 /* Copy a single element. */
2047 const bitmap_element
*src
;
2049 if (!b_elt
|| (a_elt
&& a_elt
->indx
< b_elt
->indx
))
2054 gcc_checking_assert (src
);
2055 changed
= bitmap_elt_copy (dst
, dst_elt
, dst_prev
, src
, changed
);
2061 /* DST = A | B. Return true if DST changes. */
2064 bitmap_ior (bitmap dst
, const_bitmap a
, const_bitmap b
)
2066 bitmap_element
*dst_elt
= dst
->first
;
2067 const bitmap_element
*a_elt
= a
->first
;
2068 const bitmap_element
*b_elt
= b
->first
;
2069 bitmap_element
*dst_prev
= NULL
;
2070 bitmap_element
**dst_prev_pnext
= &dst
->first
;
2071 bool changed
= false;
2073 gcc_checking_assert (!dst
->tree_form
&& !a
->tree_form
&& !b
->tree_form
);
2074 gcc_assert (dst
!= a
&& dst
!= b
);
2076 while (a_elt
|| b_elt
)
2078 changed
= bitmap_elt_ior (dst
, dst_elt
, dst_prev
, a_elt
, b_elt
, changed
);
2080 if (a_elt
&& b_elt
&& a_elt
->indx
== b_elt
->indx
)
2082 a_elt
= a_elt
->next
;
2083 b_elt
= b_elt
->next
;
2087 if (a_elt
&& (!b_elt
|| a_elt
->indx
<= b_elt
->indx
))
2088 a_elt
= a_elt
->next
;
2089 else if (b_elt
&& (!a_elt
|| b_elt
->indx
<= a_elt
->indx
))
2090 b_elt
= b_elt
->next
;
2093 dst_prev
= *dst_prev_pnext
;
2094 dst_prev_pnext
= &dst_prev
->next
;
2095 dst_elt
= *dst_prev_pnext
;
2101 /* Ensure that dst->current is valid. */
2102 dst
->current
= dst
->first
;
2103 bitmap_elt_clear_from (dst
, dst_elt
);
2105 gcc_checking_assert (!dst
->current
== !dst
->first
);
2107 dst
->indx
= dst
->current
->indx
;
2111 /* A |= B. Return true if A changes. */
2114 bitmap_ior_into (bitmap a
, const_bitmap b
)
2116 bitmap_element
*a_elt
= a
->first
;
2117 const bitmap_element
*b_elt
= b
->first
;
2118 bitmap_element
*a_prev
= NULL
;
2119 bitmap_element
**a_prev_pnext
= &a
->first
;
2120 bool changed
= false;
2122 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
);
2128 /* If A lags behind B, just advance it. */
2129 if (!a_elt
|| a_elt
->indx
== b_elt
->indx
)
2131 changed
= bitmap_elt_ior (a
, a_elt
, a_prev
, a_elt
, b_elt
, changed
);
2132 b_elt
= b_elt
->next
;
2134 else if (a_elt
->indx
> b_elt
->indx
)
2136 changed
= bitmap_elt_copy (a
, NULL
, a_prev
, b_elt
, changed
);
2137 b_elt
= b_elt
->next
;
2140 a_prev
= *a_prev_pnext
;
2141 a_prev_pnext
= &a_prev
->next
;
2142 a_elt
= *a_prev_pnext
;
2145 gcc_checking_assert (!a
->current
== !a
->first
);
2147 a
->indx
= a
->current
->indx
;
2151 /* A |= B. Return true if A changes. Free B (re-using its storage
2155 bitmap_ior_into_and_free (bitmap a
, bitmap
*b_
)
2158 bitmap_element
*a_elt
= a
->first
;
2159 bitmap_element
*b_elt
= b
->first
;
2160 bitmap_element
*a_prev
= NULL
;
2161 bitmap_element
**a_prev_pnext
= &a
->first
;
2162 bool changed
= false;
2164 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
);
2165 gcc_assert (a
->obstack
== b
->obstack
);
2171 /* If A lags behind B, just advance it. */
2172 if (!a_elt
|| a_elt
->indx
== b_elt
->indx
)
2174 changed
= bitmap_elt_ior (a
, a_elt
, a_prev
, a_elt
, b_elt
, changed
);
2175 b_elt
= b_elt
->next
;
2177 else if (a_elt
->indx
> b_elt
->indx
)
2179 bitmap_element
*b_elt_next
= b_elt
->next
;
2180 bitmap_list_unlink_element (b
, b_elt
, false);
2181 bitmap_list_insert_element_after (a
, a_prev
, b_elt
->indx
, b_elt
);
2185 a_prev
= *a_prev_pnext
;
2186 a_prev_pnext
= &a_prev
->next
;
2187 a_elt
= *a_prev_pnext
;
2190 gcc_checking_assert (!a
->current
== !a
->first
);
2192 a
->indx
= a
->current
->indx
;
2204 bitmap_xor (bitmap dst
, const_bitmap a
, const_bitmap b
)
2206 bitmap_element
*dst_elt
= dst
->first
;
2207 const bitmap_element
*a_elt
= a
->first
;
2208 const bitmap_element
*b_elt
= b
->first
;
2209 bitmap_element
*dst_prev
= NULL
;
2211 gcc_checking_assert (!dst
->tree_form
&& !a
->tree_form
&& !b
->tree_form
);
2212 gcc_assert (dst
!= a
&& dst
!= b
);
2220 while (a_elt
|| b_elt
)
2222 if (a_elt
&& b_elt
&& a_elt
->indx
== b_elt
->indx
)
2224 /* Matching elts, generate A ^ B. */
2226 BITMAP_WORD ior
= 0;
2229 dst_elt
= bitmap_list_insert_element_after (dst
, dst_prev
,
2232 dst_elt
->indx
= a_elt
->indx
;
2233 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
2235 BITMAP_WORD r
= a_elt
->bits
[ix
] ^ b_elt
->bits
[ix
];
2238 dst_elt
->bits
[ix
] = r
;
2240 a_elt
= a_elt
->next
;
2241 b_elt
= b_elt
->next
;
2245 dst_elt
= dst_elt
->next
;
2250 /* Copy a single element. */
2251 const bitmap_element
*src
;
2253 if (!b_elt
|| (a_elt
&& a_elt
->indx
< b_elt
->indx
))
2256 a_elt
= a_elt
->next
;
2261 b_elt
= b_elt
->next
;
2265 dst_elt
= bitmap_list_insert_element_after (dst
, dst_prev
,
2268 dst_elt
->indx
= src
->indx
;
2269 memcpy (dst_elt
->bits
, src
->bits
, sizeof (dst_elt
->bits
));
2271 dst_elt
= dst_elt
->next
;
2274 /* Ensure that dst->current is valid. */
2275 dst
->current
= dst
->first
;
2276 bitmap_elt_clear_from (dst
, dst_elt
);
2277 gcc_checking_assert (!dst
->current
== !dst
->first
);
2279 dst
->indx
= dst
->current
->indx
;
2285 bitmap_xor_into (bitmap a
, const_bitmap b
)
2287 bitmap_element
*a_elt
= a
->first
;
2288 const bitmap_element
*b_elt
= b
->first
;
2289 bitmap_element
*a_prev
= NULL
;
2291 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
);
2301 if (!a_elt
|| b_elt
->indx
< a_elt
->indx
)
2304 bitmap_element
*dst
= bitmap_list_insert_element_after (a
, a_prev
,
2306 memcpy (dst
->bits
, b_elt
->bits
, sizeof (dst
->bits
));
2308 b_elt
= b_elt
->next
;
2310 else if (a_elt
->indx
< b_elt
->indx
)
2313 a_elt
= a_elt
->next
;
2317 /* Matching elts, generate A ^= B. */
2319 BITMAP_WORD ior
= 0;
2320 bitmap_element
*next
= a_elt
->next
;
2322 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
2324 BITMAP_WORD r
= a_elt
->bits
[ix
] ^ b_elt
->bits
[ix
];
2327 a_elt
->bits
[ix
] = r
;
2329 b_elt
= b_elt
->next
;
2333 bitmap_list_unlink_element (a
, a_elt
);
2337 gcc_checking_assert (!a
->current
== !a
->first
);
2339 a
->indx
= a
->current
->indx
;
2342 /* Return true if two bitmaps are identical.
2343 We do not bother with a check for pointer equality, as that never
2344 occurs in practice. */
2347 bitmap_equal_p (const_bitmap a
, const_bitmap b
)
2349 const bitmap_element
*a_elt
;
2350 const bitmap_element
*b_elt
;
2353 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
);
2355 for (a_elt
= a
->first
, b_elt
= b
->first
;
2357 a_elt
= a_elt
->next
, b_elt
= b_elt
->next
)
2359 if (a_elt
->indx
!= b_elt
->indx
)
2361 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
2362 if (a_elt
->bits
[ix
] != b_elt
->bits
[ix
])
2365 return !a_elt
&& !b_elt
;
2368 /* Return true if A AND B is not empty. */
2371 bitmap_intersect_p (const_bitmap a
, const_bitmap b
)
2373 const bitmap_element
*a_elt
;
2374 const bitmap_element
*b_elt
;
2377 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
);
2379 for (a_elt
= a
->first
, b_elt
= b
->first
;
2382 if (a_elt
->indx
< b_elt
->indx
)
2383 a_elt
= a_elt
->next
;
2384 else if (b_elt
->indx
< a_elt
->indx
)
2385 b_elt
= b_elt
->next
;
2388 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
2389 if (a_elt
->bits
[ix
] & b_elt
->bits
[ix
])
2391 a_elt
= a_elt
->next
;
2392 b_elt
= b_elt
->next
;
2398 /* Return true if A AND NOT B is not empty. */
2401 bitmap_intersect_compl_p (const_bitmap a
, const_bitmap b
)
2403 const bitmap_element
*a_elt
;
2404 const bitmap_element
*b_elt
;
2407 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
);
2409 for (a_elt
= a
->first
, b_elt
= b
->first
;
2412 if (a_elt
->indx
< b_elt
->indx
)
2414 else if (b_elt
->indx
< a_elt
->indx
)
2415 b_elt
= b_elt
->next
;
2418 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
2419 if (a_elt
->bits
[ix
] & ~b_elt
->bits
[ix
])
2421 a_elt
= a_elt
->next
;
2422 b_elt
= b_elt
->next
;
2425 return a_elt
!= NULL
;
2429 /* DST = A | (FROM1 & ~FROM2). Return true if DST changes. */
2432 bitmap_ior_and_compl (bitmap dst
, const_bitmap a
, const_bitmap b
, const_bitmap kill
)
2434 bool changed
= false;
2436 bitmap_element
*dst_elt
= dst
->first
;
2437 const bitmap_element
*a_elt
= a
->first
;
2438 const bitmap_element
*b_elt
= b
->first
;
2439 const bitmap_element
*kill_elt
= kill
->first
;
2440 bitmap_element
*dst_prev
= NULL
;
2441 bitmap_element
**dst_prev_pnext
= &dst
->first
;
2443 gcc_checking_assert (!dst
->tree_form
&& !a
->tree_form
&& !b
->tree_form
2444 && !kill
->tree_form
);
2445 gcc_assert (dst
!= a
&& dst
!= b
&& dst
!= kill
);
2447 /* Special cases. We don't bother checking for bitmap_equal_p (b, kill). */
2448 if (b
== kill
|| bitmap_empty_p (b
))
2450 changed
= !bitmap_equal_p (dst
, a
);
2452 bitmap_copy (dst
, a
);
2455 if (bitmap_empty_p (kill
))
2456 return bitmap_ior (dst
, a
, b
);
2457 if (bitmap_empty_p (a
))
2458 return bitmap_and_compl (dst
, b
, kill
);
2460 while (a_elt
|| b_elt
)
2462 bool new_element
= false;
2465 while (kill_elt
&& kill_elt
->indx
< b_elt
->indx
)
2466 kill_elt
= kill_elt
->next
;
2468 if (b_elt
&& kill_elt
&& kill_elt
->indx
== b_elt
->indx
2469 && (!a_elt
|| a_elt
->indx
>= b_elt
->indx
))
2471 bitmap_element tmp_elt
;
2474 BITMAP_WORD ior
= 0;
2475 tmp_elt
.indx
= b_elt
->indx
;
2476 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
2478 BITMAP_WORD r
= b_elt
->bits
[ix
] & ~kill_elt
->bits
[ix
];
2480 tmp_elt
.bits
[ix
] = r
;
2485 changed
= bitmap_elt_ior (dst
, dst_elt
, dst_prev
,
2486 a_elt
, &tmp_elt
, changed
);
2488 if (a_elt
&& a_elt
->indx
== b_elt
->indx
)
2489 a_elt
= a_elt
->next
;
2492 b_elt
= b_elt
->next
;
2493 kill_elt
= kill_elt
->next
;
2497 changed
= bitmap_elt_ior (dst
, dst_elt
, dst_prev
,
2498 a_elt
, b_elt
, changed
);
2501 if (a_elt
&& b_elt
&& a_elt
->indx
== b_elt
->indx
)
2503 a_elt
= a_elt
->next
;
2504 b_elt
= b_elt
->next
;
2508 if (a_elt
&& (!b_elt
|| a_elt
->indx
<= b_elt
->indx
))
2509 a_elt
= a_elt
->next
;
2510 else if (b_elt
&& (!a_elt
|| b_elt
->indx
<= a_elt
->indx
))
2511 b_elt
= b_elt
->next
;
2517 dst_prev
= *dst_prev_pnext
;
2518 dst_prev_pnext
= &dst_prev
->next
;
2519 dst_elt
= *dst_prev_pnext
;
2526 /* Ensure that dst->current is valid. */
2527 dst
->current
= dst
->first
;
2528 bitmap_elt_clear_from (dst
, dst_elt
);
2530 gcc_checking_assert (!dst
->current
== !dst
->first
);
2532 dst
->indx
= dst
->current
->indx
;
2537 /* A |= (B & ~C). Return true if A changes. */
2540 bitmap_ior_and_compl_into (bitmap a
, const_bitmap b
, const_bitmap c
)
2542 bitmap_element
*a_elt
= a
->first
;
2543 const bitmap_element
*b_elt
= b
->first
;
2544 const bitmap_element
*c_elt
= c
->first
;
2545 bitmap_element and_elt
;
2546 bitmap_element
*a_prev
= NULL
;
2547 bitmap_element
**a_prev_pnext
= &a
->first
;
2548 bool changed
= false;
2551 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
&& !c
->tree_form
);
2555 if (bitmap_empty_p (c
))
2556 return bitmap_ior_into (a
, b
);
2557 else if (bitmap_empty_p (a
))
2558 return bitmap_and_compl (a
, b
, c
);
2564 while (c_elt
&& c_elt
->indx
< b_elt
->indx
)
2565 c_elt
= c_elt
->next
;
2567 const bitmap_element
*and_elt_ptr
;
2568 if (c_elt
&& c_elt
->indx
== b_elt
->indx
)
2570 BITMAP_WORD overall
= 0;
2571 and_elt_ptr
= &and_elt
;
2572 and_elt
.indx
= b_elt
->indx
;
2573 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
2575 and_elt
.bits
[ix
] = b_elt
->bits
[ix
] & ~c_elt
->bits
[ix
];
2576 overall
|= and_elt
.bits
[ix
];
2580 b_elt
= b_elt
->next
;
2585 and_elt_ptr
= b_elt
;
2587 b_elt
= b_elt
->next
;
2589 /* Now find a place to insert AND_ELT. */
2592 ix
= a_elt
? a_elt
->indx
: and_elt_ptr
->indx
;
2593 if (ix
== and_elt_ptr
->indx
)
2594 changed
= bitmap_elt_ior (a
, a_elt
, a_prev
, a_elt
,
2595 and_elt_ptr
, changed
);
2596 else if (ix
> and_elt_ptr
->indx
)
2597 changed
= bitmap_elt_copy (a
, NULL
, a_prev
, and_elt_ptr
, changed
);
2599 a_prev
= *a_prev_pnext
;
2600 a_prev_pnext
= &a_prev
->next
;
2601 a_elt
= *a_prev_pnext
;
2603 /* If A lagged behind B/C, we advanced it so loop once more. */
2605 while (ix
< and_elt_ptr
->indx
);
2608 gcc_checking_assert (!a
->current
== !a
->first
);
2610 a
->indx
= a
->current
->indx
;
2614 /* A |= (B & C). Return true if A changes. */
2617 bitmap_ior_and_into (bitmap a
, const_bitmap b
, const_bitmap c
)
2619 bitmap_element
*a_elt
= a
->first
;
2620 const bitmap_element
*b_elt
= b
->first
;
2621 const bitmap_element
*c_elt
= c
->first
;
2622 bitmap_element and_elt
;
2623 bitmap_element
*a_prev
= NULL
;
2624 bitmap_element
**a_prev_pnext
= &a
->first
;
2625 bool changed
= false;
2628 gcc_checking_assert (!a
->tree_form
&& !b
->tree_form
&& !c
->tree_form
);
2631 return bitmap_ior_into (a
, b
);
2632 if (bitmap_empty_p (b
) || bitmap_empty_p (c
))
2636 while (b_elt
&& c_elt
)
2638 BITMAP_WORD overall
;
2640 /* Find a common item of B and C. */
2641 while (b_elt
->indx
!= c_elt
->indx
)
2643 if (b_elt
->indx
< c_elt
->indx
)
2645 b_elt
= b_elt
->next
;
2651 c_elt
= c_elt
->next
;
2658 and_elt
.indx
= b_elt
->indx
;
2659 for (ix
= 0; ix
< BITMAP_ELEMENT_WORDS
; ix
++)
2661 and_elt
.bits
[ix
] = b_elt
->bits
[ix
] & c_elt
->bits
[ix
];
2662 overall
|= and_elt
.bits
[ix
];
2665 b_elt
= b_elt
->next
;
2666 c_elt
= c_elt
->next
;
2670 /* Now find a place to insert AND_ELT. */
2673 ix
= a_elt
? a_elt
->indx
: and_elt
.indx
;
2674 if (ix
== and_elt
.indx
)
2675 changed
= bitmap_elt_ior (a
, a_elt
, a_prev
, a_elt
, &and_elt
, changed
);
2676 else if (ix
> and_elt
.indx
)
2677 changed
= bitmap_elt_copy (a
, NULL
, a_prev
, &and_elt
, changed
);
2679 a_prev
= *a_prev_pnext
;
2680 a_prev_pnext
= &a_prev
->next
;
2681 a_elt
= *a_prev_pnext
;
2683 /* If A lagged behind B/C, we advanced it so loop once more. */
2685 while (ix
< and_elt
.indx
);
2689 gcc_checking_assert (!a
->current
== !a
->first
);
2691 a
->indx
= a
->current
->indx
;
2695 /* Compute hash of bitmap (for purposes of hashing). */
2698 bitmap_hash (const_bitmap head
)
2700 const bitmap_element
*ptr
;
2701 BITMAP_WORD hash
= 0;
2704 gcc_checking_assert (!head
->tree_form
);
2706 for (ptr
= head
->first
; ptr
; ptr
= ptr
->next
)
2709 for (ix
= 0; ix
!= BITMAP_ELEMENT_WORDS
; ix
++)
2710 hash
^= ptr
->bits
[ix
];
2712 return iterative_hash (&hash
, sizeof (hash
), 0);
2716 /* Function to obtain a vector of bitmap elements in bit order from
2717 HEAD in tree view. */
2720 bitmap_tree_to_vec (vec
<bitmap_element
*> &elts
, const_bitmap head
)
2722 gcc_checking_assert (head
->tree_form
);
2723 auto_vec
<bitmap_element
*, 32> stack
;
2724 bitmap_element
*e
= head
->first
;
2729 stack
.safe_push (e
);
2732 if (stack
.is_empty ())
2741 /* Debugging function to print out the contents of a bitmap element. */
2744 debug_bitmap_elt_file (FILE *file
, const bitmap_element
*ptr
)
2746 unsigned int i
, j
, col
= 26;
2748 fprintf (file
, "\t" HOST_PTR_PRINTF
" next = " HOST_PTR_PRINTF
2749 " prev = " HOST_PTR_PRINTF
" indx = %u\n\t\tbits = {",
2750 (const void*) ptr
, (const void*) ptr
->next
,
2751 (const void*) ptr
->prev
, ptr
->indx
);
2753 for (i
= 0; i
< BITMAP_ELEMENT_WORDS
; i
++)
2754 for (j
= 0; j
< BITMAP_WORD_BITS
; j
++)
2755 if ((ptr
->bits
[i
] >> j
) & 1)
2759 fprintf (file
, "\n\t\t\t");
2763 fprintf (file
, " %u", (ptr
->indx
* BITMAP_ELEMENT_ALL_BITS
2764 + i
* BITMAP_WORD_BITS
+ j
));
2768 fprintf (file
, " }\n");
2771 /* Debugging function to print out the contents of a bitmap. */
2774 debug_bitmap_file (FILE *file
, const_bitmap head
)
2776 const bitmap_element
*ptr
;
2778 fprintf (file
, "\nfirst = " HOST_PTR_PRINTF
2779 " current = " HOST_PTR_PRINTF
" indx = %u\n",
2780 (void *) head
->first
, (void *) head
->current
, head
->indx
);
2782 if (head
->tree_form
)
2784 auto_vec
<bitmap_element
*, 32> elts
;
2785 bitmap_tree_to_vec (elts
, head
);
2786 for (unsigned i
= 0; i
< elts
.length (); ++i
)
2787 debug_bitmap_elt_file (file
, elts
[i
]);
2790 for (ptr
= head
->first
; ptr
; ptr
= ptr
->next
)
2791 debug_bitmap_elt_file (file
, ptr
);
2794 /* Function to be called from the debugger to print the contents
2798 debug_bitmap (const_bitmap head
)
2800 debug_bitmap_file (stderr
, head
);
2803 /* Function to print out the contents of a bitmap. Unlike debug_bitmap_file,
2804 it does not print anything but the bits. */
2807 bitmap_print (FILE *file
, const_bitmap head
, const char *prefix
,
2810 const char *comma
= "";
2813 fputs (prefix
, file
);
2814 if (head
->tree_form
)
2816 auto_vec
<bitmap_element
*, 32> elts
;
2817 bitmap_tree_to_vec (elts
, head
);
2818 for (i
= 0; i
< elts
.length (); ++i
)
2819 for (unsigned ix
= 0; ix
!= BITMAP_ELEMENT_WORDS
; ++ix
)
2821 BITMAP_WORD word
= elts
[i
]->bits
[ix
];
2822 for (unsigned bit
= 0; bit
!= BITMAP_WORD_BITS
; ++bit
)
2823 if (word
& ((BITMAP_WORD
)1 << bit
))
2825 fprintf (file
, "%s%d", comma
,
2826 (bit
+ BITMAP_WORD_BITS
* ix
2827 + elts
[i
]->indx
* BITMAP_ELEMENT_ALL_BITS
));
2835 EXECUTE_IF_SET_IN_BITMAP (head
, 0, i
, bi
)
2837 fprintf (file
, "%s%d", comma
, i
);
2841 fputs (suffix
, file
);
2844 /* Output per-bitmap memory usage statistics. */
2846 dump_bitmap_statistics (void)
2848 if (!GATHER_STATISTICS
)
2851 bitmap_mem_desc
.dump (BITMAP_ORIGIN
);
2855 debug (const bitmap_head
&ref
)
2857 dump_bitmap (stderr
, &ref
);
2861 debug (const bitmap_head
*ptr
)
2866 fprintf (stderr
, "<nil>\n");
2870 debug (const auto_bitmap
&ref
)
2872 debug ((const bitmap_head
&) ref
);
2876 debug (const auto_bitmap
*ptr
)
2878 debug ((const bitmap_head
*) ptr
);
2882 bitmap_head::dump ()
2889 namespace selftest
{
2891 /* Selftests for bitmaps. */
2893 /* Freshly-created bitmaps ought to be empty. */
2898 bitmap b
= bitmap_gc_alloc ();
2899 ASSERT_TRUE (bitmap_empty_p (b
));
2902 /* Verify bitmap_set_range. */
2907 bitmap b
= bitmap_gc_alloc ();
2908 ASSERT_TRUE (bitmap_empty_p (b
));
2910 bitmap_set_range (b
, 7, 5);
2911 ASSERT_FALSE (bitmap_empty_p (b
));
2912 ASSERT_EQ (5, bitmap_count_bits (b
));
2914 /* Verify bitmap_bit_p at the boundaries. */
2915 ASSERT_FALSE (bitmap_bit_p (b
, 6));
2916 ASSERT_TRUE (bitmap_bit_p (b
, 7));
2917 ASSERT_TRUE (bitmap_bit_p (b
, 11));
2918 ASSERT_FALSE (bitmap_bit_p (b
, 12));
2921 /* Verify splitting a range into two pieces using bitmap_clear_bit. */
2924 test_clear_bit_in_middle ()
2926 bitmap b
= bitmap_gc_alloc ();
2928 /* Set b to [100..200]. */
2929 bitmap_set_range (b
, 100, 100);
2930 ASSERT_EQ (100, bitmap_count_bits (b
));
2932 /* Clear a bit in the middle. */
2933 bool changed
= bitmap_clear_bit (b
, 150);
2934 ASSERT_TRUE (changed
);
2935 ASSERT_EQ (99, bitmap_count_bits (b
));
2936 ASSERT_TRUE (bitmap_bit_p (b
, 149));
2937 ASSERT_FALSE (bitmap_bit_p (b
, 150));
2938 ASSERT_TRUE (bitmap_bit_p (b
, 151));
2941 /* Verify bitmap_copy. */
2946 bitmap src
= bitmap_gc_alloc ();
2947 bitmap_set_range (src
, 40, 10);
2949 bitmap dst
= bitmap_gc_alloc ();
2950 ASSERT_FALSE (bitmap_equal_p (src
, dst
));
2951 bitmap_copy (dst
, src
);
2952 ASSERT_TRUE (bitmap_equal_p (src
, dst
));
2954 /* Verify that we can make them unequal again... */
2955 bitmap_set_range (src
, 70, 5);
2956 ASSERT_FALSE (bitmap_equal_p (src
, dst
));
2958 /* ...and that changing src after the copy didn't affect
2960 ASSERT_FALSE (bitmap_bit_p (dst
, 70));
2963 /* Verify bitmap_single_bit_set_p. */
2966 test_bitmap_single_bit_set_p ()
2968 bitmap b
= bitmap_gc_alloc ();
2970 ASSERT_FALSE (bitmap_single_bit_set_p (b
));
2972 bitmap_set_range (b
, 42, 1);
2973 ASSERT_TRUE (bitmap_single_bit_set_p (b
));
2974 ASSERT_EQ (42, bitmap_first_set_bit (b
));
2976 bitmap_set_range (b
, 1066, 1);
2977 ASSERT_FALSE (bitmap_single_bit_set_p (b
));
2978 ASSERT_EQ (42, bitmap_first_set_bit (b
));
2980 bitmap_clear_range (b
, 0, 100);
2981 ASSERT_TRUE (bitmap_single_bit_set_p (b
));
2982 ASSERT_EQ (1066, bitmap_first_set_bit (b
));
2985 /* Verify accessing aligned bit chunks works as expected. */
2988 test_aligned_chunk (unsigned num_bits
)
2990 bitmap b
= bitmap_gc_alloc ();
2991 int limit
= 2 ^ num_bits
;
2994 for (int x
= 0; x
< limit
; x
++)
2996 bitmap_set_aligned_chunk (b
, index
, num_bits
, (BITMAP_WORD
) x
);
2997 ASSERT_TRUE ((int) bitmap_get_aligned_chunk (b
, index
, num_bits
) == x
);
2998 ASSERT_TRUE ((int) bitmap_get_aligned_chunk (b
, index
+ 1,
3000 ASSERT_TRUE ((int) bitmap_get_aligned_chunk (b
, index
- 1,
3005 for (int x
= 0; x
< limit
; x
++)
3007 ASSERT_TRUE ((int) bitmap_get_aligned_chunk (b
, index
, num_bits
) == x
);
3012 /* Run all of the selftests within this file. */
3019 test_clear_bit_in_middle ();
3021 test_bitmap_single_bit_set_p ();
3022 /* Test 2, 4 and 8 bit aligned chunks. */
3023 test_aligned_chunk (2);
3024 test_aligned_chunk (4);
3025 test_aligned_chunk (8);
3028 } // namespace selftest
3029 #endif /* CHECKING_P */
3031 #include "gt-bitmap.h"