xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/bitmap.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Functions to support general ended bitmaps.
2*8feb0f0bSmrg    Copyright (C) 1997-2020 Free Software Foundation, Inc.
31debfc3dSmrg 
41debfc3dSmrg This file is part of GCC.
51debfc3dSmrg 
61debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
71debfc3dSmrg the terms of the GNU General Public License as published by the Free
81debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
91debfc3dSmrg version.
101debfc3dSmrg 
111debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
121debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
131debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
141debfc3dSmrg for more details.
151debfc3dSmrg 
161debfc3dSmrg You should have received a copy of the GNU General Public License
171debfc3dSmrg along with GCC; see the file COPYING3.  If not see
181debfc3dSmrg <http://www.gnu.org/licenses/>.  */
191debfc3dSmrg 
201debfc3dSmrg #include "config.h"
211debfc3dSmrg #include "system.h"
221debfc3dSmrg #include "coretypes.h"
231debfc3dSmrg #include "bitmap.h"
241debfc3dSmrg #include "selftest.h"
251debfc3dSmrg 
261debfc3dSmrg /* Memory allocation statistics purpose instance.  */
271debfc3dSmrg mem_alloc_description<bitmap_usage> bitmap_mem_desc;
281debfc3dSmrg 
29c0a68be4Smrg /* Static zero-initialized bitmap obstack used for default initialization
30c0a68be4Smrg    of bitmap_head.  */
31c0a68be4Smrg bitmap_obstack bitmap_head::crashme;
32c0a68be4Smrg 
33c0a68be4Smrg static bitmap_element *bitmap_tree_listify_from (bitmap, bitmap_element *);
34c0a68be4Smrg 
351debfc3dSmrg /* Register new bitmap.  */
361debfc3dSmrg void
bitmap_register(bitmap b MEM_STAT_DECL)371debfc3dSmrg bitmap_register (bitmap b MEM_STAT_DECL)
381debfc3dSmrg {
39*8feb0f0bSmrg   static unsigned alloc_descriptor_max_uid = 1;
40*8feb0f0bSmrg   gcc_assert (b->alloc_descriptor == 0);
41*8feb0f0bSmrg   b->alloc_descriptor = alloc_descriptor_max_uid++;
42*8feb0f0bSmrg 
43*8feb0f0bSmrg   bitmap_mem_desc.register_descriptor (b->get_descriptor (), BITMAP_ORIGIN,
44*8feb0f0bSmrg 				       false FINAL_PASS_MEM_STAT);
451debfc3dSmrg }
461debfc3dSmrg 
471debfc3dSmrg /* Account the overhead.  */
481debfc3dSmrg static void
register_overhead(bitmap b,size_t amount)491debfc3dSmrg register_overhead (bitmap b, size_t amount)
501debfc3dSmrg {
51*8feb0f0bSmrg   unsigned *d = b->get_descriptor ();
52*8feb0f0bSmrg   if (bitmap_mem_desc.contains_descriptor_for_instance (d))
53*8feb0f0bSmrg     bitmap_mem_desc.register_instance_overhead (amount, d);
541debfc3dSmrg }
551debfc3dSmrg 
56*8feb0f0bSmrg /* Release the overhead.  */
57*8feb0f0bSmrg static void
release_overhead(bitmap b,size_t amount,bool remove_from_map)58*8feb0f0bSmrg release_overhead (bitmap b, size_t amount, bool remove_from_map)
59*8feb0f0bSmrg {
60*8feb0f0bSmrg   unsigned *d = b->get_descriptor ();
61*8feb0f0bSmrg   if (bitmap_mem_desc.contains_descriptor_for_instance (d))
62*8feb0f0bSmrg     bitmap_mem_desc.release_instance_overhead (d, amount, remove_from_map);
63*8feb0f0bSmrg }
64*8feb0f0bSmrg 
65*8feb0f0bSmrg 
661debfc3dSmrg /* Global data */
671debfc3dSmrg bitmap_element bitmap_zero_bits;  /* An element of all zero bits.  */
681debfc3dSmrg bitmap_obstack bitmap_default_obstack;    /* The default bitmap obstack.  */
691debfc3dSmrg static int bitmap_default_obstack_depth;
701debfc3dSmrg static GTY((deletable)) bitmap_element *bitmap_ggc_free; /* Freelist of
711debfc3dSmrg 							    GC'd elements.  */
721debfc3dSmrg 
731debfc3dSmrg 
74c0a68be4Smrg /* Bitmap memory management.  */
751debfc3dSmrg 
76c0a68be4Smrg /* Add ELT to the appropriate freelist.  */
771debfc3dSmrg static inline void
bitmap_elem_to_freelist(bitmap head,bitmap_element * elt)781debfc3dSmrg bitmap_elem_to_freelist (bitmap head, bitmap_element *elt)
791debfc3dSmrg {
801debfc3dSmrg   bitmap_obstack *bit_obstack = head->obstack;
811debfc3dSmrg 
82c0a68be4Smrg   if (GATHER_STATISTICS)
83*8feb0f0bSmrg     release_overhead (head, sizeof (bitmap_element), false);
84c0a68be4Smrg 
851debfc3dSmrg   elt->next = NULL;
861debfc3dSmrg   elt->indx = -1;
871debfc3dSmrg   if (bit_obstack)
881debfc3dSmrg     {
891debfc3dSmrg       elt->prev = bit_obstack->elements;
901debfc3dSmrg       bit_obstack->elements = elt;
911debfc3dSmrg     }
921debfc3dSmrg   else
931debfc3dSmrg     {
941debfc3dSmrg       elt->prev = bitmap_ggc_free;
951debfc3dSmrg       bitmap_ggc_free = elt;
961debfc3dSmrg     }
971debfc3dSmrg }
981debfc3dSmrg 
991debfc3dSmrg /* Allocate a bitmap element.  The bits are cleared, but nothing else is.  */
1001debfc3dSmrg 
1011debfc3dSmrg static inline bitmap_element *
bitmap_element_allocate(bitmap head)1021debfc3dSmrg bitmap_element_allocate (bitmap head)
1031debfc3dSmrg {
1041debfc3dSmrg   bitmap_element *element;
1051debfc3dSmrg   bitmap_obstack *bit_obstack = head->obstack;
1061debfc3dSmrg 
1071debfc3dSmrg   if (bit_obstack)
1081debfc3dSmrg     {
1091debfc3dSmrg       element = bit_obstack->elements;
1101debfc3dSmrg 
1111debfc3dSmrg       if (element)
1121debfc3dSmrg 	/* Use up the inner list first before looking at the next
1131debfc3dSmrg 	   element of the outer list.  */
1141debfc3dSmrg 	if (element->next)
1151debfc3dSmrg 	  {
1161debfc3dSmrg 	    bit_obstack->elements = element->next;
1171debfc3dSmrg 	    bit_obstack->elements->prev = element->prev;
1181debfc3dSmrg 	  }
1191debfc3dSmrg 	else
1201debfc3dSmrg 	  /*  Inner list was just a singleton.  */
1211debfc3dSmrg 	  bit_obstack->elements = element->prev;
1221debfc3dSmrg       else
1231debfc3dSmrg 	element = XOBNEW (&bit_obstack->obstack, bitmap_element);
1241debfc3dSmrg     }
1251debfc3dSmrg   else
1261debfc3dSmrg     {
1271debfc3dSmrg       element = bitmap_ggc_free;
1281debfc3dSmrg       if (element)
1291debfc3dSmrg 	/* Use up the inner list first before looking at the next
1301debfc3dSmrg 	   element of the outer list.  */
1311debfc3dSmrg 	if (element->next)
1321debfc3dSmrg 	  {
1331debfc3dSmrg 	    bitmap_ggc_free = element->next;
1341debfc3dSmrg 	    bitmap_ggc_free->prev = element->prev;
1351debfc3dSmrg 	  }
1361debfc3dSmrg 	else
1371debfc3dSmrg 	  /*  Inner list was just a singleton.  */
1381debfc3dSmrg 	  bitmap_ggc_free = element->prev;
1391debfc3dSmrg       else
1401debfc3dSmrg 	element = ggc_alloc<bitmap_element> ();
1411debfc3dSmrg     }
1421debfc3dSmrg 
1431debfc3dSmrg   if (GATHER_STATISTICS)
1441debfc3dSmrg     register_overhead (head, sizeof (bitmap_element));
1451debfc3dSmrg 
1461debfc3dSmrg   memset (element->bits, 0, sizeof (element->bits));
1471debfc3dSmrg 
1481debfc3dSmrg   return element;
1491debfc3dSmrg }
1501debfc3dSmrg 
151c0a68be4Smrg /* Remove ELT and all following elements from bitmap HEAD.
152c0a68be4Smrg    Put the released elements in the freelist for HEAD.  */
1531debfc3dSmrg 
1541debfc3dSmrg void
bitmap_elt_clear_from(bitmap head,bitmap_element * elt)1551debfc3dSmrg bitmap_elt_clear_from (bitmap head, bitmap_element *elt)
1561debfc3dSmrg {
1571debfc3dSmrg   bitmap_element *prev;
1581debfc3dSmrg   bitmap_obstack *bit_obstack = head->obstack;
1591debfc3dSmrg 
160c0a68be4Smrg   if (!elt)
161c0a68be4Smrg     return;
162c0a68be4Smrg 
163c0a68be4Smrg   if (head->tree_form)
164c0a68be4Smrg     elt = bitmap_tree_listify_from (head, elt);
1651debfc3dSmrg 
1661debfc3dSmrg   if (GATHER_STATISTICS)
1671debfc3dSmrg     {
1681debfc3dSmrg       int n = 0;
1691debfc3dSmrg       for (prev = elt; prev; prev = prev->next)
1701debfc3dSmrg 	n++;
171*8feb0f0bSmrg       release_overhead (head, sizeof (bitmap_element) * n, false);
1721debfc3dSmrg     }
1731debfc3dSmrg 
1741debfc3dSmrg   prev = elt->prev;
1751debfc3dSmrg   if (prev)
1761debfc3dSmrg     {
1771debfc3dSmrg       prev->next = NULL;
1781debfc3dSmrg       if (head->current->indx > prev->indx)
1791debfc3dSmrg 	{
1801debfc3dSmrg 	  head->current = prev;
1811debfc3dSmrg 	  head->indx = prev->indx;
1821debfc3dSmrg 	}
1831debfc3dSmrg     }
1841debfc3dSmrg   else
1851debfc3dSmrg     {
1861debfc3dSmrg       head->first = NULL;
1871debfc3dSmrg       head->current = NULL;
1881debfc3dSmrg       head->indx = 0;
1891debfc3dSmrg     }
1901debfc3dSmrg 
1911debfc3dSmrg   /* Put the entire list onto the freelist in one operation. */
1921debfc3dSmrg   if (bit_obstack)
1931debfc3dSmrg     {
1941debfc3dSmrg       elt->prev = bit_obstack->elements;
1951debfc3dSmrg       bit_obstack->elements = elt;
1961debfc3dSmrg     }
1971debfc3dSmrg   else
1981debfc3dSmrg     {
1991debfc3dSmrg       elt->prev = bitmap_ggc_free;
2001debfc3dSmrg       bitmap_ggc_free = elt;
2011debfc3dSmrg     }
2021debfc3dSmrg }
203c0a68be4Smrg 
204c0a68be4Smrg /* Linked-list view of bitmaps.
2051debfc3dSmrg 
206c0a68be4Smrg    In this representation, the bitmap elements form a double-linked list
207c0a68be4Smrg    with elements sorted by increasing index.  */
208c0a68be4Smrg 
209c0a68be4Smrg /* Link the bitmap element into the current bitmap linked list.  */
210c0a68be4Smrg 
211c0a68be4Smrg static inline void
bitmap_list_link_element(bitmap head,bitmap_element * element)212c0a68be4Smrg bitmap_list_link_element (bitmap head, bitmap_element *element)
213c0a68be4Smrg {
214c0a68be4Smrg   unsigned int indx = element->indx;
215c0a68be4Smrg   bitmap_element *ptr;
216c0a68be4Smrg 
217c0a68be4Smrg   gcc_checking_assert (!head->tree_form);
218c0a68be4Smrg 
219c0a68be4Smrg   /* If this is the first and only element, set it in.  */
220c0a68be4Smrg   if (head->first == 0)
221c0a68be4Smrg     {
222c0a68be4Smrg       element->next = element->prev = 0;
223c0a68be4Smrg       head->first = element;
224c0a68be4Smrg     }
225c0a68be4Smrg 
226c0a68be4Smrg   /* If this index is less than that of the current element, it goes someplace
227c0a68be4Smrg      before the current element.  */
228c0a68be4Smrg   else if (indx < head->indx)
229c0a68be4Smrg     {
230c0a68be4Smrg       for (ptr = head->current;
231c0a68be4Smrg 	   ptr->prev != 0 && ptr->prev->indx > indx;
232c0a68be4Smrg 	   ptr = ptr->prev)
233c0a68be4Smrg 	;
234c0a68be4Smrg 
235c0a68be4Smrg       if (ptr->prev)
236c0a68be4Smrg 	ptr->prev->next = element;
237c0a68be4Smrg       else
238c0a68be4Smrg 	head->first = element;
239c0a68be4Smrg 
240c0a68be4Smrg       element->prev = ptr->prev;
241c0a68be4Smrg       element->next = ptr;
242c0a68be4Smrg       ptr->prev = element;
243c0a68be4Smrg     }
244c0a68be4Smrg 
245c0a68be4Smrg   /* Otherwise, it must go someplace after the current element.  */
246c0a68be4Smrg   else
247c0a68be4Smrg     {
248c0a68be4Smrg       for (ptr = head->current;
249c0a68be4Smrg 	   ptr->next != 0 && ptr->next->indx < indx;
250c0a68be4Smrg 	   ptr = ptr->next)
251c0a68be4Smrg 	;
252c0a68be4Smrg 
253c0a68be4Smrg       if (ptr->next)
254c0a68be4Smrg 	ptr->next->prev = element;
255c0a68be4Smrg 
256c0a68be4Smrg       element->next = ptr->next;
257c0a68be4Smrg       element->prev = ptr;
258c0a68be4Smrg       ptr->next = element;
259c0a68be4Smrg     }
260c0a68be4Smrg 
261c0a68be4Smrg   /* Set up so this is the first element searched.  */
262c0a68be4Smrg   head->current = element;
263c0a68be4Smrg   head->indx = indx;
264c0a68be4Smrg }
265c0a68be4Smrg 
266c0a68be4Smrg /* Unlink the bitmap element from the current bitmap linked list,
267c0a68be4Smrg    and return it to the freelist.  */
268c0a68be4Smrg 
269c0a68be4Smrg static inline void
270*8feb0f0bSmrg bitmap_list_unlink_element (bitmap head, bitmap_element *element,
271*8feb0f0bSmrg 			    bool to_freelist = true)
272c0a68be4Smrg {
273c0a68be4Smrg   bitmap_element *next = element->next;
274c0a68be4Smrg   bitmap_element *prev = element->prev;
275c0a68be4Smrg 
276c0a68be4Smrg   gcc_checking_assert (!head->tree_form);
277c0a68be4Smrg 
278c0a68be4Smrg   if (prev)
279c0a68be4Smrg     prev->next = next;
280c0a68be4Smrg 
281c0a68be4Smrg   if (next)
282c0a68be4Smrg     next->prev = prev;
283c0a68be4Smrg 
284c0a68be4Smrg   if (head->first == element)
285c0a68be4Smrg     head->first = next;
286c0a68be4Smrg 
287c0a68be4Smrg   /* Since the first thing we try is to insert before current,
288c0a68be4Smrg      make current the next entry in preference to the previous.  */
289c0a68be4Smrg   if (head->current == element)
290c0a68be4Smrg     {
291c0a68be4Smrg       head->current = next != 0 ? next : prev;
292c0a68be4Smrg       if (head->current)
293c0a68be4Smrg 	head->indx = head->current->indx;
294c0a68be4Smrg       else
295c0a68be4Smrg 	head->indx = 0;
296c0a68be4Smrg     }
297c0a68be4Smrg 
298*8feb0f0bSmrg   if (to_freelist)
299c0a68be4Smrg     bitmap_elem_to_freelist (head, element);
300c0a68be4Smrg }
301c0a68be4Smrg 
302*8feb0f0bSmrg /* Insert a new uninitialized element (or NODE if not NULL) into bitmap
303*8feb0f0bSmrg    HEAD after element ELT.  If ELT is NULL, insert the element at the start.
304*8feb0f0bSmrg    Return the new element.  */
305c0a68be4Smrg 
306c0a68be4Smrg static bitmap_element *
307c0a68be4Smrg bitmap_list_insert_element_after (bitmap head,
308*8feb0f0bSmrg 				  bitmap_element *elt, unsigned int indx,
309*8feb0f0bSmrg 				  bitmap_element *node = NULL)
310c0a68be4Smrg {
311*8feb0f0bSmrg   if (!node)
312*8feb0f0bSmrg     node = bitmap_element_allocate (head);
313c0a68be4Smrg   node->indx = indx;
314c0a68be4Smrg 
315c0a68be4Smrg   gcc_checking_assert (!head->tree_form);
316c0a68be4Smrg 
317c0a68be4Smrg   if (!elt)
318c0a68be4Smrg     {
319c0a68be4Smrg       if (!head->current)
320c0a68be4Smrg 	{
321c0a68be4Smrg 	  head->current = node;
322c0a68be4Smrg 	  head->indx = indx;
323c0a68be4Smrg 	}
324c0a68be4Smrg       node->next = head->first;
325c0a68be4Smrg       if (node->next)
326c0a68be4Smrg 	node->next->prev = node;
327c0a68be4Smrg       head->first = node;
328c0a68be4Smrg       node->prev = NULL;
329c0a68be4Smrg     }
330c0a68be4Smrg   else
331c0a68be4Smrg     {
332c0a68be4Smrg       gcc_checking_assert (head->current);
333c0a68be4Smrg       node->next = elt->next;
334c0a68be4Smrg       if (node->next)
335c0a68be4Smrg 	node->next->prev = node;
336c0a68be4Smrg       elt->next = node;
337c0a68be4Smrg       node->prev = elt;
338c0a68be4Smrg     }
339c0a68be4Smrg   return node;
340c0a68be4Smrg }
341c0a68be4Smrg 
342c0a68be4Smrg /* Return the element for INDX, or NULL if the element doesn't exist.
343c0a68be4Smrg    Update the `current' field even if we can't find an element that
344c0a68be4Smrg    would hold the bitmap's bit to make eventual allocation
345c0a68be4Smrg    faster.  */
346c0a68be4Smrg 
347c0a68be4Smrg static inline bitmap_element *
bitmap_list_find_element(bitmap head,unsigned int indx)348c0a68be4Smrg bitmap_list_find_element (bitmap head, unsigned int indx)
349c0a68be4Smrg {
350c0a68be4Smrg   bitmap_element *element;
351c0a68be4Smrg 
352c0a68be4Smrg   if (head->current == NULL
353c0a68be4Smrg       || head->indx == indx)
354c0a68be4Smrg     return head->current;
355c0a68be4Smrg 
356c0a68be4Smrg   if (head->current == head->first
357c0a68be4Smrg       && head->first->next == NULL)
358c0a68be4Smrg     return NULL;
359c0a68be4Smrg 
360c0a68be4Smrg   /* Usage can be NULL due to allocated bitmaps for which we do not
361c0a68be4Smrg      call initialize function.  */
362c0a68be4Smrg   bitmap_usage *usage = NULL;
363c0a68be4Smrg   if (GATHER_STATISTICS)
364c0a68be4Smrg     usage = bitmap_mem_desc.get_descriptor_for_instance (head);
365c0a68be4Smrg 
366c0a68be4Smrg   /* This bitmap has more than one element, and we're going to look
367c0a68be4Smrg      through the elements list.  Count that as a search.  */
368c0a68be4Smrg   if (GATHER_STATISTICS && usage)
369c0a68be4Smrg     usage->m_nsearches++;
370c0a68be4Smrg 
371c0a68be4Smrg   if (head->indx < indx)
372c0a68be4Smrg     /* INDX is beyond head->indx.  Search from head->current
373c0a68be4Smrg        forward.  */
374c0a68be4Smrg     for (element = head->current;
375c0a68be4Smrg 	 element->next != 0 && element->indx < indx;
376c0a68be4Smrg 	 element = element->next)
377c0a68be4Smrg       {
378c0a68be4Smrg 	if (GATHER_STATISTICS && usage)
379c0a68be4Smrg 	  usage->m_search_iter++;
380c0a68be4Smrg       }
381c0a68be4Smrg 
382c0a68be4Smrg   else if (head->indx / 2 < indx)
383c0a68be4Smrg     /* INDX is less than head->indx and closer to head->indx than to
384c0a68be4Smrg        0.  Search from head->current backward.  */
385c0a68be4Smrg     for (element = head->current;
386c0a68be4Smrg 	 element->prev != 0 && element->indx > indx;
387c0a68be4Smrg 	 element = element->prev)
388c0a68be4Smrg       {
389c0a68be4Smrg 	if (GATHER_STATISTICS && usage)
390c0a68be4Smrg 	  usage->m_search_iter++;
391c0a68be4Smrg       }
392c0a68be4Smrg 
393c0a68be4Smrg   else
394c0a68be4Smrg     /* INDX is less than head->indx and closer to 0 than to
395c0a68be4Smrg        head->indx.  Search from head->first forward.  */
396c0a68be4Smrg     for (element = head->first;
397c0a68be4Smrg 	 element->next != 0 && element->indx < indx;
398c0a68be4Smrg 	 element = element->next)
399c0a68be4Smrg       {
400c0a68be4Smrg 	if (GATHER_STATISTICS && usage)
401c0a68be4Smrg 	  usage->m_search_iter++;
402c0a68be4Smrg       }
403c0a68be4Smrg 
404c0a68be4Smrg   /* `element' is the nearest to the one we want.  If it's not the one we
405c0a68be4Smrg      want, the one we want doesn't exist.  */
406c0a68be4Smrg   gcc_checking_assert (element != NULL);
407c0a68be4Smrg   head->current = element;
408c0a68be4Smrg   head->indx = element->indx;
409c0a68be4Smrg   if (element->indx != indx)
410c0a68be4Smrg     element = 0;
411c0a68be4Smrg   return element;
412c0a68be4Smrg }
413c0a68be4Smrg 
414c0a68be4Smrg 
415c0a68be4Smrg /* Splay-tree view of bitmaps.
416c0a68be4Smrg 
417c0a68be4Smrg    This is an almost one-to-one the implementatin of the simple top-down
418c0a68be4Smrg    splay tree in Sleator and Tarjan's "Self-adjusting Binary Search Trees".
419c0a68be4Smrg    It is probably not the most efficient form of splay trees, but it should
420c0a68be4Smrg    be good enough to experiment with this idea of bitmaps-as-trees.
421c0a68be4Smrg 
422c0a68be4Smrg    For all functions below, the variable or function argument "t" is a node
423c0a68be4Smrg    in the tree, and "e" is a temporary or new node in the tree.  The rest
424c0a68be4Smrg    is sufficiently straigh-forward (and very well explained in the paper)
425c0a68be4Smrg    that comment would only clutter things.  */
426c0a68be4Smrg 
427c0a68be4Smrg static inline void
bitmap_tree_link_left(bitmap_element * & t,bitmap_element * & l)428c0a68be4Smrg bitmap_tree_link_left (bitmap_element * &t, bitmap_element * &l)
429c0a68be4Smrg {
430c0a68be4Smrg   l->next = t;
431c0a68be4Smrg   l = t;
432c0a68be4Smrg   t = t->next;
433c0a68be4Smrg }
434c0a68be4Smrg 
435c0a68be4Smrg static inline void
bitmap_tree_link_right(bitmap_element * & t,bitmap_element * & r)436c0a68be4Smrg bitmap_tree_link_right (bitmap_element * &t, bitmap_element * &r)
437c0a68be4Smrg {
438c0a68be4Smrg   r->prev = t;
439c0a68be4Smrg   r = t;
440c0a68be4Smrg   t = t->prev;
441c0a68be4Smrg }
442c0a68be4Smrg 
443c0a68be4Smrg static inline void
bitmap_tree_rotate_left(bitmap_element * & t)444c0a68be4Smrg bitmap_tree_rotate_left (bitmap_element * &t)
445c0a68be4Smrg {
446c0a68be4Smrg   bitmap_element *e = t->next;
447c0a68be4Smrg   t->next = t->next->prev;
448c0a68be4Smrg   e->prev = t;
449c0a68be4Smrg   t = e;
450c0a68be4Smrg }
451c0a68be4Smrg 
452c0a68be4Smrg static inline void
bitmap_tree_rotate_right(bitmap_element * & t)453c0a68be4Smrg bitmap_tree_rotate_right (bitmap_element * &t)
454c0a68be4Smrg {
455c0a68be4Smrg   bitmap_element *e = t->prev;
456c0a68be4Smrg   t->prev = t->prev->next;
457c0a68be4Smrg   e->next = t;
458c0a68be4Smrg   t = e;
459c0a68be4Smrg }
460c0a68be4Smrg 
461c0a68be4Smrg static bitmap_element *
bitmap_tree_splay(bitmap head,bitmap_element * t,unsigned int indx)462c0a68be4Smrg bitmap_tree_splay (bitmap head, bitmap_element *t, unsigned int indx)
463c0a68be4Smrg {
464c0a68be4Smrg   bitmap_element N, *l, *r;
465c0a68be4Smrg 
466c0a68be4Smrg   if (t == NULL)
467c0a68be4Smrg     return NULL;
468c0a68be4Smrg 
469c0a68be4Smrg   bitmap_usage *usage = NULL;
470c0a68be4Smrg   if (GATHER_STATISTICS)
471c0a68be4Smrg     usage = bitmap_mem_desc.get_descriptor_for_instance (head);
472c0a68be4Smrg 
473c0a68be4Smrg   N.prev = N.next = NULL;
474c0a68be4Smrg   l = r = &N;
475c0a68be4Smrg 
476c0a68be4Smrg   while (indx != t->indx)
477c0a68be4Smrg     {
478c0a68be4Smrg       if (GATHER_STATISTICS && usage)
479c0a68be4Smrg 	usage->m_search_iter++;
480c0a68be4Smrg 
481c0a68be4Smrg       if (indx < t->indx)
482c0a68be4Smrg 	{
483c0a68be4Smrg 	  if (t->prev != NULL && indx < t->prev->indx)
484c0a68be4Smrg 	    bitmap_tree_rotate_right (t);
485c0a68be4Smrg 	  if (t->prev == NULL)
486c0a68be4Smrg 	    break;
487c0a68be4Smrg 	  bitmap_tree_link_right (t, r);
488c0a68be4Smrg 	}
489c0a68be4Smrg       else if (indx > t->indx)
490c0a68be4Smrg 	{
491c0a68be4Smrg 	  if (t->next != NULL && indx > t->next->indx)
492c0a68be4Smrg 	    bitmap_tree_rotate_left (t);
493c0a68be4Smrg 	  if (t->next == NULL)
494c0a68be4Smrg 	    break;
495c0a68be4Smrg 	  bitmap_tree_link_left (t, l);
496c0a68be4Smrg 	}
497c0a68be4Smrg     }
498c0a68be4Smrg 
499c0a68be4Smrg   l->next = t->prev;
500c0a68be4Smrg   r->prev = t->next;
501c0a68be4Smrg   t->prev = N.next;
502c0a68be4Smrg   t->next = N.prev;
503c0a68be4Smrg   return t;
504c0a68be4Smrg }
505c0a68be4Smrg 
506c0a68be4Smrg /* Link bitmap element E into the current bitmap splay tree.  */
507c0a68be4Smrg 
508c0a68be4Smrg static inline void
bitmap_tree_link_element(bitmap head,bitmap_element * e)509c0a68be4Smrg bitmap_tree_link_element (bitmap head, bitmap_element *e)
510c0a68be4Smrg {
511c0a68be4Smrg   if (head->first == NULL)
512c0a68be4Smrg     e->prev = e->next = NULL;
513c0a68be4Smrg   else
514c0a68be4Smrg     {
515c0a68be4Smrg       bitmap_element *t = bitmap_tree_splay (head, head->first, e->indx);
516c0a68be4Smrg       if (e->indx < t->indx)
517c0a68be4Smrg 	{
518c0a68be4Smrg 	  e->prev = t->prev;
519c0a68be4Smrg 	  e->next = t;
520c0a68be4Smrg 	  t->prev = NULL;
521c0a68be4Smrg 	}
522c0a68be4Smrg       else if (e->indx > t->indx)
523c0a68be4Smrg 	{
524c0a68be4Smrg 	  e->next = t->next;
525c0a68be4Smrg 	  e->prev = t;
526c0a68be4Smrg 	  t->next = NULL;
527c0a68be4Smrg 	}
528c0a68be4Smrg       else
529c0a68be4Smrg 	gcc_unreachable ();
530c0a68be4Smrg     }
531c0a68be4Smrg   head->first = e;
532c0a68be4Smrg   head->current = e;
533c0a68be4Smrg   head->indx = e->indx;
534c0a68be4Smrg }
535c0a68be4Smrg 
536c0a68be4Smrg /* Unlink bitmap element E from the current bitmap splay tree,
537c0a68be4Smrg    and return it to the freelist.  */
538c0a68be4Smrg 
539c0a68be4Smrg static void
bitmap_tree_unlink_element(bitmap head,bitmap_element * e)540c0a68be4Smrg bitmap_tree_unlink_element (bitmap head, bitmap_element *e)
541c0a68be4Smrg {
542c0a68be4Smrg   bitmap_element *t = bitmap_tree_splay (head, head->first, e->indx);
543c0a68be4Smrg 
544c0a68be4Smrg   gcc_checking_assert (t == e);
545c0a68be4Smrg 
546c0a68be4Smrg   if (e->prev == NULL)
547c0a68be4Smrg     t = e->next;
548c0a68be4Smrg   else
549c0a68be4Smrg     {
550c0a68be4Smrg       t = bitmap_tree_splay (head, e->prev, e->indx);
551c0a68be4Smrg       t->next = e->next;
552c0a68be4Smrg     }
553c0a68be4Smrg   head->first = t;
554c0a68be4Smrg   head->current = t;
555c0a68be4Smrg   head->indx = (t != NULL) ? t->indx : 0;
556c0a68be4Smrg 
557c0a68be4Smrg   bitmap_elem_to_freelist (head, e);
558c0a68be4Smrg }
559c0a68be4Smrg 
560c0a68be4Smrg /* Return the element for INDX, or NULL if the element doesn't exist.  */
561c0a68be4Smrg 
562c0a68be4Smrg static inline bitmap_element *
bitmap_tree_find_element(bitmap head,unsigned int indx)563c0a68be4Smrg bitmap_tree_find_element (bitmap head, unsigned int indx)
564c0a68be4Smrg {
565c0a68be4Smrg   if (head->current == NULL
566c0a68be4Smrg       || head->indx == indx)
567c0a68be4Smrg     return head->current;
568c0a68be4Smrg 
569c0a68be4Smrg   /* Usage can be NULL due to allocated bitmaps for which we do not
570c0a68be4Smrg      call initialize function.  */
571c0a68be4Smrg   bitmap_usage *usage = NULL;
572c0a68be4Smrg   if (GATHER_STATISTICS)
573c0a68be4Smrg     usage = bitmap_mem_desc.get_descriptor_for_instance (head);
574c0a68be4Smrg 
575c0a68be4Smrg   /* This bitmap has more than one element, and we're going to look
576c0a68be4Smrg      through the elements list.  Count that as a search.  */
577c0a68be4Smrg   if (GATHER_STATISTICS && usage)
578c0a68be4Smrg     usage->m_nsearches++;
579c0a68be4Smrg 
580c0a68be4Smrg   bitmap_element *element = bitmap_tree_splay (head, head->first, indx);
581c0a68be4Smrg   gcc_checking_assert (element != NULL);
582c0a68be4Smrg   head->first = element;
583c0a68be4Smrg   head->current = element;
584c0a68be4Smrg   head->indx = element->indx;
585c0a68be4Smrg   if (element->indx != indx)
586c0a68be4Smrg     element = 0;
587c0a68be4Smrg   return element;
588c0a68be4Smrg }
589c0a68be4Smrg 
590c0a68be4Smrg /* Converting bitmap views from linked-list to tree and vice versa.  */
591c0a68be4Smrg 
592c0a68be4Smrg /* Splice element E and all elements with a larger index from
593c0a68be4Smrg    bitmap HEAD, convert the spliced elements to the linked-list
594c0a68be4Smrg    view, and return the head of the list (which should be E again),  */
595c0a68be4Smrg 
596c0a68be4Smrg static bitmap_element *
bitmap_tree_listify_from(bitmap head,bitmap_element * e)597c0a68be4Smrg bitmap_tree_listify_from (bitmap head, bitmap_element *e)
598c0a68be4Smrg {
599c0a68be4Smrg   bitmap_element *t, *erb;
600c0a68be4Smrg 
601c0a68be4Smrg   /* Detach the right branch from E (all elements with indx > E->indx),
602c0a68be4Smrg      and splay E to the root.  */
603c0a68be4Smrg   erb = e->next;
604c0a68be4Smrg   e->next = NULL;
605c0a68be4Smrg   t = bitmap_tree_splay (head, head->first, e->indx);
606c0a68be4Smrg   gcc_checking_assert (t == e);
607c0a68be4Smrg 
608c0a68be4Smrg   /* Because E has no right branch, and we rotated it to the root,
609c0a68be4Smrg      the left branch is the new root.  */
610c0a68be4Smrg   t = e->prev;
611c0a68be4Smrg   head->first = t;
612c0a68be4Smrg   head->current = t;
613c0a68be4Smrg   head->indx = (t != NULL) ? t->indx : 0;
614c0a68be4Smrg 
615c0a68be4Smrg   /* Detach the tree from E, and re-attach the right branch of E.  */
616c0a68be4Smrg   e->prev = NULL;
617c0a68be4Smrg   e->next = erb;
618c0a68be4Smrg 
619c0a68be4Smrg   /* The tree is now valid again.  Now we need to "un-tree" E.
620c0a68be4Smrg      It is imperative that a non-recursive implementation is used
621c0a68be4Smrg      for this, because splay trees have a worst case depth of O(N)
622c0a68be4Smrg      for a tree with N nodes.  A recursive implementation could
623c0a68be4Smrg      result in a stack overflow for a sufficiently large, unbalanced
624c0a68be4Smrg      bitmap tree.  */
625c0a68be4Smrg 
626c0a68be4Smrg   auto_vec<bitmap_element *, 32> stack;
627c0a68be4Smrg   auto_vec<bitmap_element *, 32> sorted_elements;
628c0a68be4Smrg   bitmap_element *n = e;
629c0a68be4Smrg 
630c0a68be4Smrg   while (true)
631c0a68be4Smrg     {
632c0a68be4Smrg       while (n != NULL)
633c0a68be4Smrg 	{
634c0a68be4Smrg 	  stack.safe_push (n);
635c0a68be4Smrg 	  n = n->prev;
636c0a68be4Smrg 	}
637c0a68be4Smrg 
638c0a68be4Smrg       if (stack.is_empty ())
639c0a68be4Smrg 	break;
640c0a68be4Smrg 
641c0a68be4Smrg       n = stack.pop ();
642c0a68be4Smrg       sorted_elements.safe_push (n);
643c0a68be4Smrg       n = n->next;
644c0a68be4Smrg     }
645c0a68be4Smrg 
646c0a68be4Smrg   gcc_assert (sorted_elements[0] == e);
647c0a68be4Smrg 
648c0a68be4Smrg   bitmap_element *prev = NULL;
649c0a68be4Smrg   unsigned ix;
650c0a68be4Smrg   FOR_EACH_VEC_ELT (sorted_elements, ix, n)
651c0a68be4Smrg     {
652c0a68be4Smrg       if (prev != NULL)
653c0a68be4Smrg         prev->next = n;
654c0a68be4Smrg       n->prev = prev;
655c0a68be4Smrg       n->next = NULL;
656c0a68be4Smrg       prev = n;
657c0a68be4Smrg     }
658c0a68be4Smrg 
659c0a68be4Smrg   return e;
660c0a68be4Smrg }
661c0a68be4Smrg 
662c0a68be4Smrg /* Convert bitmap HEAD from splay-tree view to linked-list view.  */
663c0a68be4Smrg 
664c0a68be4Smrg void
bitmap_list_view(bitmap head)665c0a68be4Smrg bitmap_list_view (bitmap head)
666c0a68be4Smrg {
667c0a68be4Smrg   bitmap_element *ptr;
668c0a68be4Smrg 
669c0a68be4Smrg   gcc_assert (head->tree_form);
670c0a68be4Smrg 
671c0a68be4Smrg   ptr = head->first;
672c0a68be4Smrg   if (ptr)
673c0a68be4Smrg     {
674c0a68be4Smrg       while (ptr->prev)
675c0a68be4Smrg 	bitmap_tree_rotate_right (ptr);
676c0a68be4Smrg       head->first = ptr;
677c0a68be4Smrg       head->first = bitmap_tree_listify_from (head, ptr);
678c0a68be4Smrg     }
679c0a68be4Smrg 
680c0a68be4Smrg   head->tree_form = false;
681c0a68be4Smrg }
682c0a68be4Smrg 
683c0a68be4Smrg /* Convert bitmap HEAD from linked-list view to splay-tree view.
684c0a68be4Smrg    This is simply a matter of dropping the prev or next pointers
685c0a68be4Smrg    and setting the tree_form flag.  The tree will balance itself
686c0a68be4Smrg    if and when it is used.  */
687c0a68be4Smrg 
688c0a68be4Smrg void
bitmap_tree_view(bitmap head)689c0a68be4Smrg bitmap_tree_view (bitmap head)
690c0a68be4Smrg {
691c0a68be4Smrg   bitmap_element *ptr;
692c0a68be4Smrg 
693c0a68be4Smrg   gcc_assert (! head->tree_form);
694c0a68be4Smrg 
695c0a68be4Smrg   ptr = head->first;
696c0a68be4Smrg   while (ptr)
697c0a68be4Smrg     {
698c0a68be4Smrg       ptr->prev = NULL;
699c0a68be4Smrg       ptr = ptr->next;
700c0a68be4Smrg     }
701c0a68be4Smrg 
702c0a68be4Smrg   head->tree_form = true;
703c0a68be4Smrg }
704c0a68be4Smrg 
705c0a68be4Smrg /* Clear a bitmap by freeing all its elements.  */
7061debfc3dSmrg 
7071debfc3dSmrg void
bitmap_clear(bitmap head)7081debfc3dSmrg bitmap_clear (bitmap head)
7091debfc3dSmrg {
710c0a68be4Smrg   if (head->first == NULL)
711c0a68be4Smrg     return;
712c0a68be4Smrg   if (head->tree_form)
713c0a68be4Smrg     {
714c0a68be4Smrg       bitmap_element *e, *t;
715c0a68be4Smrg       for (e = head->first; e->prev; e = e->prev)
716c0a68be4Smrg 	/* Loop to find the element with the smallest index.  */ ;
717c0a68be4Smrg       t = bitmap_tree_splay (head, head->first, e->indx);
718c0a68be4Smrg       gcc_checking_assert (t == e);
719c0a68be4Smrg       head->first = t;
720c0a68be4Smrg     }
7211debfc3dSmrg   bitmap_elt_clear_from (head, head->first);
7221debfc3dSmrg }
7231debfc3dSmrg 
7241debfc3dSmrg /* Initialize a bitmap obstack.  If BIT_OBSTACK is NULL, initialize
7251debfc3dSmrg    the default bitmap obstack.  */
7261debfc3dSmrg 
7271debfc3dSmrg void
bitmap_obstack_initialize(bitmap_obstack * bit_obstack)7281debfc3dSmrg bitmap_obstack_initialize (bitmap_obstack *bit_obstack)
7291debfc3dSmrg {
7301debfc3dSmrg   if (!bit_obstack)
7311debfc3dSmrg     {
7321debfc3dSmrg       if (bitmap_default_obstack_depth++)
7331debfc3dSmrg 	return;
7341debfc3dSmrg       bit_obstack = &bitmap_default_obstack;
7351debfc3dSmrg     }
7361debfc3dSmrg 
7371debfc3dSmrg #if !defined(__GNUC__) || (__GNUC__ < 2)
7381debfc3dSmrg #define __alignof__(type) 0
7391debfc3dSmrg #endif
7401debfc3dSmrg 
7411debfc3dSmrg   bit_obstack->elements = NULL;
7421debfc3dSmrg   bit_obstack->heads = NULL;
7431debfc3dSmrg   obstack_specify_allocation (&bit_obstack->obstack, OBSTACK_CHUNK_SIZE,
7441debfc3dSmrg 			      __alignof__ (bitmap_element),
7451debfc3dSmrg 			      obstack_chunk_alloc,
7461debfc3dSmrg 			      obstack_chunk_free);
7471debfc3dSmrg }
7481debfc3dSmrg 
7491debfc3dSmrg /* Release the memory from a bitmap obstack.  If BIT_OBSTACK is NULL,
7501debfc3dSmrg    release the default bitmap obstack.  */
7511debfc3dSmrg 
7521debfc3dSmrg void
bitmap_obstack_release(bitmap_obstack * bit_obstack)7531debfc3dSmrg bitmap_obstack_release (bitmap_obstack *bit_obstack)
7541debfc3dSmrg {
7551debfc3dSmrg   if (!bit_obstack)
7561debfc3dSmrg     {
7571debfc3dSmrg       if (--bitmap_default_obstack_depth)
7581debfc3dSmrg 	{
7591debfc3dSmrg 	  gcc_assert (bitmap_default_obstack_depth > 0);
7601debfc3dSmrg 	  return;
7611debfc3dSmrg 	}
7621debfc3dSmrg       bit_obstack = &bitmap_default_obstack;
7631debfc3dSmrg     }
7641debfc3dSmrg 
7651debfc3dSmrg   bit_obstack->elements = NULL;
7661debfc3dSmrg   bit_obstack->heads = NULL;
7671debfc3dSmrg   obstack_free (&bit_obstack->obstack, NULL);
7681debfc3dSmrg }
7691debfc3dSmrg 
7701debfc3dSmrg /* Create a new bitmap on an obstack.  If BIT_OBSTACK is NULL, create
7711debfc3dSmrg    it on the default bitmap obstack.  */
7721debfc3dSmrg 
7731debfc3dSmrg bitmap
bitmap_alloc(bitmap_obstack * bit_obstack MEM_STAT_DECL)774a2dc1f3fSmrg bitmap_alloc (bitmap_obstack *bit_obstack MEM_STAT_DECL)
7751debfc3dSmrg {
7761debfc3dSmrg   bitmap map;
7771debfc3dSmrg 
7781debfc3dSmrg   if (!bit_obstack)
7791debfc3dSmrg     bit_obstack = &bitmap_default_obstack;
7801debfc3dSmrg   map = bit_obstack->heads;
7811debfc3dSmrg   if (map)
782*8feb0f0bSmrg     bit_obstack->heads = (class bitmap_head *) map->first;
7831debfc3dSmrg   else
7841debfc3dSmrg     map = XOBNEW (&bit_obstack->obstack, bitmap_head);
785a2dc1f3fSmrg   bitmap_initialize (map, bit_obstack PASS_MEM_STAT);
7861debfc3dSmrg 
7871debfc3dSmrg   if (GATHER_STATISTICS)
7881debfc3dSmrg     register_overhead (map, sizeof (bitmap_head));
7891debfc3dSmrg 
7901debfc3dSmrg   return map;
7911debfc3dSmrg }
7921debfc3dSmrg 
7931debfc3dSmrg /* Create a new GCd bitmap.  */
7941debfc3dSmrg 
7951debfc3dSmrg bitmap
bitmap_gc_alloc(ALONE_MEM_STAT_DECL)796a2dc1f3fSmrg bitmap_gc_alloc (ALONE_MEM_STAT_DECL)
7971debfc3dSmrg {
7981debfc3dSmrg   bitmap map;
7991debfc3dSmrg 
8001debfc3dSmrg   map = ggc_alloc<bitmap_head> ();
801a2dc1f3fSmrg   bitmap_initialize (map, NULL PASS_MEM_STAT);
8021debfc3dSmrg 
8031debfc3dSmrg   if (GATHER_STATISTICS)
8041debfc3dSmrg     register_overhead (map, sizeof (bitmap_head));
8051debfc3dSmrg 
8061debfc3dSmrg   return map;
8071debfc3dSmrg }
8081debfc3dSmrg 
8091debfc3dSmrg /* Release an obstack allocated bitmap.  */
8101debfc3dSmrg 
8111debfc3dSmrg void
bitmap_obstack_free(bitmap map)8121debfc3dSmrg bitmap_obstack_free (bitmap map)
8131debfc3dSmrg {
8141debfc3dSmrg   if (map)
8151debfc3dSmrg     {
8161debfc3dSmrg       bitmap_clear (map);
8171debfc3dSmrg       map->first = (bitmap_element *) map->obstack->heads;
8181debfc3dSmrg 
8191debfc3dSmrg       if (GATHER_STATISTICS)
820*8feb0f0bSmrg 	release_overhead (map, sizeof (bitmap_head), true);
8211debfc3dSmrg 
8221debfc3dSmrg       map->obstack->heads = map;
8231debfc3dSmrg     }
8241debfc3dSmrg }
8251debfc3dSmrg 
8261debfc3dSmrg 
8271debfc3dSmrg /* Return nonzero if all bits in an element are zero.  */
8281debfc3dSmrg 
8291debfc3dSmrg static inline int
bitmap_element_zerop(const bitmap_element * element)8301debfc3dSmrg bitmap_element_zerop (const bitmap_element *element)
8311debfc3dSmrg {
8321debfc3dSmrg #if BITMAP_ELEMENT_WORDS == 2
8331debfc3dSmrg   return (element->bits[0] | element->bits[1]) == 0;
8341debfc3dSmrg #else
8351debfc3dSmrg   unsigned i;
8361debfc3dSmrg 
8371debfc3dSmrg   for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
8381debfc3dSmrg     if (element->bits[i] != 0)
8391debfc3dSmrg       return 0;
8401debfc3dSmrg 
8411debfc3dSmrg   return 1;
8421debfc3dSmrg #endif
8431debfc3dSmrg }
8441debfc3dSmrg 
8451debfc3dSmrg /* Copy a bitmap to another bitmap.  */
8461debfc3dSmrg 
8471debfc3dSmrg void
bitmap_copy(bitmap to,const_bitmap from)8481debfc3dSmrg bitmap_copy (bitmap to, const_bitmap from)
8491debfc3dSmrg {
8501debfc3dSmrg   const bitmap_element *from_ptr;
8511debfc3dSmrg   bitmap_element *to_ptr = 0;
8521debfc3dSmrg 
853c0a68be4Smrg   gcc_checking_assert (!to->tree_form && !from->tree_form);
854c0a68be4Smrg 
8551debfc3dSmrg   bitmap_clear (to);
8561debfc3dSmrg 
8571debfc3dSmrg   /* Copy elements in forward direction one at a time.  */
8581debfc3dSmrg   for (from_ptr = from->first; from_ptr; from_ptr = from_ptr->next)
8591debfc3dSmrg     {
8601debfc3dSmrg       bitmap_element *to_elt = bitmap_element_allocate (to);
8611debfc3dSmrg 
8621debfc3dSmrg       to_elt->indx = from_ptr->indx;
8631debfc3dSmrg       memcpy (to_elt->bits, from_ptr->bits, sizeof (to_elt->bits));
8641debfc3dSmrg 
865c0a68be4Smrg       /* Here we have a special case of bitmap_list_link_element,
866c0a68be4Smrg          for the case where we know the links are being entered
867c0a68be4Smrg 	 in sequence.  */
8681debfc3dSmrg       if (to_ptr == 0)
8691debfc3dSmrg 	{
8701debfc3dSmrg 	  to->first = to->current = to_elt;
8711debfc3dSmrg 	  to->indx = from_ptr->indx;
8721debfc3dSmrg 	  to_elt->next = to_elt->prev = 0;
8731debfc3dSmrg 	}
8741debfc3dSmrg       else
8751debfc3dSmrg 	{
8761debfc3dSmrg 	  to_elt->prev = to_ptr;
8771debfc3dSmrg 	  to_elt->next = 0;
8781debfc3dSmrg 	  to_ptr->next = to_elt;
8791debfc3dSmrg 	}
8801debfc3dSmrg 
8811debfc3dSmrg       to_ptr = to_elt;
8821debfc3dSmrg     }
8831debfc3dSmrg }
8841debfc3dSmrg 
8851debfc3dSmrg /* Move a bitmap to another bitmap.  */
8861debfc3dSmrg 
8871debfc3dSmrg void
bitmap_move(bitmap to,bitmap from)8881debfc3dSmrg bitmap_move (bitmap to, bitmap from)
8891debfc3dSmrg {
8901debfc3dSmrg   gcc_assert (to->obstack == from->obstack);
8911debfc3dSmrg 
8921debfc3dSmrg   bitmap_clear (to);
8931debfc3dSmrg 
894*8feb0f0bSmrg   size_t sz = 0;
8951debfc3dSmrg   if (GATHER_STATISTICS)
8961debfc3dSmrg     {
8971debfc3dSmrg       for (bitmap_element *e = to->first; e; e = e->next)
8981debfc3dSmrg 	sz += sizeof (bitmap_element);
8991debfc3dSmrg       register_overhead (to, sz);
9001debfc3dSmrg     }
901*8feb0f0bSmrg 
902*8feb0f0bSmrg   *to = *from;
903*8feb0f0bSmrg 
904*8feb0f0bSmrg   if (GATHER_STATISTICS)
905*8feb0f0bSmrg     release_overhead (from, sz, false);
9061debfc3dSmrg }
9071debfc3dSmrg 
9081debfc3dSmrg /* Clear a single bit in a bitmap.  Return true if the bit changed.  */
9091debfc3dSmrg 
9101debfc3dSmrg bool
bitmap_clear_bit(bitmap head,int bit)9111debfc3dSmrg bitmap_clear_bit (bitmap head, int bit)
9121debfc3dSmrg {
913c0a68be4Smrg   unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
914c0a68be4Smrg   bitmap_element *ptr;
9151debfc3dSmrg 
916c0a68be4Smrg   if (!head->tree_form)
917c0a68be4Smrg     ptr = bitmap_list_find_element (head, indx);
918c0a68be4Smrg   else
919c0a68be4Smrg     ptr = bitmap_tree_find_element (head, indx);
9201debfc3dSmrg   if (ptr != 0)
9211debfc3dSmrg     {
9221debfc3dSmrg       unsigned bit_num  = bit % BITMAP_WORD_BITS;
9231debfc3dSmrg       unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
9241debfc3dSmrg       BITMAP_WORD bit_val = ((BITMAP_WORD) 1) << bit_num;
9251debfc3dSmrg       bool res = (ptr->bits[word_num] & bit_val) != 0;
9261debfc3dSmrg       if (res)
9271debfc3dSmrg 	{
9281debfc3dSmrg 	  ptr->bits[word_num] &= ~bit_val;
9291debfc3dSmrg 	  /* If we cleared the entire word, free up the element.  */
9301debfc3dSmrg 	  if (!ptr->bits[word_num]
9311debfc3dSmrg 	      && bitmap_element_zerop (ptr))
932c0a68be4Smrg 	    {
933c0a68be4Smrg 	      if (!head->tree_form)
934c0a68be4Smrg 		bitmap_list_unlink_element (head, ptr);
935c0a68be4Smrg 	      else
936c0a68be4Smrg 		bitmap_tree_unlink_element (head, ptr);
937c0a68be4Smrg 	    }
9381debfc3dSmrg 	}
9391debfc3dSmrg 
9401debfc3dSmrg       return res;
9411debfc3dSmrg     }
9421debfc3dSmrg 
9431debfc3dSmrg   return false;
9441debfc3dSmrg }
9451debfc3dSmrg 
9461debfc3dSmrg /* Set a single bit in a bitmap.  Return true if the bit changed.  */
9471debfc3dSmrg 
9481debfc3dSmrg bool
bitmap_set_bit(bitmap head,int bit)9491debfc3dSmrg bitmap_set_bit (bitmap head, int bit)
9501debfc3dSmrg {
951c0a68be4Smrg   unsigned indx = bit / BITMAP_ELEMENT_ALL_BITS;
952c0a68be4Smrg   bitmap_element *ptr;
953c0a68be4Smrg   if (!head->tree_form)
954c0a68be4Smrg     ptr = bitmap_list_find_element (head, indx);
955c0a68be4Smrg   else
956c0a68be4Smrg     ptr = bitmap_tree_find_element (head, indx);
9571debfc3dSmrg   unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
9581debfc3dSmrg   unsigned bit_num  = bit % BITMAP_WORD_BITS;
9591debfc3dSmrg   BITMAP_WORD bit_val = ((BITMAP_WORD) 1) << bit_num;
9601debfc3dSmrg 
961c0a68be4Smrg   if (ptr != 0)
9621debfc3dSmrg     {
9631debfc3dSmrg       bool res = (ptr->bits[word_num] & bit_val) == 0;
9641debfc3dSmrg       if (res)
9651debfc3dSmrg 	ptr->bits[word_num] |= bit_val;
9661debfc3dSmrg       return res;
9671debfc3dSmrg     }
968c0a68be4Smrg 
969c0a68be4Smrg   ptr = bitmap_element_allocate (head);
970c0a68be4Smrg   ptr->indx = bit / BITMAP_ELEMENT_ALL_BITS;
971c0a68be4Smrg   ptr->bits[word_num] = bit_val;
972c0a68be4Smrg   if (!head->tree_form)
973c0a68be4Smrg     bitmap_list_link_element (head, ptr);
974c0a68be4Smrg   else
975c0a68be4Smrg     bitmap_tree_link_element (head, ptr);
976c0a68be4Smrg   return true;
9771debfc3dSmrg }
9781debfc3dSmrg 
9791debfc3dSmrg /* Return whether a bit is set within a bitmap.  */
9801debfc3dSmrg 
9811debfc3dSmrg int
bitmap_bit_p(const_bitmap head,int bit)982*8feb0f0bSmrg bitmap_bit_p (const_bitmap head, int bit)
9831debfc3dSmrg {
984c0a68be4Smrg   unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
985*8feb0f0bSmrg   const bitmap_element *ptr;
9861debfc3dSmrg   unsigned bit_num;
9871debfc3dSmrg   unsigned word_num;
9881debfc3dSmrg 
989c0a68be4Smrg   if (!head->tree_form)
990*8feb0f0bSmrg     ptr = bitmap_list_find_element (const_cast<bitmap> (head), indx);
991c0a68be4Smrg   else
992*8feb0f0bSmrg     ptr = bitmap_tree_find_element (const_cast<bitmap> (head), indx);
9931debfc3dSmrg   if (ptr == 0)
9941debfc3dSmrg     return 0;
9951debfc3dSmrg 
9961debfc3dSmrg   bit_num = bit % BITMAP_WORD_BITS;
9971debfc3dSmrg   word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
9981debfc3dSmrg 
9991debfc3dSmrg   return (ptr->bits[word_num] >> bit_num) & 1;
10001debfc3dSmrg }
10011debfc3dSmrg 
10021debfc3dSmrg #if GCC_VERSION < 3400
10031debfc3dSmrg /* Table of number of set bits in a character, indexed by value of char.  */
10041debfc3dSmrg static const unsigned char popcount_table[] =
10051debfc3dSmrg {
10061debfc3dSmrg     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,
10071debfc3dSmrg     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,
10081debfc3dSmrg     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,
10091debfc3dSmrg     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,
10101debfc3dSmrg     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,
10111debfc3dSmrg     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,
10121debfc3dSmrg     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,
10131debfc3dSmrg     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,
10141debfc3dSmrg };
10151debfc3dSmrg 
10161debfc3dSmrg static unsigned long
bitmap_popcount(BITMAP_WORD a)10171debfc3dSmrg bitmap_popcount (BITMAP_WORD a)
10181debfc3dSmrg {
10191debfc3dSmrg   unsigned long ret = 0;
10201debfc3dSmrg   unsigned i;
10211debfc3dSmrg 
10221debfc3dSmrg   /* Just do this the table way for now  */
10231debfc3dSmrg   for (i = 0; i < BITMAP_WORD_BITS; i+= 8)
10241debfc3dSmrg     ret += popcount_table[(a >> i) & 0xff];
10251debfc3dSmrg   return ret;
10261debfc3dSmrg }
10271debfc3dSmrg #endif
10281debfc3dSmrg 
10291debfc3dSmrg /* Count and return the number of bits set in the bitmap word BITS.  */
10301debfc3dSmrg static unsigned long
bitmap_count_bits_in_word(const BITMAP_WORD * bits)10311debfc3dSmrg bitmap_count_bits_in_word (const BITMAP_WORD *bits)
10321debfc3dSmrg {
10331debfc3dSmrg   unsigned long count = 0;
10341debfc3dSmrg 
10351debfc3dSmrg   for (unsigned ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
10361debfc3dSmrg     {
10371debfc3dSmrg #if GCC_VERSION >= 3400
10381debfc3dSmrg       /* Note that popcountl matches BITMAP_WORD in type, so the actual size
10391debfc3dSmrg 	 of BITMAP_WORD is not material.  */
10401debfc3dSmrg       count += __builtin_popcountl (bits[ix]);
10411debfc3dSmrg #else
10421debfc3dSmrg       count += bitmap_popcount (bits[ix]);
10431debfc3dSmrg #endif
10441debfc3dSmrg     }
10451debfc3dSmrg   return count;
10461debfc3dSmrg }
10471debfc3dSmrg 
10481debfc3dSmrg /* Count the number of bits set in the bitmap, and return it.  */
10491debfc3dSmrg 
10501debfc3dSmrg unsigned long
bitmap_count_bits(const_bitmap a)10511debfc3dSmrg bitmap_count_bits (const_bitmap a)
10521debfc3dSmrg {
10531debfc3dSmrg   unsigned long count = 0;
10541debfc3dSmrg   const bitmap_element *elt;
10551debfc3dSmrg 
1056c0a68be4Smrg   gcc_checking_assert (!a->tree_form);
10571debfc3dSmrg   for (elt = a->first; elt; elt = elt->next)
10581debfc3dSmrg     count += bitmap_count_bits_in_word (elt->bits);
10591debfc3dSmrg 
10601debfc3dSmrg   return count;
10611debfc3dSmrg }
10621debfc3dSmrg 
10631debfc3dSmrg /* Count the number of unique bits set in A and B and return it.  */
10641debfc3dSmrg 
10651debfc3dSmrg unsigned long
bitmap_count_unique_bits(const_bitmap a,const_bitmap b)10661debfc3dSmrg bitmap_count_unique_bits (const_bitmap a, const_bitmap b)
10671debfc3dSmrg {
10681debfc3dSmrg   unsigned long count = 0;
10691debfc3dSmrg   const bitmap_element *elt_a, *elt_b;
10701debfc3dSmrg 
10711debfc3dSmrg   for (elt_a = a->first, elt_b = b->first; elt_a && elt_b; )
10721debfc3dSmrg     {
10731debfc3dSmrg       /* If we're at different indices, then count all the bits
10741debfc3dSmrg 	 in the lower element.  If we're at the same index, then
10751debfc3dSmrg 	 count the bits in the IOR of the two elements.  */
10761debfc3dSmrg       if (elt_a->indx < elt_b->indx)
10771debfc3dSmrg 	{
10781debfc3dSmrg 	  count += bitmap_count_bits_in_word (elt_a->bits);
10791debfc3dSmrg 	  elt_a = elt_a->next;
10801debfc3dSmrg 	}
10811debfc3dSmrg       else if (elt_b->indx < elt_a->indx)
10821debfc3dSmrg 	{
10831debfc3dSmrg 	  count += bitmap_count_bits_in_word (elt_b->bits);
10841debfc3dSmrg 	  elt_b = elt_b->next;
10851debfc3dSmrg 	}
10861debfc3dSmrg       else
10871debfc3dSmrg 	{
10881debfc3dSmrg 	  BITMAP_WORD bits[BITMAP_ELEMENT_WORDS];
10891debfc3dSmrg 	  for (unsigned ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
10901debfc3dSmrg 	    bits[ix] = elt_a->bits[ix] | elt_b->bits[ix];
10911debfc3dSmrg 	  count += bitmap_count_bits_in_word (bits);
10921debfc3dSmrg 	  elt_a = elt_a->next;
10931debfc3dSmrg 	  elt_b = elt_b->next;
10941debfc3dSmrg 	}
10951debfc3dSmrg     }
10961debfc3dSmrg   return count;
10971debfc3dSmrg }
10981debfc3dSmrg 
10991debfc3dSmrg /* Return true if the bitmap has a single bit set.  Otherwise return
11001debfc3dSmrg    false.  */
11011debfc3dSmrg 
11021debfc3dSmrg bool
bitmap_single_bit_set_p(const_bitmap a)11031debfc3dSmrg bitmap_single_bit_set_p (const_bitmap a)
11041debfc3dSmrg {
11051debfc3dSmrg   unsigned long count = 0;
11061debfc3dSmrg   const bitmap_element *elt;
11071debfc3dSmrg   unsigned ix;
11081debfc3dSmrg 
11091debfc3dSmrg   if (bitmap_empty_p (a))
11101debfc3dSmrg     return false;
11111debfc3dSmrg 
11121debfc3dSmrg   elt = a->first;
1113c0a68be4Smrg 
11141debfc3dSmrg   /* As there are no completely empty bitmap elements, a second one
11151debfc3dSmrg      means we have more than one bit set.  */
1116c0a68be4Smrg   if (elt->next != NULL
1117c0a68be4Smrg       && (!a->tree_form || elt->prev != NULL))
11181debfc3dSmrg     return false;
11191debfc3dSmrg 
11201debfc3dSmrg   for (ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
11211debfc3dSmrg     {
11221debfc3dSmrg #if GCC_VERSION >= 3400
11231debfc3dSmrg       /* Note that popcountl matches BITMAP_WORD in type, so the actual size
11241debfc3dSmrg 	 of BITMAP_WORD is not material.  */
11251debfc3dSmrg       count += __builtin_popcountl (elt->bits[ix]);
11261debfc3dSmrg #else
11271debfc3dSmrg       count += bitmap_popcount (elt->bits[ix]);
11281debfc3dSmrg #endif
11291debfc3dSmrg       if (count > 1)
11301debfc3dSmrg 	return false;
11311debfc3dSmrg     }
11321debfc3dSmrg 
11331debfc3dSmrg   return count == 1;
11341debfc3dSmrg }
11351debfc3dSmrg 
11361debfc3dSmrg 
11371debfc3dSmrg /* Return the bit number of the first set bit in the bitmap.  The
11381debfc3dSmrg    bitmap must be non-empty.  */
11391debfc3dSmrg 
11401debfc3dSmrg unsigned
bitmap_first_set_bit(const_bitmap a)11411debfc3dSmrg bitmap_first_set_bit (const_bitmap a)
11421debfc3dSmrg {
11431debfc3dSmrg   const bitmap_element *elt = a->first;
11441debfc3dSmrg   unsigned bit_no;
11451debfc3dSmrg   BITMAP_WORD word;
11461debfc3dSmrg   unsigned ix;
11471debfc3dSmrg 
11481debfc3dSmrg   gcc_checking_assert (elt);
1149c0a68be4Smrg 
1150c0a68be4Smrg   if (a->tree_form)
1151c0a68be4Smrg     while (elt->prev)
1152c0a68be4Smrg       elt = elt->prev;
1153c0a68be4Smrg 
11541debfc3dSmrg   bit_no = elt->indx * BITMAP_ELEMENT_ALL_BITS;
11551debfc3dSmrg   for (ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
11561debfc3dSmrg     {
11571debfc3dSmrg       word = elt->bits[ix];
11581debfc3dSmrg       if (word)
11591debfc3dSmrg 	goto found_bit;
11601debfc3dSmrg     }
11611debfc3dSmrg   gcc_unreachable ();
11621debfc3dSmrg  found_bit:
11631debfc3dSmrg   bit_no += ix * BITMAP_WORD_BITS;
11641debfc3dSmrg 
11651debfc3dSmrg #if GCC_VERSION >= 3004
11661debfc3dSmrg   gcc_assert (sizeof (long) == sizeof (word));
11671debfc3dSmrg   bit_no += __builtin_ctzl (word);
11681debfc3dSmrg #else
11691debfc3dSmrg   /* Binary search for the first set bit.  */
11701debfc3dSmrg #if BITMAP_WORD_BITS > 64
11711debfc3dSmrg #error "Fill out the table."
11721debfc3dSmrg #endif
11731debfc3dSmrg #if BITMAP_WORD_BITS > 32
11741debfc3dSmrg   if (!(word & 0xffffffff))
11751debfc3dSmrg     word >>= 32, bit_no += 32;
11761debfc3dSmrg #endif
11771debfc3dSmrg   if (!(word & 0xffff))
11781debfc3dSmrg     word >>= 16, bit_no += 16;
11791debfc3dSmrg   if (!(word & 0xff))
11801debfc3dSmrg     word >>= 8, bit_no += 8;
11811debfc3dSmrg   if (!(word & 0xf))
11821debfc3dSmrg     word >>= 4, bit_no += 4;
11831debfc3dSmrg   if (!(word & 0x3))
11841debfc3dSmrg     word >>= 2, bit_no += 2;
11851debfc3dSmrg   if (!(word & 0x1))
11861debfc3dSmrg     word >>= 1, bit_no += 1;
11871debfc3dSmrg 
11881debfc3dSmrg  gcc_checking_assert (word & 1);
11891debfc3dSmrg #endif
11901debfc3dSmrg  return bit_no;
11911debfc3dSmrg }
11921debfc3dSmrg 
11931debfc3dSmrg /* Return the bit number of the first set bit in the bitmap.  The
11941debfc3dSmrg    bitmap must be non-empty.  */
11951debfc3dSmrg 
11961debfc3dSmrg unsigned
bitmap_last_set_bit(const_bitmap a)11971debfc3dSmrg bitmap_last_set_bit (const_bitmap a)
11981debfc3dSmrg {
1199c0a68be4Smrg   const bitmap_element *elt;
12001debfc3dSmrg   unsigned bit_no;
12011debfc3dSmrg   BITMAP_WORD word;
12021debfc3dSmrg   int ix;
12031debfc3dSmrg 
1204c0a68be4Smrg   if (a->tree_form)
1205c0a68be4Smrg     elt = a->first;
1206c0a68be4Smrg   else
1207c0a68be4Smrg     elt = a->current ? a->current : a->first;
12081debfc3dSmrg   gcc_checking_assert (elt);
1209c0a68be4Smrg 
12101debfc3dSmrg   while (elt->next)
12111debfc3dSmrg     elt = elt->next;
1212c0a68be4Smrg 
12131debfc3dSmrg   bit_no = elt->indx * BITMAP_ELEMENT_ALL_BITS;
1214c0a68be4Smrg   for (ix = BITMAP_ELEMENT_WORDS - 1; ix >= 1; ix--)
12151debfc3dSmrg     {
12161debfc3dSmrg       word = elt->bits[ix];
12171debfc3dSmrg       if (word)
12181debfc3dSmrg 	goto found_bit;
12191debfc3dSmrg     }
1220c0a68be4Smrg   gcc_assert (elt->bits[ix] != 0);
12211debfc3dSmrg  found_bit:
12221debfc3dSmrg   bit_no += ix * BITMAP_WORD_BITS;
12231debfc3dSmrg #if GCC_VERSION >= 3004
12241debfc3dSmrg   gcc_assert (sizeof (long) == sizeof (word));
12251debfc3dSmrg   bit_no += BITMAP_WORD_BITS - __builtin_clzl (word) - 1;
12261debfc3dSmrg #else
12271debfc3dSmrg   /* Hopefully this is a twos-complement host...  */
12281debfc3dSmrg   BITMAP_WORD x = word;
12291debfc3dSmrg   x |= (x >> 1);
12301debfc3dSmrg   x |= (x >> 2);
12311debfc3dSmrg   x |= (x >> 4);
12321debfc3dSmrg   x |= (x >> 8);
12331debfc3dSmrg   x |= (x >> 16);
12341debfc3dSmrg #if BITMAP_WORD_BITS > 32
12351debfc3dSmrg   x |= (x >> 32);
12361debfc3dSmrg #endif
12371debfc3dSmrg   bit_no += bitmap_popcount (x) - 1;
12381debfc3dSmrg #endif
12391debfc3dSmrg 
12401debfc3dSmrg   return bit_no;
12411debfc3dSmrg }
12421debfc3dSmrg 
12431debfc3dSmrg 
12441debfc3dSmrg /* DST = A & B.  */
12451debfc3dSmrg 
12461debfc3dSmrg void
bitmap_and(bitmap dst,const_bitmap a,const_bitmap b)12471debfc3dSmrg bitmap_and (bitmap dst, const_bitmap a, const_bitmap b)
12481debfc3dSmrg {
12491debfc3dSmrg   bitmap_element *dst_elt = dst->first;
12501debfc3dSmrg   const bitmap_element *a_elt = a->first;
12511debfc3dSmrg   const bitmap_element *b_elt = b->first;
12521debfc3dSmrg   bitmap_element *dst_prev = NULL;
12531debfc3dSmrg 
1254c0a68be4Smrg   gcc_checking_assert (!dst->tree_form && !a->tree_form && !b->tree_form);
12551debfc3dSmrg   gcc_assert (dst != a && dst != b);
12561debfc3dSmrg 
12571debfc3dSmrg   if (a == b)
12581debfc3dSmrg     {
12591debfc3dSmrg       bitmap_copy (dst, a);
12601debfc3dSmrg       return;
12611debfc3dSmrg     }
12621debfc3dSmrg 
12631debfc3dSmrg   while (a_elt && b_elt)
12641debfc3dSmrg     {
12651debfc3dSmrg       if (a_elt->indx < b_elt->indx)
12661debfc3dSmrg 	a_elt = a_elt->next;
12671debfc3dSmrg       else if (b_elt->indx < a_elt->indx)
12681debfc3dSmrg 	b_elt = b_elt->next;
12691debfc3dSmrg       else
12701debfc3dSmrg 	{
12711debfc3dSmrg 	  /* Matching elts, generate A & B.  */
12721debfc3dSmrg 	  unsigned ix;
12731debfc3dSmrg 	  BITMAP_WORD ior = 0;
12741debfc3dSmrg 
12751debfc3dSmrg 	  if (!dst_elt)
1276c0a68be4Smrg 	    dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
1277c0a68be4Smrg 							a_elt->indx);
12781debfc3dSmrg 	  else
12791debfc3dSmrg 	    dst_elt->indx = a_elt->indx;
12801debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
12811debfc3dSmrg 	    {
12821debfc3dSmrg 	      BITMAP_WORD r = a_elt->bits[ix] & b_elt->bits[ix];
12831debfc3dSmrg 
12841debfc3dSmrg 	      dst_elt->bits[ix] = r;
12851debfc3dSmrg 	      ior |= r;
12861debfc3dSmrg 	    }
12871debfc3dSmrg 	  if (ior)
12881debfc3dSmrg 	    {
12891debfc3dSmrg 	      dst_prev = dst_elt;
12901debfc3dSmrg 	      dst_elt = dst_elt->next;
12911debfc3dSmrg 	    }
12921debfc3dSmrg 	  a_elt = a_elt->next;
12931debfc3dSmrg 	  b_elt = b_elt->next;
12941debfc3dSmrg 	}
12951debfc3dSmrg     }
12961debfc3dSmrg   /* Ensure that dst->current is valid.  */
12971debfc3dSmrg   dst->current = dst->first;
12981debfc3dSmrg   bitmap_elt_clear_from (dst, dst_elt);
12991debfc3dSmrg   gcc_checking_assert (!dst->current == !dst->first);
13001debfc3dSmrg   if (dst->current)
13011debfc3dSmrg     dst->indx = dst->current->indx;
13021debfc3dSmrg }
13031debfc3dSmrg 
13041debfc3dSmrg /* A &= B.  Return true if A changed.  */
13051debfc3dSmrg 
13061debfc3dSmrg bool
bitmap_and_into(bitmap a,const_bitmap b)13071debfc3dSmrg bitmap_and_into (bitmap a, const_bitmap b)
13081debfc3dSmrg {
13091debfc3dSmrg   bitmap_element *a_elt = a->first;
13101debfc3dSmrg   const bitmap_element *b_elt = b->first;
13111debfc3dSmrg   bitmap_element *next;
13121debfc3dSmrg   bool changed = false;
13131debfc3dSmrg 
1314c0a68be4Smrg   gcc_checking_assert (!a->tree_form && !b->tree_form);
1315c0a68be4Smrg 
13161debfc3dSmrg   if (a == b)
13171debfc3dSmrg     return false;
13181debfc3dSmrg 
13191debfc3dSmrg   while (a_elt && b_elt)
13201debfc3dSmrg     {
13211debfc3dSmrg       if (a_elt->indx < b_elt->indx)
13221debfc3dSmrg 	{
13231debfc3dSmrg 	  next = a_elt->next;
1324c0a68be4Smrg 	  bitmap_list_unlink_element (a, a_elt);
13251debfc3dSmrg 	  a_elt = next;
13261debfc3dSmrg 	  changed = true;
13271debfc3dSmrg 	}
13281debfc3dSmrg       else if (b_elt->indx < a_elt->indx)
13291debfc3dSmrg 	b_elt = b_elt->next;
13301debfc3dSmrg       else
13311debfc3dSmrg 	{
13321debfc3dSmrg 	  /* Matching elts, generate A &= B.  */
13331debfc3dSmrg 	  unsigned ix;
13341debfc3dSmrg 	  BITMAP_WORD ior = 0;
13351debfc3dSmrg 
13361debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
13371debfc3dSmrg 	    {
13381debfc3dSmrg 	      BITMAP_WORD r = a_elt->bits[ix] & b_elt->bits[ix];
13391debfc3dSmrg 	      if (a_elt->bits[ix] != r)
13401debfc3dSmrg 		changed = true;
13411debfc3dSmrg 	      a_elt->bits[ix] = r;
13421debfc3dSmrg 	      ior |= r;
13431debfc3dSmrg 	    }
13441debfc3dSmrg 	  next = a_elt->next;
13451debfc3dSmrg 	  if (!ior)
1346c0a68be4Smrg 	    bitmap_list_unlink_element (a, a_elt);
13471debfc3dSmrg 	  a_elt = next;
13481debfc3dSmrg 	  b_elt = b_elt->next;
13491debfc3dSmrg 	}
13501debfc3dSmrg     }
13511debfc3dSmrg 
13521debfc3dSmrg   if (a_elt)
13531debfc3dSmrg     {
13541debfc3dSmrg       changed = true;
13551debfc3dSmrg       bitmap_elt_clear_from (a, a_elt);
13561debfc3dSmrg     }
13571debfc3dSmrg 
13581debfc3dSmrg   gcc_checking_assert (!a->current == !a->first
13591debfc3dSmrg 		       && (!a->current || a->indx == a->current->indx));
13601debfc3dSmrg 
13611debfc3dSmrg   return changed;
13621debfc3dSmrg }
13631debfc3dSmrg 
13641debfc3dSmrg 
13651debfc3dSmrg /* Insert an element equal to SRC_ELT after DST_PREV, overwriting DST_ELT
13661debfc3dSmrg    if non-NULL.  CHANGED is true if the destination bitmap had already been
13671debfc3dSmrg    changed; the new value of CHANGED is returned.  */
13681debfc3dSmrg 
13691debfc3dSmrg static inline bool
bitmap_elt_copy(bitmap dst,bitmap_element * dst_elt,bitmap_element * dst_prev,const bitmap_element * src_elt,bool changed)13701debfc3dSmrg bitmap_elt_copy (bitmap dst, bitmap_element *dst_elt, bitmap_element *dst_prev,
13711debfc3dSmrg 		 const bitmap_element *src_elt, bool changed)
13721debfc3dSmrg {
13731debfc3dSmrg   if (!changed && dst_elt && dst_elt->indx == src_elt->indx)
13741debfc3dSmrg     {
13751debfc3dSmrg       unsigned ix;
13761debfc3dSmrg 
13771debfc3dSmrg       for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
13781debfc3dSmrg 	if (src_elt->bits[ix] != dst_elt->bits[ix])
13791debfc3dSmrg 	  {
13801debfc3dSmrg 	    dst_elt->bits[ix] = src_elt->bits[ix];
13811debfc3dSmrg 	    changed = true;
13821debfc3dSmrg 	  }
13831debfc3dSmrg     }
13841debfc3dSmrg   else
13851debfc3dSmrg     {
13861debfc3dSmrg       changed = true;
13871debfc3dSmrg       if (!dst_elt)
1388c0a68be4Smrg 	dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
1389c0a68be4Smrg 						    src_elt->indx);
13901debfc3dSmrg       else
13911debfc3dSmrg 	dst_elt->indx = src_elt->indx;
13921debfc3dSmrg       memcpy (dst_elt->bits, src_elt->bits, sizeof (dst_elt->bits));
13931debfc3dSmrg     }
13941debfc3dSmrg   return changed;
13951debfc3dSmrg }
13961debfc3dSmrg 
13971debfc3dSmrg 
13981debfc3dSmrg 
13991debfc3dSmrg /* DST = A & ~B  */
14001debfc3dSmrg 
14011debfc3dSmrg bool
bitmap_and_compl(bitmap dst,const_bitmap a,const_bitmap b)14021debfc3dSmrg bitmap_and_compl (bitmap dst, const_bitmap a, const_bitmap b)
14031debfc3dSmrg {
14041debfc3dSmrg   bitmap_element *dst_elt = dst->first;
14051debfc3dSmrg   const bitmap_element *a_elt = a->first;
14061debfc3dSmrg   const bitmap_element *b_elt = b->first;
14071debfc3dSmrg   bitmap_element *dst_prev = NULL;
14081debfc3dSmrg   bitmap_element **dst_prev_pnext = &dst->first;
14091debfc3dSmrg   bool changed = false;
14101debfc3dSmrg 
1411c0a68be4Smrg   gcc_checking_assert (!dst->tree_form && !a->tree_form && !b->tree_form);
14121debfc3dSmrg   gcc_assert (dst != a && dst != b);
14131debfc3dSmrg 
14141debfc3dSmrg   if (a == b)
14151debfc3dSmrg     {
14161debfc3dSmrg       changed = !bitmap_empty_p (dst);
14171debfc3dSmrg       bitmap_clear (dst);
14181debfc3dSmrg       return changed;
14191debfc3dSmrg     }
14201debfc3dSmrg 
14211debfc3dSmrg   while (a_elt)
14221debfc3dSmrg     {
14231debfc3dSmrg       while (b_elt && b_elt->indx < a_elt->indx)
14241debfc3dSmrg 	b_elt = b_elt->next;
14251debfc3dSmrg 
14261debfc3dSmrg       if (!b_elt || b_elt->indx > a_elt->indx)
14271debfc3dSmrg 	{
14281debfc3dSmrg 	  changed = bitmap_elt_copy (dst, dst_elt, dst_prev, a_elt, changed);
14291debfc3dSmrg 	  dst_prev = *dst_prev_pnext;
14301debfc3dSmrg 	  dst_prev_pnext = &dst_prev->next;
14311debfc3dSmrg 	  dst_elt = *dst_prev_pnext;
14321debfc3dSmrg 	  a_elt = a_elt->next;
14331debfc3dSmrg 	}
14341debfc3dSmrg 
14351debfc3dSmrg       else
14361debfc3dSmrg 	{
14371debfc3dSmrg 	  /* Matching elts, generate A & ~B.  */
14381debfc3dSmrg 	  unsigned ix;
14391debfc3dSmrg 	  BITMAP_WORD ior = 0;
14401debfc3dSmrg 
14411debfc3dSmrg 	  if (!changed && dst_elt && dst_elt->indx == a_elt->indx)
14421debfc3dSmrg 	    {
14431debfc3dSmrg 	      for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
14441debfc3dSmrg 		{
14451debfc3dSmrg 		  BITMAP_WORD r = a_elt->bits[ix] & ~b_elt->bits[ix];
14461debfc3dSmrg 
14471debfc3dSmrg 		  if (dst_elt->bits[ix] != r)
14481debfc3dSmrg 		    {
14491debfc3dSmrg 		      changed = true;
14501debfc3dSmrg 		      dst_elt->bits[ix] = r;
14511debfc3dSmrg 		    }
14521debfc3dSmrg 		  ior |= r;
14531debfc3dSmrg 		}
14541debfc3dSmrg 	    }
14551debfc3dSmrg 	  else
14561debfc3dSmrg 	    {
14571debfc3dSmrg 	      bool new_element;
14581debfc3dSmrg 	      if (!dst_elt || dst_elt->indx > a_elt->indx)
14591debfc3dSmrg 		{
1460c0a68be4Smrg 		  dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
1461c0a68be4Smrg 							      a_elt->indx);
14621debfc3dSmrg 		  new_element = true;
14631debfc3dSmrg 		}
14641debfc3dSmrg 	      else
14651debfc3dSmrg 		{
14661debfc3dSmrg 		  dst_elt->indx = a_elt->indx;
14671debfc3dSmrg 		  new_element = false;
14681debfc3dSmrg 		}
14691debfc3dSmrg 
14701debfc3dSmrg 	      for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
14711debfc3dSmrg 		{
14721debfc3dSmrg 		  BITMAP_WORD r = a_elt->bits[ix] & ~b_elt->bits[ix];
14731debfc3dSmrg 
14741debfc3dSmrg 		  dst_elt->bits[ix] = r;
14751debfc3dSmrg 		  ior |= r;
14761debfc3dSmrg 		}
14771debfc3dSmrg 
14781debfc3dSmrg 	      if (ior)
14791debfc3dSmrg 	        changed = true;
14801debfc3dSmrg 	      else
14811debfc3dSmrg 	        {
14821debfc3dSmrg 	          changed |= !new_element;
1483c0a68be4Smrg 		  bitmap_list_unlink_element (dst, dst_elt);
14841debfc3dSmrg 		  dst_elt = *dst_prev_pnext;
14851debfc3dSmrg 		}
14861debfc3dSmrg 	    }
14871debfc3dSmrg 
14881debfc3dSmrg 	  if (ior)
14891debfc3dSmrg 	    {
14901debfc3dSmrg 	      dst_prev = *dst_prev_pnext;
14911debfc3dSmrg 	      dst_prev_pnext = &dst_prev->next;
14921debfc3dSmrg 	      dst_elt = *dst_prev_pnext;
14931debfc3dSmrg 	    }
14941debfc3dSmrg 	  a_elt = a_elt->next;
14951debfc3dSmrg 	  b_elt = b_elt->next;
14961debfc3dSmrg 	}
14971debfc3dSmrg     }
14981debfc3dSmrg 
14991debfc3dSmrg   /* Ensure that dst->current is valid.  */
15001debfc3dSmrg   dst->current = dst->first;
15011debfc3dSmrg 
15021debfc3dSmrg   if (dst_elt)
15031debfc3dSmrg     {
15041debfc3dSmrg       changed = true;
15051debfc3dSmrg       bitmap_elt_clear_from (dst, dst_elt);
15061debfc3dSmrg     }
15071debfc3dSmrg   gcc_checking_assert (!dst->current == !dst->first);
15081debfc3dSmrg   if (dst->current)
15091debfc3dSmrg     dst->indx = dst->current->indx;
15101debfc3dSmrg 
15111debfc3dSmrg   return changed;
15121debfc3dSmrg }
15131debfc3dSmrg 
15141debfc3dSmrg /* A &= ~B. Returns true if A changes */
15151debfc3dSmrg 
15161debfc3dSmrg bool
bitmap_and_compl_into(bitmap a,const_bitmap b)15171debfc3dSmrg bitmap_and_compl_into (bitmap a, const_bitmap b)
15181debfc3dSmrg {
15191debfc3dSmrg   bitmap_element *a_elt = a->first;
15201debfc3dSmrg   const bitmap_element *b_elt = b->first;
15211debfc3dSmrg   bitmap_element *next;
15221debfc3dSmrg   BITMAP_WORD changed = 0;
15231debfc3dSmrg 
1524c0a68be4Smrg   gcc_checking_assert (!a->tree_form && !b->tree_form);
1525c0a68be4Smrg 
15261debfc3dSmrg   if (a == b)
15271debfc3dSmrg     {
15281debfc3dSmrg       if (bitmap_empty_p (a))
15291debfc3dSmrg 	return false;
15301debfc3dSmrg       else
15311debfc3dSmrg 	{
15321debfc3dSmrg 	  bitmap_clear (a);
15331debfc3dSmrg 	  return true;
15341debfc3dSmrg 	}
15351debfc3dSmrg     }
15361debfc3dSmrg 
15371debfc3dSmrg   while (a_elt && b_elt)
15381debfc3dSmrg     {
15391debfc3dSmrg       if (a_elt->indx < b_elt->indx)
15401debfc3dSmrg 	a_elt = a_elt->next;
15411debfc3dSmrg       else if (b_elt->indx < a_elt->indx)
15421debfc3dSmrg 	b_elt = b_elt->next;
15431debfc3dSmrg       else
15441debfc3dSmrg 	{
15451debfc3dSmrg 	  /* Matching elts, generate A &= ~B.  */
15461debfc3dSmrg 	  unsigned ix;
15471debfc3dSmrg 	  BITMAP_WORD ior = 0;
15481debfc3dSmrg 
15491debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
15501debfc3dSmrg 	    {
15511debfc3dSmrg 	      BITMAP_WORD cleared = a_elt->bits[ix] & b_elt->bits[ix];
15521debfc3dSmrg 	      BITMAP_WORD r = a_elt->bits[ix] ^ cleared;
15531debfc3dSmrg 
15541debfc3dSmrg 	      a_elt->bits[ix] = r;
15551debfc3dSmrg 	      changed |= cleared;
15561debfc3dSmrg 	      ior |= r;
15571debfc3dSmrg 	    }
15581debfc3dSmrg 	  next = a_elt->next;
15591debfc3dSmrg 	  if (!ior)
1560c0a68be4Smrg 	    bitmap_list_unlink_element (a, a_elt);
15611debfc3dSmrg 	  a_elt = next;
15621debfc3dSmrg 	  b_elt = b_elt->next;
15631debfc3dSmrg 	}
15641debfc3dSmrg     }
15651debfc3dSmrg   gcc_checking_assert (!a->current == !a->first
15661debfc3dSmrg 		       && (!a->current || a->indx == a->current->indx));
15671debfc3dSmrg   return changed != 0;
15681debfc3dSmrg }
15691debfc3dSmrg 
15701debfc3dSmrg /* Set COUNT bits from START in HEAD.  */
15711debfc3dSmrg void
bitmap_set_range(bitmap head,unsigned int start,unsigned int count)15721debfc3dSmrg bitmap_set_range (bitmap head, unsigned int start, unsigned int count)
15731debfc3dSmrg {
15741debfc3dSmrg   unsigned int first_index, end_bit_plus1, last_index;
15751debfc3dSmrg   bitmap_element *elt, *elt_prev;
15761debfc3dSmrg   unsigned int i;
15771debfc3dSmrg 
1578c0a68be4Smrg   gcc_checking_assert (!head->tree_form);
1579c0a68be4Smrg 
15801debfc3dSmrg   if (!count)
15811debfc3dSmrg     return;
15821debfc3dSmrg 
15831debfc3dSmrg   if (count == 1)
15841debfc3dSmrg     {
15851debfc3dSmrg       bitmap_set_bit (head, start);
15861debfc3dSmrg       return;
15871debfc3dSmrg     }
15881debfc3dSmrg 
15891debfc3dSmrg   first_index = start / BITMAP_ELEMENT_ALL_BITS;
15901debfc3dSmrg   end_bit_plus1 = start + count;
15911debfc3dSmrg   last_index = (end_bit_plus1 - 1) / BITMAP_ELEMENT_ALL_BITS;
1592c0a68be4Smrg   elt = bitmap_list_find_element (head, first_index);
15931debfc3dSmrg 
1594c0a68be4Smrg   /* If bitmap_list_find_element returns zero, the current is the closest block
15951debfc3dSmrg      to the result.  Otherwise, just use bitmap_element_allocate to
15961debfc3dSmrg      ensure ELT is set; in the loop below, ELT == NULL means "insert
15971debfc3dSmrg      at the end of the bitmap".  */
15981debfc3dSmrg   if (!elt)
15991debfc3dSmrg     {
16001debfc3dSmrg       elt = bitmap_element_allocate (head);
16011debfc3dSmrg       elt->indx = first_index;
1602c0a68be4Smrg       bitmap_list_link_element (head, elt);
16031debfc3dSmrg     }
16041debfc3dSmrg 
16051debfc3dSmrg   gcc_checking_assert (elt->indx == first_index);
16061debfc3dSmrg   elt_prev = elt->prev;
16071debfc3dSmrg   for (i = first_index; i <= last_index; i++)
16081debfc3dSmrg     {
16091debfc3dSmrg       unsigned elt_start_bit = i * BITMAP_ELEMENT_ALL_BITS;
16101debfc3dSmrg       unsigned elt_end_bit_plus1 = elt_start_bit + BITMAP_ELEMENT_ALL_BITS;
16111debfc3dSmrg 
16121debfc3dSmrg       unsigned int first_word_to_mod;
16131debfc3dSmrg       BITMAP_WORD first_mask;
16141debfc3dSmrg       unsigned int last_word_to_mod;
16151debfc3dSmrg       BITMAP_WORD last_mask;
16161debfc3dSmrg       unsigned int ix;
16171debfc3dSmrg 
16181debfc3dSmrg       if (!elt || elt->indx != i)
1619c0a68be4Smrg 	elt = bitmap_list_insert_element_after (head, elt_prev, i);
16201debfc3dSmrg 
16211debfc3dSmrg       if (elt_start_bit <= start)
16221debfc3dSmrg 	{
16231debfc3dSmrg 	  /* The first bit to turn on is somewhere inside this
16241debfc3dSmrg 	     elt.  */
16251debfc3dSmrg 	  first_word_to_mod = (start - elt_start_bit) / BITMAP_WORD_BITS;
16261debfc3dSmrg 
16271debfc3dSmrg 	  /* This mask should have 1s in all bits >= start position. */
16281debfc3dSmrg 	  first_mask =
16291debfc3dSmrg 	    (((BITMAP_WORD) 1) << ((start % BITMAP_WORD_BITS))) - 1;
16301debfc3dSmrg 	  first_mask = ~first_mask;
16311debfc3dSmrg 	}
16321debfc3dSmrg       else
16331debfc3dSmrg 	{
16341debfc3dSmrg 	  /* The first bit to turn on is below this start of this elt.  */
16351debfc3dSmrg 	  first_word_to_mod = 0;
16361debfc3dSmrg 	  first_mask = ~(BITMAP_WORD) 0;
16371debfc3dSmrg 	}
16381debfc3dSmrg 
16391debfc3dSmrg       if (elt_end_bit_plus1 <= end_bit_plus1)
16401debfc3dSmrg 	{
16411debfc3dSmrg 	  /* The last bit to turn on is beyond this elt.  */
16421debfc3dSmrg 	  last_word_to_mod = BITMAP_ELEMENT_WORDS - 1;
16431debfc3dSmrg 	  last_mask = ~(BITMAP_WORD) 0;
16441debfc3dSmrg 	}
16451debfc3dSmrg       else
16461debfc3dSmrg 	{
16471debfc3dSmrg 	  /* The last bit to turn on is inside to this elt.  */
16481debfc3dSmrg 	  last_word_to_mod =
16491debfc3dSmrg 	    (end_bit_plus1 - elt_start_bit) / BITMAP_WORD_BITS;
16501debfc3dSmrg 
16511debfc3dSmrg 	  /* The last mask should have 1s below the end bit.  */
16521debfc3dSmrg 	  last_mask =
16531debfc3dSmrg 	    (((BITMAP_WORD) 1) << ((end_bit_plus1 % BITMAP_WORD_BITS))) - 1;
16541debfc3dSmrg 	}
16551debfc3dSmrg 
16561debfc3dSmrg       if (first_word_to_mod == last_word_to_mod)
16571debfc3dSmrg 	{
16581debfc3dSmrg 	  BITMAP_WORD mask = first_mask & last_mask;
16591debfc3dSmrg 	  elt->bits[first_word_to_mod] |= mask;
16601debfc3dSmrg 	}
16611debfc3dSmrg       else
16621debfc3dSmrg 	{
16631debfc3dSmrg 	  elt->bits[first_word_to_mod] |= first_mask;
16641debfc3dSmrg 	  if (BITMAP_ELEMENT_WORDS > 2)
16651debfc3dSmrg 	    for (ix = first_word_to_mod + 1; ix < last_word_to_mod; ix++)
16661debfc3dSmrg 	      elt->bits[ix] = ~(BITMAP_WORD) 0;
16671debfc3dSmrg 	  elt->bits[last_word_to_mod] |= last_mask;
16681debfc3dSmrg 	}
16691debfc3dSmrg 
16701debfc3dSmrg       elt_prev = elt;
16711debfc3dSmrg       elt = elt->next;
16721debfc3dSmrg     }
16731debfc3dSmrg 
16741debfc3dSmrg   head->current = elt ? elt : elt_prev;
16751debfc3dSmrg   head->indx = head->current->indx;
16761debfc3dSmrg }
16771debfc3dSmrg 
16781debfc3dSmrg /* Clear COUNT bits from START in HEAD.  */
16791debfc3dSmrg void
bitmap_clear_range(bitmap head,unsigned int start,unsigned int count)16801debfc3dSmrg bitmap_clear_range (bitmap head, unsigned int start, unsigned int count)
16811debfc3dSmrg {
16821debfc3dSmrg   unsigned int first_index, end_bit_plus1, last_index;
16831debfc3dSmrg   bitmap_element *elt;
16841debfc3dSmrg 
1685c0a68be4Smrg   gcc_checking_assert (!head->tree_form);
1686c0a68be4Smrg 
16871debfc3dSmrg   if (!count)
16881debfc3dSmrg     return;
16891debfc3dSmrg 
16901debfc3dSmrg   if (count == 1)
16911debfc3dSmrg     {
16921debfc3dSmrg       bitmap_clear_bit (head, start);
16931debfc3dSmrg       return;
16941debfc3dSmrg     }
16951debfc3dSmrg 
16961debfc3dSmrg   first_index = start / BITMAP_ELEMENT_ALL_BITS;
16971debfc3dSmrg   end_bit_plus1 = start + count;
16981debfc3dSmrg   last_index = (end_bit_plus1 - 1) / BITMAP_ELEMENT_ALL_BITS;
1699c0a68be4Smrg   elt = bitmap_list_find_element (head, first_index);
17001debfc3dSmrg 
1701c0a68be4Smrg   /* If bitmap_list_find_element returns zero, the current is the closest block
17021debfc3dSmrg      to the result.  If the current is less than first index, find the
17031debfc3dSmrg      next one.  Otherwise, just set elt to be current.  */
17041debfc3dSmrg   if (!elt)
17051debfc3dSmrg     {
17061debfc3dSmrg       if (head->current)
17071debfc3dSmrg 	{
17081debfc3dSmrg 	  if (head->indx < first_index)
17091debfc3dSmrg 	    {
17101debfc3dSmrg 	      elt = head->current->next;
17111debfc3dSmrg 	      if (!elt)
17121debfc3dSmrg 		return;
17131debfc3dSmrg 	    }
17141debfc3dSmrg 	  else
17151debfc3dSmrg 	    elt = head->current;
17161debfc3dSmrg 	}
17171debfc3dSmrg       else
17181debfc3dSmrg 	return;
17191debfc3dSmrg     }
17201debfc3dSmrg 
17211debfc3dSmrg   while (elt && (elt->indx <= last_index))
17221debfc3dSmrg     {
17231debfc3dSmrg       bitmap_element * next_elt = elt->next;
17241debfc3dSmrg       unsigned elt_start_bit = (elt->indx) * BITMAP_ELEMENT_ALL_BITS;
17251debfc3dSmrg       unsigned elt_end_bit_plus1 = elt_start_bit + BITMAP_ELEMENT_ALL_BITS;
17261debfc3dSmrg 
17271debfc3dSmrg 
17281debfc3dSmrg       if (elt_start_bit >= start && elt_end_bit_plus1 <= end_bit_plus1)
17291debfc3dSmrg 	/* Get rid of the entire elt and go to the next one.  */
1730c0a68be4Smrg 	bitmap_list_unlink_element (head, elt);
17311debfc3dSmrg       else
17321debfc3dSmrg 	{
17331debfc3dSmrg 	  /* Going to have to knock out some bits in this elt.  */
17341debfc3dSmrg 	  unsigned int first_word_to_mod;
17351debfc3dSmrg 	  BITMAP_WORD first_mask;
17361debfc3dSmrg 	  unsigned int last_word_to_mod;
17371debfc3dSmrg 	  BITMAP_WORD last_mask;
17381debfc3dSmrg 	  unsigned int i;
17391debfc3dSmrg 	  bool clear = true;
17401debfc3dSmrg 
17411debfc3dSmrg 	  if (elt_start_bit <= start)
17421debfc3dSmrg 	    {
17431debfc3dSmrg 	      /* The first bit to turn off is somewhere inside this
17441debfc3dSmrg 		 elt.  */
17451debfc3dSmrg 	      first_word_to_mod = (start - elt_start_bit) / BITMAP_WORD_BITS;
17461debfc3dSmrg 
17471debfc3dSmrg 	      /* This mask should have 1s in all bits >= start position. */
17481debfc3dSmrg 	      first_mask =
17491debfc3dSmrg 		(((BITMAP_WORD) 1) << ((start % BITMAP_WORD_BITS))) - 1;
17501debfc3dSmrg 	      first_mask = ~first_mask;
17511debfc3dSmrg 	    }
17521debfc3dSmrg 	  else
17531debfc3dSmrg 	    {
17541debfc3dSmrg 	      /* The first bit to turn off is below this start of this elt.  */
17551debfc3dSmrg 	      first_word_to_mod = 0;
17561debfc3dSmrg 	      first_mask = 0;
17571debfc3dSmrg 	      first_mask = ~first_mask;
17581debfc3dSmrg 	    }
17591debfc3dSmrg 
17601debfc3dSmrg 	  if (elt_end_bit_plus1 <= end_bit_plus1)
17611debfc3dSmrg 	    {
17621debfc3dSmrg 	      /* The last bit to turn off is beyond this elt.  */
17631debfc3dSmrg 	      last_word_to_mod = BITMAP_ELEMENT_WORDS - 1;
17641debfc3dSmrg 	      last_mask = 0;
17651debfc3dSmrg 	      last_mask = ~last_mask;
17661debfc3dSmrg 	    }
17671debfc3dSmrg 	  else
17681debfc3dSmrg 	    {
17691debfc3dSmrg 	      /* The last bit to turn off is inside to this elt.  */
17701debfc3dSmrg 	      last_word_to_mod =
17711debfc3dSmrg 		(end_bit_plus1 - elt_start_bit) / BITMAP_WORD_BITS;
17721debfc3dSmrg 
17731debfc3dSmrg 	      /* The last mask should have 1s below the end bit.  */
17741debfc3dSmrg 	      last_mask =
17751debfc3dSmrg 		(((BITMAP_WORD) 1) << (((end_bit_plus1) % BITMAP_WORD_BITS))) - 1;
17761debfc3dSmrg 	    }
17771debfc3dSmrg 
17781debfc3dSmrg 
17791debfc3dSmrg 	  if (first_word_to_mod == last_word_to_mod)
17801debfc3dSmrg 	    {
17811debfc3dSmrg 	      BITMAP_WORD mask = first_mask & last_mask;
17821debfc3dSmrg 	      elt->bits[first_word_to_mod] &= ~mask;
17831debfc3dSmrg 	    }
17841debfc3dSmrg 	  else
17851debfc3dSmrg 	    {
17861debfc3dSmrg 	      elt->bits[first_word_to_mod] &= ~first_mask;
17871debfc3dSmrg 	      if (BITMAP_ELEMENT_WORDS > 2)
17881debfc3dSmrg 	        for (i = first_word_to_mod + 1; i < last_word_to_mod; i++)
17891debfc3dSmrg 		  elt->bits[i] = 0;
17901debfc3dSmrg 	      elt->bits[last_word_to_mod] &= ~last_mask;
17911debfc3dSmrg 	    }
17921debfc3dSmrg 	  for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
17931debfc3dSmrg 	    if (elt->bits[i])
17941debfc3dSmrg 	      {
17951debfc3dSmrg 		clear = false;
17961debfc3dSmrg 		break;
17971debfc3dSmrg 	      }
17981debfc3dSmrg 	  /* Check to see if there are any bits left.  */
17991debfc3dSmrg 	  if (clear)
1800c0a68be4Smrg 	    bitmap_list_unlink_element (head, elt);
18011debfc3dSmrg 	}
18021debfc3dSmrg       elt = next_elt;
18031debfc3dSmrg     }
18041debfc3dSmrg 
18051debfc3dSmrg   if (elt)
18061debfc3dSmrg     {
18071debfc3dSmrg       head->current = elt;
18081debfc3dSmrg       head->indx = head->current->indx;
18091debfc3dSmrg     }
18101debfc3dSmrg }
18111debfc3dSmrg 
18121debfc3dSmrg /* A = ~A & B. */
18131debfc3dSmrg 
18141debfc3dSmrg void
bitmap_compl_and_into(bitmap a,const_bitmap b)18151debfc3dSmrg bitmap_compl_and_into (bitmap a, const_bitmap b)
18161debfc3dSmrg {
18171debfc3dSmrg   bitmap_element *a_elt = a->first;
18181debfc3dSmrg   const bitmap_element *b_elt = b->first;
18191debfc3dSmrg   bitmap_element *a_prev = NULL;
18201debfc3dSmrg   bitmap_element *next;
18211debfc3dSmrg 
1822c0a68be4Smrg   gcc_checking_assert (!a->tree_form && !b->tree_form);
18231debfc3dSmrg   gcc_assert (a != b);
18241debfc3dSmrg 
18251debfc3dSmrg   if (bitmap_empty_p (a))
18261debfc3dSmrg     {
18271debfc3dSmrg       bitmap_copy (a, b);
18281debfc3dSmrg       return;
18291debfc3dSmrg     }
18301debfc3dSmrg   if (bitmap_empty_p (b))
18311debfc3dSmrg     {
18321debfc3dSmrg       bitmap_clear (a);
18331debfc3dSmrg       return;
18341debfc3dSmrg     }
18351debfc3dSmrg 
18361debfc3dSmrg   while (a_elt || b_elt)
18371debfc3dSmrg     {
18381debfc3dSmrg       if (!b_elt || (a_elt && a_elt->indx < b_elt->indx))
18391debfc3dSmrg 	{
18401debfc3dSmrg 	  /* A is before B.  Remove A */
18411debfc3dSmrg 	  next = a_elt->next;
18421debfc3dSmrg 	  a_prev = a_elt->prev;
1843c0a68be4Smrg 	  bitmap_list_unlink_element (a, a_elt);
18441debfc3dSmrg 	  a_elt = next;
18451debfc3dSmrg 	}
18461debfc3dSmrg       else if (!a_elt || b_elt->indx < a_elt->indx)
18471debfc3dSmrg 	{
18481debfc3dSmrg 	  /* B is before A.  Copy B. */
1849c0a68be4Smrg 	  next = bitmap_list_insert_element_after (a, a_prev, b_elt->indx);
18501debfc3dSmrg 	  memcpy (next->bits, b_elt->bits, sizeof (next->bits));
18511debfc3dSmrg 	  a_prev = next;
18521debfc3dSmrg 	  b_elt = b_elt->next;
18531debfc3dSmrg 	}
18541debfc3dSmrg       else
18551debfc3dSmrg 	{
18561debfc3dSmrg 	  /* Matching elts, generate A = ~A & B.  */
18571debfc3dSmrg 	  unsigned ix;
18581debfc3dSmrg 	  BITMAP_WORD ior = 0;
18591debfc3dSmrg 
18601debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
18611debfc3dSmrg 	    {
18621debfc3dSmrg 	      BITMAP_WORD cleared = a_elt->bits[ix] & b_elt->bits[ix];
18631debfc3dSmrg 	      BITMAP_WORD r = b_elt->bits[ix] ^ cleared;
18641debfc3dSmrg 
18651debfc3dSmrg 	      a_elt->bits[ix] = r;
18661debfc3dSmrg 	      ior |= r;
18671debfc3dSmrg 	    }
18681debfc3dSmrg 	  next = a_elt->next;
18691debfc3dSmrg 	  if (!ior)
1870c0a68be4Smrg 	    bitmap_list_unlink_element (a, a_elt);
18711debfc3dSmrg 	  else
18721debfc3dSmrg 	    a_prev = a_elt;
18731debfc3dSmrg 	  a_elt = next;
18741debfc3dSmrg 	  b_elt = b_elt->next;
18751debfc3dSmrg 	}
18761debfc3dSmrg     }
18771debfc3dSmrg   gcc_checking_assert (!a->current == !a->first
18781debfc3dSmrg 		       && (!a->current || a->indx == a->current->indx));
18791debfc3dSmrg   return;
18801debfc3dSmrg }
18811debfc3dSmrg 
18821debfc3dSmrg 
18831debfc3dSmrg /* Insert an element corresponding to A_ELT | B_ELT after DST_PREV,
18841debfc3dSmrg    overwriting DST_ELT if non-NULL.  CHANGED is true if the destination bitmap
18851debfc3dSmrg    had already been changed; the new value of CHANGED is returned.  */
18861debfc3dSmrg 
18871debfc3dSmrg static inline bool
bitmap_elt_ior(bitmap dst,bitmap_element * dst_elt,bitmap_element * dst_prev,const bitmap_element * a_elt,const bitmap_element * b_elt,bool changed)18881debfc3dSmrg bitmap_elt_ior (bitmap dst, bitmap_element *dst_elt, bitmap_element *dst_prev,
18891debfc3dSmrg 		const bitmap_element *a_elt, const bitmap_element *b_elt,
18901debfc3dSmrg 		bool changed)
18911debfc3dSmrg {
18921debfc3dSmrg   gcc_assert (a_elt || b_elt);
18931debfc3dSmrg 
18941debfc3dSmrg   if (a_elt && b_elt && a_elt->indx == b_elt->indx)
18951debfc3dSmrg     {
18961debfc3dSmrg       /* Matching elts, generate A | B.  */
18971debfc3dSmrg       unsigned ix;
18981debfc3dSmrg 
18991debfc3dSmrg       if (!changed && dst_elt && dst_elt->indx == a_elt->indx)
19001debfc3dSmrg 	{
19011debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
19021debfc3dSmrg 	    {
19031debfc3dSmrg 	      BITMAP_WORD r = a_elt->bits[ix] | b_elt->bits[ix];
19041debfc3dSmrg 	      if (r != dst_elt->bits[ix])
19051debfc3dSmrg 		{
19061debfc3dSmrg 		  dst_elt->bits[ix] = r;
19071debfc3dSmrg 		  changed = true;
19081debfc3dSmrg 		}
19091debfc3dSmrg 	    }
19101debfc3dSmrg 	}
19111debfc3dSmrg       else
19121debfc3dSmrg 	{
19131debfc3dSmrg 	  changed = true;
19141debfc3dSmrg 	  if (!dst_elt)
1915c0a68be4Smrg 	    dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
1916c0a68be4Smrg 							a_elt->indx);
19171debfc3dSmrg 	  else
19181debfc3dSmrg 	    dst_elt->indx = a_elt->indx;
19191debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
19201debfc3dSmrg 	    {
19211debfc3dSmrg 	      BITMAP_WORD r = a_elt->bits[ix] | b_elt->bits[ix];
19221debfc3dSmrg 	      dst_elt->bits[ix] = r;
19231debfc3dSmrg 	    }
19241debfc3dSmrg 	}
19251debfc3dSmrg     }
19261debfc3dSmrg   else
19271debfc3dSmrg     {
19281debfc3dSmrg       /* Copy a single element.  */
19291debfc3dSmrg       const bitmap_element *src;
19301debfc3dSmrg 
19311debfc3dSmrg       if (!b_elt || (a_elt && a_elt->indx < b_elt->indx))
19321debfc3dSmrg 	src = a_elt;
19331debfc3dSmrg       else
19341debfc3dSmrg 	src = b_elt;
19351debfc3dSmrg 
19361debfc3dSmrg       gcc_checking_assert (src);
19371debfc3dSmrg       changed = bitmap_elt_copy (dst, dst_elt, dst_prev, src, changed);
19381debfc3dSmrg     }
19391debfc3dSmrg   return changed;
19401debfc3dSmrg }
19411debfc3dSmrg 
19421debfc3dSmrg 
19431debfc3dSmrg /* DST = A | B.  Return true if DST changes.  */
19441debfc3dSmrg 
19451debfc3dSmrg bool
bitmap_ior(bitmap dst,const_bitmap a,const_bitmap b)19461debfc3dSmrg bitmap_ior (bitmap dst, const_bitmap a, const_bitmap b)
19471debfc3dSmrg {
19481debfc3dSmrg   bitmap_element *dst_elt = dst->first;
19491debfc3dSmrg   const bitmap_element *a_elt = a->first;
19501debfc3dSmrg   const bitmap_element *b_elt = b->first;
19511debfc3dSmrg   bitmap_element *dst_prev = NULL;
19521debfc3dSmrg   bitmap_element **dst_prev_pnext = &dst->first;
19531debfc3dSmrg   bool changed = false;
19541debfc3dSmrg 
1955c0a68be4Smrg   gcc_checking_assert (!dst->tree_form && !a->tree_form && !b->tree_form);
19561debfc3dSmrg   gcc_assert (dst != a && dst != b);
19571debfc3dSmrg 
19581debfc3dSmrg   while (a_elt || b_elt)
19591debfc3dSmrg     {
19601debfc3dSmrg       changed = bitmap_elt_ior (dst, dst_elt, dst_prev, a_elt, b_elt, changed);
19611debfc3dSmrg 
19621debfc3dSmrg       if (a_elt && b_elt && a_elt->indx == b_elt->indx)
19631debfc3dSmrg 	{
19641debfc3dSmrg 	  a_elt = a_elt->next;
19651debfc3dSmrg 	  b_elt = b_elt->next;
19661debfc3dSmrg 	}
19671debfc3dSmrg       else
19681debfc3dSmrg 	{
19691debfc3dSmrg 	  if (a_elt && (!b_elt || a_elt->indx <= b_elt->indx))
19701debfc3dSmrg             a_elt = a_elt->next;
19711debfc3dSmrg           else if (b_elt && (!a_elt || b_elt->indx <= a_elt->indx))
19721debfc3dSmrg             b_elt = b_elt->next;
19731debfc3dSmrg 	}
19741debfc3dSmrg 
19751debfc3dSmrg       dst_prev = *dst_prev_pnext;
19761debfc3dSmrg       dst_prev_pnext = &dst_prev->next;
19771debfc3dSmrg       dst_elt = *dst_prev_pnext;
19781debfc3dSmrg     }
19791debfc3dSmrg 
19801debfc3dSmrg   if (dst_elt)
19811debfc3dSmrg     {
19821debfc3dSmrg       changed = true;
19831debfc3dSmrg       /* Ensure that dst->current is valid.  */
19841debfc3dSmrg       dst->current = dst->first;
19851debfc3dSmrg       bitmap_elt_clear_from (dst, dst_elt);
19861debfc3dSmrg     }
19871debfc3dSmrg   gcc_checking_assert (!dst->current == !dst->first);
19881debfc3dSmrg   if (dst->current)
19891debfc3dSmrg     dst->indx = dst->current->indx;
19901debfc3dSmrg   return changed;
19911debfc3dSmrg }
19921debfc3dSmrg 
19931debfc3dSmrg /* A |= B.  Return true if A changes.  */
19941debfc3dSmrg 
19951debfc3dSmrg bool
bitmap_ior_into(bitmap a,const_bitmap b)19961debfc3dSmrg bitmap_ior_into (bitmap a, const_bitmap b)
19971debfc3dSmrg {
19981debfc3dSmrg   bitmap_element *a_elt = a->first;
19991debfc3dSmrg   const bitmap_element *b_elt = b->first;
20001debfc3dSmrg   bitmap_element *a_prev = NULL;
20011debfc3dSmrg   bitmap_element **a_prev_pnext = &a->first;
20021debfc3dSmrg   bool changed = false;
20031debfc3dSmrg 
2004c0a68be4Smrg   gcc_checking_assert (!a->tree_form && !b->tree_form);
20051debfc3dSmrg   if (a == b)
20061debfc3dSmrg     return false;
20071debfc3dSmrg 
20081debfc3dSmrg   while (b_elt)
20091debfc3dSmrg     {
20101debfc3dSmrg       /* If A lags behind B, just advance it.  */
20111debfc3dSmrg       if (!a_elt || a_elt->indx == b_elt->indx)
20121debfc3dSmrg 	{
20131debfc3dSmrg 	  changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, b_elt, changed);
20141debfc3dSmrg 	  b_elt = b_elt->next;
20151debfc3dSmrg 	}
20161debfc3dSmrg       else if (a_elt->indx > b_elt->indx)
20171debfc3dSmrg 	{
20181debfc3dSmrg           changed = bitmap_elt_copy (a, NULL, a_prev, b_elt, changed);
20191debfc3dSmrg 	  b_elt = b_elt->next;
20201debfc3dSmrg 	}
20211debfc3dSmrg 
20221debfc3dSmrg       a_prev = *a_prev_pnext;
20231debfc3dSmrg       a_prev_pnext = &a_prev->next;
20241debfc3dSmrg       a_elt = *a_prev_pnext;
20251debfc3dSmrg     }
20261debfc3dSmrg 
20271debfc3dSmrg   gcc_checking_assert (!a->current == !a->first);
20281debfc3dSmrg   if (a->current)
20291debfc3dSmrg     a->indx = a->current->indx;
20301debfc3dSmrg   return changed;
20311debfc3dSmrg }
20321debfc3dSmrg 
2033*8feb0f0bSmrg /* A |= B.  Return true if A changes.  Free B (re-using its storage
2034*8feb0f0bSmrg    for the result).  */
2035*8feb0f0bSmrg 
2036*8feb0f0bSmrg bool
bitmap_ior_into_and_free(bitmap a,bitmap * b_)2037*8feb0f0bSmrg bitmap_ior_into_and_free (bitmap a, bitmap *b_)
2038*8feb0f0bSmrg {
2039*8feb0f0bSmrg   bitmap b = *b_;
2040*8feb0f0bSmrg   bitmap_element *a_elt = a->first;
2041*8feb0f0bSmrg   bitmap_element *b_elt = b->first;
2042*8feb0f0bSmrg   bitmap_element *a_prev = NULL;
2043*8feb0f0bSmrg   bitmap_element **a_prev_pnext = &a->first;
2044*8feb0f0bSmrg   bool changed = false;
2045*8feb0f0bSmrg 
2046*8feb0f0bSmrg   gcc_checking_assert (!a->tree_form && !b->tree_form);
2047*8feb0f0bSmrg   gcc_assert (a->obstack == b->obstack);
2048*8feb0f0bSmrg   if (a == b)
2049*8feb0f0bSmrg     return false;
2050*8feb0f0bSmrg 
2051*8feb0f0bSmrg   while (b_elt)
2052*8feb0f0bSmrg     {
2053*8feb0f0bSmrg       /* If A lags behind B, just advance it.  */
2054*8feb0f0bSmrg       if (!a_elt || a_elt->indx == b_elt->indx)
2055*8feb0f0bSmrg 	{
2056*8feb0f0bSmrg 	  changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, b_elt, changed);
2057*8feb0f0bSmrg 	  b_elt = b_elt->next;
2058*8feb0f0bSmrg 	}
2059*8feb0f0bSmrg       else if (a_elt->indx > b_elt->indx)
2060*8feb0f0bSmrg 	{
2061*8feb0f0bSmrg 	  bitmap_element *b_elt_next = b_elt->next;
2062*8feb0f0bSmrg 	  bitmap_list_unlink_element (b, b_elt, false);
2063*8feb0f0bSmrg 	  bitmap_list_insert_element_after (a, a_prev, b_elt->indx, b_elt);
2064*8feb0f0bSmrg 	  b_elt = b_elt_next;
2065*8feb0f0bSmrg 	}
2066*8feb0f0bSmrg 
2067*8feb0f0bSmrg       a_prev = *a_prev_pnext;
2068*8feb0f0bSmrg       a_prev_pnext = &a_prev->next;
2069*8feb0f0bSmrg       a_elt = *a_prev_pnext;
2070*8feb0f0bSmrg     }
2071*8feb0f0bSmrg 
2072*8feb0f0bSmrg   gcc_checking_assert (!a->current == !a->first);
2073*8feb0f0bSmrg   if (a->current)
2074*8feb0f0bSmrg     a->indx = a->current->indx;
2075*8feb0f0bSmrg 
2076*8feb0f0bSmrg   if (b->obstack)
2077*8feb0f0bSmrg     BITMAP_FREE (*b_);
2078*8feb0f0bSmrg   else
2079*8feb0f0bSmrg     bitmap_clear (b);
2080*8feb0f0bSmrg   return changed;
2081*8feb0f0bSmrg }
2082*8feb0f0bSmrg 
20831debfc3dSmrg /* DST = A ^ B  */
20841debfc3dSmrg 
20851debfc3dSmrg void
bitmap_xor(bitmap dst,const_bitmap a,const_bitmap b)20861debfc3dSmrg bitmap_xor (bitmap dst, const_bitmap a, const_bitmap b)
20871debfc3dSmrg {
20881debfc3dSmrg   bitmap_element *dst_elt = dst->first;
20891debfc3dSmrg   const bitmap_element *a_elt = a->first;
20901debfc3dSmrg   const bitmap_element *b_elt = b->first;
20911debfc3dSmrg   bitmap_element *dst_prev = NULL;
20921debfc3dSmrg 
2093c0a68be4Smrg   gcc_checking_assert (!dst->tree_form && !a->tree_form && !b->tree_form);
20941debfc3dSmrg   gcc_assert (dst != a && dst != b);
2095c0a68be4Smrg 
20961debfc3dSmrg   if (a == b)
20971debfc3dSmrg     {
20981debfc3dSmrg       bitmap_clear (dst);
20991debfc3dSmrg       return;
21001debfc3dSmrg     }
21011debfc3dSmrg 
21021debfc3dSmrg   while (a_elt || b_elt)
21031debfc3dSmrg     {
21041debfc3dSmrg       if (a_elt && b_elt && a_elt->indx == b_elt->indx)
21051debfc3dSmrg 	{
21061debfc3dSmrg 	  /* Matching elts, generate A ^ B.  */
21071debfc3dSmrg 	  unsigned ix;
21081debfc3dSmrg 	  BITMAP_WORD ior = 0;
21091debfc3dSmrg 
21101debfc3dSmrg 	  if (!dst_elt)
2111c0a68be4Smrg 	    dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
2112c0a68be4Smrg 							a_elt->indx);
21131debfc3dSmrg 	  else
21141debfc3dSmrg 	    dst_elt->indx = a_elt->indx;
21151debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
21161debfc3dSmrg 	    {
21171debfc3dSmrg 	      BITMAP_WORD r = a_elt->bits[ix] ^ b_elt->bits[ix];
21181debfc3dSmrg 
21191debfc3dSmrg 	      ior |= r;
21201debfc3dSmrg 	      dst_elt->bits[ix] = r;
21211debfc3dSmrg 	    }
21221debfc3dSmrg 	  a_elt = a_elt->next;
21231debfc3dSmrg 	  b_elt = b_elt->next;
21241debfc3dSmrg 	  if (ior)
21251debfc3dSmrg 	    {
21261debfc3dSmrg 	      dst_prev = dst_elt;
21271debfc3dSmrg 	      dst_elt = dst_elt->next;
21281debfc3dSmrg 	    }
21291debfc3dSmrg 	}
21301debfc3dSmrg       else
21311debfc3dSmrg 	{
21321debfc3dSmrg 	  /* Copy a single element.  */
21331debfc3dSmrg 	  const bitmap_element *src;
21341debfc3dSmrg 
21351debfc3dSmrg 	  if (!b_elt || (a_elt && a_elt->indx < b_elt->indx))
21361debfc3dSmrg 	    {
21371debfc3dSmrg 	      src = a_elt;
21381debfc3dSmrg 	      a_elt = a_elt->next;
21391debfc3dSmrg 	    }
21401debfc3dSmrg 	  else
21411debfc3dSmrg 	    {
21421debfc3dSmrg 	      src = b_elt;
21431debfc3dSmrg 	      b_elt = b_elt->next;
21441debfc3dSmrg 	    }
21451debfc3dSmrg 
21461debfc3dSmrg 	  if (!dst_elt)
2147c0a68be4Smrg 	    dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
2148c0a68be4Smrg 							src->indx);
21491debfc3dSmrg 	  else
21501debfc3dSmrg 	    dst_elt->indx = src->indx;
21511debfc3dSmrg 	  memcpy (dst_elt->bits, src->bits, sizeof (dst_elt->bits));
21521debfc3dSmrg 	  dst_prev = dst_elt;
21531debfc3dSmrg 	  dst_elt = dst_elt->next;
21541debfc3dSmrg 	}
21551debfc3dSmrg     }
21561debfc3dSmrg   /* Ensure that dst->current is valid.  */
21571debfc3dSmrg   dst->current = dst->first;
21581debfc3dSmrg   bitmap_elt_clear_from (dst, dst_elt);
21591debfc3dSmrg   gcc_checking_assert (!dst->current == !dst->first);
21601debfc3dSmrg   if (dst->current)
21611debfc3dSmrg     dst->indx = dst->current->indx;
21621debfc3dSmrg }
21631debfc3dSmrg 
21641debfc3dSmrg /* A ^= B */
21651debfc3dSmrg 
21661debfc3dSmrg void
bitmap_xor_into(bitmap a,const_bitmap b)21671debfc3dSmrg bitmap_xor_into (bitmap a, const_bitmap b)
21681debfc3dSmrg {
21691debfc3dSmrg   bitmap_element *a_elt = a->first;
21701debfc3dSmrg   const bitmap_element *b_elt = b->first;
21711debfc3dSmrg   bitmap_element *a_prev = NULL;
21721debfc3dSmrg 
2173c0a68be4Smrg   gcc_checking_assert (!a->tree_form && !b->tree_form);
2174c0a68be4Smrg 
21751debfc3dSmrg   if (a == b)
21761debfc3dSmrg     {
21771debfc3dSmrg       bitmap_clear (a);
21781debfc3dSmrg       return;
21791debfc3dSmrg     }
21801debfc3dSmrg 
21811debfc3dSmrg   while (b_elt)
21821debfc3dSmrg     {
21831debfc3dSmrg       if (!a_elt || b_elt->indx < a_elt->indx)
21841debfc3dSmrg 	{
21851debfc3dSmrg 	  /* Copy b_elt.  */
2186c0a68be4Smrg 	  bitmap_element *dst = bitmap_list_insert_element_after (a, a_prev,
2187c0a68be4Smrg 								  b_elt->indx);
21881debfc3dSmrg 	  memcpy (dst->bits, b_elt->bits, sizeof (dst->bits));
21891debfc3dSmrg 	  a_prev = dst;
21901debfc3dSmrg 	  b_elt = b_elt->next;
21911debfc3dSmrg 	}
21921debfc3dSmrg       else if (a_elt->indx < b_elt->indx)
21931debfc3dSmrg 	{
21941debfc3dSmrg 	  a_prev = a_elt;
21951debfc3dSmrg 	  a_elt = a_elt->next;
21961debfc3dSmrg 	}
21971debfc3dSmrg       else
21981debfc3dSmrg 	{
21991debfc3dSmrg 	  /* Matching elts, generate A ^= B.  */
22001debfc3dSmrg 	  unsigned ix;
22011debfc3dSmrg 	  BITMAP_WORD ior = 0;
22021debfc3dSmrg 	  bitmap_element *next = a_elt->next;
22031debfc3dSmrg 
22041debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
22051debfc3dSmrg 	    {
22061debfc3dSmrg 	      BITMAP_WORD r = a_elt->bits[ix] ^ b_elt->bits[ix];
22071debfc3dSmrg 
22081debfc3dSmrg 	      ior |= r;
22091debfc3dSmrg 	      a_elt->bits[ix] = r;
22101debfc3dSmrg 	    }
22111debfc3dSmrg 	  b_elt = b_elt->next;
22121debfc3dSmrg 	  if (ior)
22131debfc3dSmrg 	    a_prev = a_elt;
22141debfc3dSmrg 	  else
2215c0a68be4Smrg 	    bitmap_list_unlink_element (a, a_elt);
22161debfc3dSmrg 	  a_elt = next;
22171debfc3dSmrg 	}
22181debfc3dSmrg     }
22191debfc3dSmrg   gcc_checking_assert (!a->current == !a->first);
22201debfc3dSmrg   if (a->current)
22211debfc3dSmrg     a->indx = a->current->indx;
22221debfc3dSmrg }
22231debfc3dSmrg 
22241debfc3dSmrg /* Return true if two bitmaps are identical.
22251debfc3dSmrg    We do not bother with a check for pointer equality, as that never
22261debfc3dSmrg    occurs in practice.  */
22271debfc3dSmrg 
22281debfc3dSmrg bool
bitmap_equal_p(const_bitmap a,const_bitmap b)22291debfc3dSmrg bitmap_equal_p (const_bitmap a, const_bitmap b)
22301debfc3dSmrg {
22311debfc3dSmrg   const bitmap_element *a_elt;
22321debfc3dSmrg   const bitmap_element *b_elt;
22331debfc3dSmrg   unsigned ix;
22341debfc3dSmrg 
2235c0a68be4Smrg   gcc_checking_assert (!a->tree_form && !b->tree_form);
2236c0a68be4Smrg 
22371debfc3dSmrg   for (a_elt = a->first, b_elt = b->first;
22381debfc3dSmrg        a_elt && b_elt;
22391debfc3dSmrg        a_elt = a_elt->next, b_elt = b_elt->next)
22401debfc3dSmrg     {
22411debfc3dSmrg       if (a_elt->indx != b_elt->indx)
22421debfc3dSmrg 	return false;
22431debfc3dSmrg       for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
22441debfc3dSmrg 	if (a_elt->bits[ix] != b_elt->bits[ix])
22451debfc3dSmrg 	  return false;
22461debfc3dSmrg     }
22471debfc3dSmrg   return !a_elt && !b_elt;
22481debfc3dSmrg }
22491debfc3dSmrg 
22501debfc3dSmrg /* Return true if A AND B is not empty.  */
22511debfc3dSmrg 
22521debfc3dSmrg bool
bitmap_intersect_p(const_bitmap a,const_bitmap b)22531debfc3dSmrg bitmap_intersect_p (const_bitmap a, const_bitmap b)
22541debfc3dSmrg {
22551debfc3dSmrg   const bitmap_element *a_elt;
22561debfc3dSmrg   const bitmap_element *b_elt;
22571debfc3dSmrg   unsigned ix;
22581debfc3dSmrg 
2259c0a68be4Smrg   gcc_checking_assert (!a->tree_form && !b->tree_form);
2260c0a68be4Smrg 
22611debfc3dSmrg   for (a_elt = a->first, b_elt = b->first;
22621debfc3dSmrg        a_elt && b_elt;)
22631debfc3dSmrg     {
22641debfc3dSmrg       if (a_elt->indx < b_elt->indx)
22651debfc3dSmrg 	a_elt = a_elt->next;
22661debfc3dSmrg       else if (b_elt->indx < a_elt->indx)
22671debfc3dSmrg 	b_elt = b_elt->next;
22681debfc3dSmrg       else
22691debfc3dSmrg 	{
22701debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
22711debfc3dSmrg 	    if (a_elt->bits[ix] & b_elt->bits[ix])
22721debfc3dSmrg 	      return true;
22731debfc3dSmrg 	  a_elt = a_elt->next;
22741debfc3dSmrg 	  b_elt = b_elt->next;
22751debfc3dSmrg 	}
22761debfc3dSmrg     }
22771debfc3dSmrg   return false;
22781debfc3dSmrg }
22791debfc3dSmrg 
22801debfc3dSmrg /* Return true if A AND NOT B is not empty.  */
22811debfc3dSmrg 
22821debfc3dSmrg bool
bitmap_intersect_compl_p(const_bitmap a,const_bitmap b)22831debfc3dSmrg bitmap_intersect_compl_p (const_bitmap a, const_bitmap b)
22841debfc3dSmrg {
22851debfc3dSmrg   const bitmap_element *a_elt;
22861debfc3dSmrg   const bitmap_element *b_elt;
22871debfc3dSmrg   unsigned ix;
2288c0a68be4Smrg 
2289c0a68be4Smrg   gcc_checking_assert (!a->tree_form && !b->tree_form);
2290c0a68be4Smrg 
22911debfc3dSmrg   for (a_elt = a->first, b_elt = b->first;
22921debfc3dSmrg        a_elt && b_elt;)
22931debfc3dSmrg     {
22941debfc3dSmrg       if (a_elt->indx < b_elt->indx)
22951debfc3dSmrg 	return true;
22961debfc3dSmrg       else if (b_elt->indx < a_elt->indx)
22971debfc3dSmrg 	b_elt = b_elt->next;
22981debfc3dSmrg       else
22991debfc3dSmrg 	{
23001debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
23011debfc3dSmrg 	    if (a_elt->bits[ix] & ~b_elt->bits[ix])
23021debfc3dSmrg 	      return true;
23031debfc3dSmrg 	  a_elt = a_elt->next;
23041debfc3dSmrg 	  b_elt = b_elt->next;
23051debfc3dSmrg 	}
23061debfc3dSmrg     }
23071debfc3dSmrg   return a_elt != NULL;
23081debfc3dSmrg }
23091debfc3dSmrg 
23101debfc3dSmrg 
23111debfc3dSmrg /* DST = A | (FROM1 & ~FROM2).  Return true if DST changes.  */
23121debfc3dSmrg 
23131debfc3dSmrg bool
bitmap_ior_and_compl(bitmap dst,const_bitmap a,const_bitmap b,const_bitmap kill)23141debfc3dSmrg bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b, const_bitmap kill)
23151debfc3dSmrg {
23161debfc3dSmrg   bool changed = false;
23171debfc3dSmrg 
23181debfc3dSmrg   bitmap_element *dst_elt = dst->first;
23191debfc3dSmrg   const bitmap_element *a_elt = a->first;
23201debfc3dSmrg   const bitmap_element *b_elt = b->first;
23211debfc3dSmrg   const bitmap_element *kill_elt = kill->first;
23221debfc3dSmrg   bitmap_element *dst_prev = NULL;
23231debfc3dSmrg   bitmap_element **dst_prev_pnext = &dst->first;
23241debfc3dSmrg 
2325c0a68be4Smrg   gcc_checking_assert (!dst->tree_form && !a->tree_form && !b->tree_form
2326c0a68be4Smrg 		       && !kill->tree_form);
23271debfc3dSmrg   gcc_assert (dst != a && dst != b && dst != kill);
23281debfc3dSmrg 
23291debfc3dSmrg   /* Special cases.  We don't bother checking for bitmap_equal_p (b, kill).  */
23301debfc3dSmrg   if (b == kill || bitmap_empty_p (b))
23311debfc3dSmrg     {
23321debfc3dSmrg       changed = !bitmap_equal_p (dst, a);
23331debfc3dSmrg       if (changed)
23341debfc3dSmrg 	bitmap_copy (dst, a);
23351debfc3dSmrg       return changed;
23361debfc3dSmrg     }
23371debfc3dSmrg   if (bitmap_empty_p (kill))
23381debfc3dSmrg     return bitmap_ior (dst, a, b);
23391debfc3dSmrg   if (bitmap_empty_p (a))
23401debfc3dSmrg     return bitmap_and_compl (dst, b, kill);
23411debfc3dSmrg 
23421debfc3dSmrg   while (a_elt || b_elt)
23431debfc3dSmrg     {
23441debfc3dSmrg       bool new_element = false;
23451debfc3dSmrg 
23461debfc3dSmrg       if (b_elt)
23471debfc3dSmrg 	while (kill_elt && kill_elt->indx < b_elt->indx)
23481debfc3dSmrg 	  kill_elt = kill_elt->next;
23491debfc3dSmrg 
23501debfc3dSmrg       if (b_elt && kill_elt && kill_elt->indx == b_elt->indx
23511debfc3dSmrg 	  && (!a_elt || a_elt->indx >= b_elt->indx))
23521debfc3dSmrg         {
23531debfc3dSmrg 	  bitmap_element tmp_elt;
23541debfc3dSmrg 	  unsigned ix;
23551debfc3dSmrg 
23561debfc3dSmrg 	  BITMAP_WORD ior = 0;
23571debfc3dSmrg 	  tmp_elt.indx = b_elt->indx;
23581debfc3dSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
23591debfc3dSmrg             {
23601debfc3dSmrg               BITMAP_WORD r = b_elt->bits[ix] & ~kill_elt->bits[ix];
23611debfc3dSmrg               ior |= r;
23621debfc3dSmrg               tmp_elt.bits[ix] = r;
23631debfc3dSmrg             }
23641debfc3dSmrg 
23651debfc3dSmrg 	  if (ior)
23661debfc3dSmrg 	    {
23671debfc3dSmrg 	      changed = bitmap_elt_ior (dst, dst_elt, dst_prev,
23681debfc3dSmrg 				        a_elt, &tmp_elt, changed);
23691debfc3dSmrg 	      new_element = true;
23701debfc3dSmrg 	      if (a_elt && a_elt->indx == b_elt->indx)
23711debfc3dSmrg                 a_elt = a_elt->next;
23721debfc3dSmrg 	    }
23731debfc3dSmrg 
23741debfc3dSmrg 	  b_elt = b_elt->next;
23751debfc3dSmrg 	  kill_elt = kill_elt->next;
23761debfc3dSmrg 	}
23771debfc3dSmrg       else
23781debfc3dSmrg 	{
23791debfc3dSmrg 	  changed = bitmap_elt_ior (dst, dst_elt, dst_prev,
23801debfc3dSmrg 				    a_elt, b_elt, changed);
23811debfc3dSmrg 	  new_element = true;
23821debfc3dSmrg 
23831debfc3dSmrg           if (a_elt && b_elt && a_elt->indx == b_elt->indx)
23841debfc3dSmrg 	    {
23851debfc3dSmrg 	      a_elt = a_elt->next;
23861debfc3dSmrg 	      b_elt = b_elt->next;
23871debfc3dSmrg 	    }
23881debfc3dSmrg           else
23891debfc3dSmrg 	    {
23901debfc3dSmrg 	      if (a_elt && (!b_elt || a_elt->indx <= b_elt->indx))
23911debfc3dSmrg                 a_elt = a_elt->next;
23921debfc3dSmrg               else if (b_elt && (!a_elt || b_elt->indx <= a_elt->indx))
23931debfc3dSmrg                 b_elt = b_elt->next;
23941debfc3dSmrg 	    }
23951debfc3dSmrg 	}
23961debfc3dSmrg 
23971debfc3dSmrg       if (new_element)
23981debfc3dSmrg 	{
23991debfc3dSmrg 	  dst_prev = *dst_prev_pnext;
24001debfc3dSmrg 	  dst_prev_pnext = &dst_prev->next;
24011debfc3dSmrg 	  dst_elt = *dst_prev_pnext;
24021debfc3dSmrg 	}
24031debfc3dSmrg     }
24041debfc3dSmrg 
24051debfc3dSmrg   if (dst_elt)
24061debfc3dSmrg     {
24071debfc3dSmrg       changed = true;
24081debfc3dSmrg       /* Ensure that dst->current is valid.  */
24091debfc3dSmrg       dst->current = dst->first;
24101debfc3dSmrg       bitmap_elt_clear_from (dst, dst_elt);
24111debfc3dSmrg     }
24121debfc3dSmrg   gcc_checking_assert (!dst->current == !dst->first);
24131debfc3dSmrg   if (dst->current)
24141debfc3dSmrg     dst->indx = dst->current->indx;
24151debfc3dSmrg 
24161debfc3dSmrg   return changed;
24171debfc3dSmrg }
24181debfc3dSmrg 
2419c0a68be4Smrg /* A |= (B & ~C).  Return true if A changes.  */
24201debfc3dSmrg 
24211debfc3dSmrg bool
bitmap_ior_and_compl_into(bitmap a,const_bitmap b,const_bitmap c)2422c0a68be4Smrg bitmap_ior_and_compl_into (bitmap a, const_bitmap b, const_bitmap c)
24231debfc3dSmrg {
2424*8feb0f0bSmrg   bitmap_element *a_elt = a->first;
2425*8feb0f0bSmrg   const bitmap_element *b_elt = b->first;
2426*8feb0f0bSmrg   const bitmap_element *c_elt = c->first;
2427*8feb0f0bSmrg   bitmap_element and_elt;
2428*8feb0f0bSmrg   bitmap_element *a_prev = NULL;
2429*8feb0f0bSmrg   bitmap_element **a_prev_pnext = &a->first;
2430*8feb0f0bSmrg   bool changed = false;
2431*8feb0f0bSmrg   unsigned ix;
24321debfc3dSmrg 
2433c0a68be4Smrg   gcc_checking_assert (!a->tree_form && !b->tree_form && !c->tree_form);
2434c0a68be4Smrg 
2435*8feb0f0bSmrg   if (a == b)
2436*8feb0f0bSmrg     return false;
2437*8feb0f0bSmrg   if (bitmap_empty_p (c))
2438*8feb0f0bSmrg     return bitmap_ior_into (a, b);
2439*8feb0f0bSmrg   else if (bitmap_empty_p (a))
2440*8feb0f0bSmrg     return bitmap_and_compl (a, b, c);
24411debfc3dSmrg 
2442*8feb0f0bSmrg   and_elt.indx = -1;
2443*8feb0f0bSmrg   while (b_elt)
2444*8feb0f0bSmrg     {
2445*8feb0f0bSmrg       /* Advance C.  */
2446*8feb0f0bSmrg       while (c_elt && c_elt->indx < b_elt->indx)
2447*8feb0f0bSmrg 	c_elt = c_elt->next;
2448*8feb0f0bSmrg 
2449*8feb0f0bSmrg       const bitmap_element *and_elt_ptr;
2450*8feb0f0bSmrg       if (c_elt && c_elt->indx == b_elt->indx)
2451*8feb0f0bSmrg 	{
2452*8feb0f0bSmrg 	  BITMAP_WORD overall = 0;
2453*8feb0f0bSmrg 	  and_elt_ptr = &and_elt;
2454*8feb0f0bSmrg 	  and_elt.indx = b_elt->indx;
2455*8feb0f0bSmrg 	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
2456*8feb0f0bSmrg 	    {
2457*8feb0f0bSmrg 	      and_elt.bits[ix] = b_elt->bits[ix] & ~c_elt->bits[ix];
2458*8feb0f0bSmrg 	      overall |= and_elt.bits[ix];
2459*8feb0f0bSmrg 	    }
2460*8feb0f0bSmrg 	  if (!overall)
2461*8feb0f0bSmrg 	    {
2462*8feb0f0bSmrg 	      b_elt = b_elt->next;
2463*8feb0f0bSmrg 	      continue;
2464*8feb0f0bSmrg 	    }
2465*8feb0f0bSmrg 	}
2466*8feb0f0bSmrg       else
2467*8feb0f0bSmrg 	and_elt_ptr = b_elt;
2468*8feb0f0bSmrg 
2469*8feb0f0bSmrg       b_elt = b_elt->next;
2470*8feb0f0bSmrg 
2471*8feb0f0bSmrg       /* Now find a place to insert AND_ELT.  */
2472*8feb0f0bSmrg       do
2473*8feb0f0bSmrg 	{
2474*8feb0f0bSmrg 	  ix = a_elt ? a_elt->indx : and_elt_ptr->indx;
2475*8feb0f0bSmrg           if (ix == and_elt_ptr->indx)
2476*8feb0f0bSmrg 	    changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt,
2477*8feb0f0bSmrg 				      and_elt_ptr, changed);
2478*8feb0f0bSmrg           else if (ix > and_elt_ptr->indx)
2479*8feb0f0bSmrg 	    changed = bitmap_elt_copy (a, NULL, a_prev, and_elt_ptr, changed);
2480*8feb0f0bSmrg 
2481*8feb0f0bSmrg           a_prev = *a_prev_pnext;
2482*8feb0f0bSmrg           a_prev_pnext = &a_prev->next;
2483*8feb0f0bSmrg           a_elt = *a_prev_pnext;
2484*8feb0f0bSmrg 
2485*8feb0f0bSmrg           /* If A lagged behind B/C, we advanced it so loop once more.  */
2486*8feb0f0bSmrg 	}
2487*8feb0f0bSmrg       while (ix < and_elt_ptr->indx);
2488*8feb0f0bSmrg     }
2489*8feb0f0bSmrg 
2490*8feb0f0bSmrg   gcc_checking_assert (!a->current == !a->first);
2491*8feb0f0bSmrg   if (a->current)
2492*8feb0f0bSmrg     a->indx = a->current->indx;
24931debfc3dSmrg   return changed;
24941debfc3dSmrg }
24951debfc3dSmrg 
24961debfc3dSmrg /* A |= (B & C).  Return true if A changes.  */
24971debfc3dSmrg 
24981debfc3dSmrg bool
bitmap_ior_and_into(bitmap a,const_bitmap b,const_bitmap c)24991debfc3dSmrg bitmap_ior_and_into (bitmap a, const_bitmap b, const_bitmap c)
25001debfc3dSmrg {
25011debfc3dSmrg   bitmap_element *a_elt = a->first;
25021debfc3dSmrg   const bitmap_element *b_elt = b->first;
25031debfc3dSmrg   const bitmap_element *c_elt = c->first;
25041debfc3dSmrg   bitmap_element and_elt;
25051debfc3dSmrg   bitmap_element *a_prev = NULL;
25061debfc3dSmrg   bitmap_element **a_prev_pnext = &a->first;
25071debfc3dSmrg   bool changed = false;
25081debfc3dSmrg   unsigned ix;
25091debfc3dSmrg 
2510c0a68be4Smrg   gcc_checking_assert (!a->tree_form && !b->tree_form && !c->tree_form);
2511c0a68be4Smrg 
25121debfc3dSmrg   if (b == c)
25131debfc3dSmrg     return bitmap_ior_into (a, b);
25141debfc3dSmrg   if (bitmap_empty_p (b) || bitmap_empty_p (c))
25151debfc3dSmrg     return false;
25161debfc3dSmrg 
25171debfc3dSmrg   and_elt.indx = -1;
25181debfc3dSmrg   while (b_elt && c_elt)
25191debfc3dSmrg     {
25201debfc3dSmrg       BITMAP_WORD overall;
25211debfc3dSmrg 
25221debfc3dSmrg       /* Find a common item of B and C.  */
25231debfc3dSmrg       while (b_elt->indx != c_elt->indx)
25241debfc3dSmrg 	{
25251debfc3dSmrg           if (b_elt->indx < c_elt->indx)
25261debfc3dSmrg 	    {
25271debfc3dSmrg 	      b_elt = b_elt->next;
25281debfc3dSmrg 	      if (!b_elt)
25291debfc3dSmrg 		goto done;
25301debfc3dSmrg 	    }
25311debfc3dSmrg           else
25321debfc3dSmrg 	    {
25331debfc3dSmrg 	      c_elt = c_elt->next;
25341debfc3dSmrg 	      if (!c_elt)
25351debfc3dSmrg 		goto done;
25361debfc3dSmrg 	    }
25371debfc3dSmrg 	}
25381debfc3dSmrg 
25391debfc3dSmrg       overall = 0;
25401debfc3dSmrg       and_elt.indx = b_elt->indx;
25411debfc3dSmrg       for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
25421debfc3dSmrg 	{
25431debfc3dSmrg 	  and_elt.bits[ix] = b_elt->bits[ix] & c_elt->bits[ix];
25441debfc3dSmrg 	  overall |= and_elt.bits[ix];
25451debfc3dSmrg 	}
25461debfc3dSmrg 
25471debfc3dSmrg       b_elt = b_elt->next;
25481debfc3dSmrg       c_elt = c_elt->next;
25491debfc3dSmrg       if (!overall)
25501debfc3dSmrg 	continue;
25511debfc3dSmrg 
25521debfc3dSmrg       /* Now find a place to insert AND_ELT.  */
25531debfc3dSmrg       do
25541debfc3dSmrg 	{
25551debfc3dSmrg 	  ix = a_elt ? a_elt->indx : and_elt.indx;
25561debfc3dSmrg           if (ix == and_elt.indx)
25571debfc3dSmrg 	    changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, &and_elt, changed);
25581debfc3dSmrg           else if (ix > and_elt.indx)
25591debfc3dSmrg 	    changed = bitmap_elt_copy (a, NULL, a_prev, &and_elt, changed);
25601debfc3dSmrg 
25611debfc3dSmrg           a_prev = *a_prev_pnext;
25621debfc3dSmrg           a_prev_pnext = &a_prev->next;
25631debfc3dSmrg           a_elt = *a_prev_pnext;
25641debfc3dSmrg 
25651debfc3dSmrg           /* If A lagged behind B/C, we advanced it so loop once more.  */
25661debfc3dSmrg 	}
25671debfc3dSmrg       while (ix < and_elt.indx);
25681debfc3dSmrg     }
25691debfc3dSmrg 
25701debfc3dSmrg  done:
25711debfc3dSmrg   gcc_checking_assert (!a->current == !a->first);
25721debfc3dSmrg   if (a->current)
25731debfc3dSmrg     a->indx = a->current->indx;
25741debfc3dSmrg   return changed;
25751debfc3dSmrg }
25761debfc3dSmrg 
25771debfc3dSmrg /* Compute hash of bitmap (for purposes of hashing).  */
2578c0a68be4Smrg 
25791debfc3dSmrg hashval_t
bitmap_hash(const_bitmap head)25801debfc3dSmrg bitmap_hash (const_bitmap head)
25811debfc3dSmrg {
25821debfc3dSmrg   const bitmap_element *ptr;
25831debfc3dSmrg   BITMAP_WORD hash = 0;
25841debfc3dSmrg   int ix;
25851debfc3dSmrg 
2586c0a68be4Smrg   gcc_checking_assert (!head->tree_form);
2587c0a68be4Smrg 
25881debfc3dSmrg   for (ptr = head->first; ptr; ptr = ptr->next)
25891debfc3dSmrg     {
25901debfc3dSmrg       hash ^= ptr->indx;
25911debfc3dSmrg       for (ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
25921debfc3dSmrg 	hash ^= ptr->bits[ix];
25931debfc3dSmrg     }
25941debfc3dSmrg   return (hashval_t)hash;
25951debfc3dSmrg }
25961debfc3dSmrg 
25971debfc3dSmrg 
2598c0a68be4Smrg /* Function to obtain a vector of bitmap elements in bit order from
2599c0a68be4Smrg    HEAD in tree view.  */
2600c0a68be4Smrg 
2601c0a68be4Smrg static void
bitmap_tree_to_vec(vec<bitmap_element * > & elts,const_bitmap head)2602c0a68be4Smrg bitmap_tree_to_vec (vec<bitmap_element *> &elts, const_bitmap head)
2603c0a68be4Smrg {
2604c0a68be4Smrg   gcc_checking_assert (head->tree_form);
2605c0a68be4Smrg   auto_vec<bitmap_element *, 32> stack;
2606c0a68be4Smrg   bitmap_element *e = head->first;
2607c0a68be4Smrg   while (true)
2608c0a68be4Smrg     {
2609c0a68be4Smrg       while (e != NULL)
2610c0a68be4Smrg 	{
2611c0a68be4Smrg 	  stack.safe_push (e);
2612c0a68be4Smrg 	  e = e->prev;
2613c0a68be4Smrg 	}
2614c0a68be4Smrg       if (stack.is_empty ())
2615c0a68be4Smrg 	break;
2616c0a68be4Smrg 
2617c0a68be4Smrg       e = stack.pop ();
2618c0a68be4Smrg       elts.safe_push (e);
2619c0a68be4Smrg       e = e->next;
2620c0a68be4Smrg     }
2621c0a68be4Smrg }
2622c0a68be4Smrg 
2623c0a68be4Smrg /* Debugging function to print out the contents of a bitmap element.  */
26241debfc3dSmrg 
26251debfc3dSmrg DEBUG_FUNCTION void
debug_bitmap_elt_file(FILE * file,const bitmap_element * ptr)2626c0a68be4Smrg debug_bitmap_elt_file (FILE *file, const bitmap_element *ptr)
26271debfc3dSmrg {
26281debfc3dSmrg   unsigned int i, j, col = 26;
26291debfc3dSmrg 
26301debfc3dSmrg   fprintf (file, "\t" HOST_PTR_PRINTF " next = " HOST_PTR_PRINTF
26311debfc3dSmrg 	   " prev = " HOST_PTR_PRINTF " indx = %u\n\t\tbits = {",
26321debfc3dSmrg 	   (const void*) ptr, (const void*) ptr->next,
26331debfc3dSmrg 	   (const void*) ptr->prev, ptr->indx);
26341debfc3dSmrg 
26351debfc3dSmrg   for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
26361debfc3dSmrg     for (j = 0; j < BITMAP_WORD_BITS; j++)
26371debfc3dSmrg       if ((ptr->bits[i] >> j) & 1)
26381debfc3dSmrg 	{
26391debfc3dSmrg 	  if (col > 70)
26401debfc3dSmrg 	    {
26411debfc3dSmrg 	      fprintf (file, "\n\t\t\t");
26421debfc3dSmrg 	      col = 24;
26431debfc3dSmrg 	    }
26441debfc3dSmrg 
26451debfc3dSmrg 	  fprintf (file, " %u", (ptr->indx * BITMAP_ELEMENT_ALL_BITS
26461debfc3dSmrg 				 + i * BITMAP_WORD_BITS + j));
26471debfc3dSmrg 	  col += 4;
26481debfc3dSmrg 	}
26491debfc3dSmrg 
26501debfc3dSmrg   fprintf (file, " }\n");
26511debfc3dSmrg }
2652c0a68be4Smrg 
2653c0a68be4Smrg /* Debugging function to print out the contents of a bitmap.  */
2654c0a68be4Smrg 
2655c0a68be4Smrg DEBUG_FUNCTION void
debug_bitmap_file(FILE * file,const_bitmap head)2656c0a68be4Smrg debug_bitmap_file (FILE *file, const_bitmap head)
2657c0a68be4Smrg {
2658c0a68be4Smrg   const bitmap_element *ptr;
2659c0a68be4Smrg 
2660c0a68be4Smrg   fprintf (file, "\nfirst = " HOST_PTR_PRINTF
2661c0a68be4Smrg 	   " current = " HOST_PTR_PRINTF " indx = %u\n",
2662c0a68be4Smrg 	   (void *) head->first, (void *) head->current, head->indx);
2663c0a68be4Smrg 
2664c0a68be4Smrg   if (head->tree_form)
2665c0a68be4Smrg     {
2666c0a68be4Smrg       auto_vec<bitmap_element *, 32> elts;
2667c0a68be4Smrg       bitmap_tree_to_vec (elts, head);
2668c0a68be4Smrg       for (unsigned i = 0; i < elts.length (); ++i)
2669c0a68be4Smrg 	debug_bitmap_elt_file (file, elts[i]);
2670c0a68be4Smrg     }
2671c0a68be4Smrg   else
2672c0a68be4Smrg     for (ptr = head->first; ptr; ptr = ptr->next)
2673c0a68be4Smrg       debug_bitmap_elt_file (file, ptr);
26741debfc3dSmrg }
26751debfc3dSmrg 
26761debfc3dSmrg /* Function to be called from the debugger to print the contents
26771debfc3dSmrg    of a bitmap.  */
26781debfc3dSmrg 
26791debfc3dSmrg DEBUG_FUNCTION void
debug_bitmap(const_bitmap head)26801debfc3dSmrg debug_bitmap (const_bitmap head)
26811debfc3dSmrg {
26821debfc3dSmrg   debug_bitmap_file (stderr, head);
26831debfc3dSmrg }
26841debfc3dSmrg 
26851debfc3dSmrg /* Function to print out the contents of a bitmap.  Unlike debug_bitmap_file,
26861debfc3dSmrg    it does not print anything but the bits.  */
26871debfc3dSmrg 
26881debfc3dSmrg DEBUG_FUNCTION void
bitmap_print(FILE * file,const_bitmap head,const char * prefix,const char * suffix)26891debfc3dSmrg bitmap_print (FILE *file, const_bitmap head, const char *prefix,
26901debfc3dSmrg 	      const char *suffix)
26911debfc3dSmrg {
26921debfc3dSmrg   const char *comma = "";
26931debfc3dSmrg   unsigned i;
26941debfc3dSmrg 
26951debfc3dSmrg   fputs (prefix, file);
2696c0a68be4Smrg   if (head->tree_form)
2697c0a68be4Smrg     {
2698c0a68be4Smrg       auto_vec<bitmap_element *, 32> elts;
2699c0a68be4Smrg       bitmap_tree_to_vec (elts, head);
2700c0a68be4Smrg       for (i = 0; i < elts.length (); ++i)
2701c0a68be4Smrg 	for (unsigned ix = 0; ix != BITMAP_ELEMENT_WORDS; ++ix)
2702c0a68be4Smrg 	  {
2703c0a68be4Smrg 	    BITMAP_WORD word = elts[i]->bits[ix];
2704c0a68be4Smrg 	    for (unsigned bit = 0; bit != BITMAP_WORD_BITS; ++bit)
2705c0a68be4Smrg 	      if (word & ((BITMAP_WORD)1 << bit))
2706c0a68be4Smrg 		{
2707c0a68be4Smrg 		  fprintf (file, "%s%d", comma,
2708c0a68be4Smrg 			   (bit + BITMAP_WORD_BITS * ix
2709c0a68be4Smrg 			    + elts[i]->indx * BITMAP_ELEMENT_ALL_BITS));
2710c0a68be4Smrg 		  comma = ", ";
2711c0a68be4Smrg 		}
2712c0a68be4Smrg 	  }
2713c0a68be4Smrg     }
2714c0a68be4Smrg   else
2715c0a68be4Smrg     {
2716c0a68be4Smrg       bitmap_iterator bi;
27171debfc3dSmrg       EXECUTE_IF_SET_IN_BITMAP (head, 0, i, bi)
27181debfc3dSmrg 	{
27191debfc3dSmrg 	  fprintf (file, "%s%d", comma, i);
27201debfc3dSmrg 	  comma = ", ";
27211debfc3dSmrg 	}
2722c0a68be4Smrg     }
27231debfc3dSmrg   fputs (suffix, file);
27241debfc3dSmrg }
27251debfc3dSmrg 
27261debfc3dSmrg /* Output per-bitmap memory usage statistics.  */
27271debfc3dSmrg void
dump_bitmap_statistics(void)27281debfc3dSmrg dump_bitmap_statistics (void)
27291debfc3dSmrg {
27301debfc3dSmrg   if (!GATHER_STATISTICS)
27311debfc3dSmrg     return;
27321debfc3dSmrg 
27331debfc3dSmrg   bitmap_mem_desc.dump (BITMAP_ORIGIN);
27341debfc3dSmrg }
27351debfc3dSmrg 
27361debfc3dSmrg DEBUG_FUNCTION void
debug(const bitmap_head & ref)27371debfc3dSmrg debug (const bitmap_head &ref)
27381debfc3dSmrg {
27391debfc3dSmrg   dump_bitmap (stderr, &ref);
27401debfc3dSmrg }
27411debfc3dSmrg 
27421debfc3dSmrg DEBUG_FUNCTION void
debug(const bitmap_head * ptr)27431debfc3dSmrg debug (const bitmap_head *ptr)
27441debfc3dSmrg {
27451debfc3dSmrg   if (ptr)
27461debfc3dSmrg     debug (*ptr);
27471debfc3dSmrg   else
27481debfc3dSmrg     fprintf (stderr, "<nil>\n");
27491debfc3dSmrg }
27501debfc3dSmrg 
2751c0a68be4Smrg void
dump()2752c0a68be4Smrg bitmap_head::dump ()
2753c0a68be4Smrg {
2754c0a68be4Smrg   debug (this);
2755c0a68be4Smrg }
2756c0a68be4Smrg 
27571debfc3dSmrg #if CHECKING_P
27581debfc3dSmrg 
27591debfc3dSmrg namespace selftest {
27601debfc3dSmrg 
27611debfc3dSmrg /* Selftests for bitmaps.  */
27621debfc3dSmrg 
27631debfc3dSmrg /* Freshly-created bitmaps ought to be empty.  */
27641debfc3dSmrg 
27651debfc3dSmrg static void
test_gc_alloc()27661debfc3dSmrg test_gc_alloc ()
27671debfc3dSmrg {
27681debfc3dSmrg   bitmap b = bitmap_gc_alloc ();
27691debfc3dSmrg   ASSERT_TRUE (bitmap_empty_p (b));
27701debfc3dSmrg }
27711debfc3dSmrg 
27721debfc3dSmrg /* Verify bitmap_set_range.  */
27731debfc3dSmrg 
27741debfc3dSmrg static void
test_set_range()27751debfc3dSmrg test_set_range ()
27761debfc3dSmrg {
27771debfc3dSmrg   bitmap b = bitmap_gc_alloc ();
27781debfc3dSmrg   ASSERT_TRUE (bitmap_empty_p (b));
27791debfc3dSmrg 
27801debfc3dSmrg   bitmap_set_range (b, 7, 5);
27811debfc3dSmrg   ASSERT_FALSE (bitmap_empty_p (b));
27821debfc3dSmrg   ASSERT_EQ (5, bitmap_count_bits (b));
27831debfc3dSmrg 
27841debfc3dSmrg   /* Verify bitmap_bit_p at the boundaries.  */
27851debfc3dSmrg   ASSERT_FALSE (bitmap_bit_p (b, 6));
27861debfc3dSmrg   ASSERT_TRUE (bitmap_bit_p (b, 7));
27871debfc3dSmrg   ASSERT_TRUE (bitmap_bit_p (b, 11));
27881debfc3dSmrg   ASSERT_FALSE (bitmap_bit_p (b, 12));
27891debfc3dSmrg }
27901debfc3dSmrg 
27911debfc3dSmrg /* Verify splitting a range into two pieces using bitmap_clear_bit.  */
27921debfc3dSmrg 
27931debfc3dSmrg static void
test_clear_bit_in_middle()27941debfc3dSmrg test_clear_bit_in_middle ()
27951debfc3dSmrg {
27961debfc3dSmrg   bitmap b = bitmap_gc_alloc ();
27971debfc3dSmrg 
27981debfc3dSmrg   /* Set b to [100..200].  */
27991debfc3dSmrg   bitmap_set_range (b, 100, 100);
28001debfc3dSmrg   ASSERT_EQ (100, bitmap_count_bits (b));
28011debfc3dSmrg 
28021debfc3dSmrg   /* Clear a bit in the middle.  */
28031debfc3dSmrg   bool changed = bitmap_clear_bit (b, 150);
28041debfc3dSmrg   ASSERT_TRUE (changed);
28051debfc3dSmrg   ASSERT_EQ (99, bitmap_count_bits (b));
28061debfc3dSmrg   ASSERT_TRUE (bitmap_bit_p (b, 149));
28071debfc3dSmrg   ASSERT_FALSE (bitmap_bit_p (b, 150));
28081debfc3dSmrg   ASSERT_TRUE (bitmap_bit_p (b, 151));
28091debfc3dSmrg }
28101debfc3dSmrg 
28111debfc3dSmrg /* Verify bitmap_copy.  */
28121debfc3dSmrg 
28131debfc3dSmrg static void
test_copying()28141debfc3dSmrg test_copying ()
28151debfc3dSmrg {
28161debfc3dSmrg   bitmap src = bitmap_gc_alloc ();
28171debfc3dSmrg   bitmap_set_range (src, 40, 10);
28181debfc3dSmrg 
28191debfc3dSmrg   bitmap dst = bitmap_gc_alloc ();
28201debfc3dSmrg   ASSERT_FALSE (bitmap_equal_p (src, dst));
28211debfc3dSmrg   bitmap_copy (dst, src);
28221debfc3dSmrg   ASSERT_TRUE (bitmap_equal_p (src, dst));
28231debfc3dSmrg 
28241debfc3dSmrg   /* Verify that we can make them unequal again...  */
28251debfc3dSmrg   bitmap_set_range (src, 70, 5);
28261debfc3dSmrg   ASSERT_FALSE (bitmap_equal_p (src, dst));
28271debfc3dSmrg 
28281debfc3dSmrg   /* ...and that changing src after the copy didn't affect
28291debfc3dSmrg      the other: */
28301debfc3dSmrg   ASSERT_FALSE (bitmap_bit_p (dst, 70));
28311debfc3dSmrg }
28321debfc3dSmrg 
28331debfc3dSmrg /* Verify bitmap_single_bit_set_p.  */
28341debfc3dSmrg 
28351debfc3dSmrg static void
test_bitmap_single_bit_set_p()28361debfc3dSmrg test_bitmap_single_bit_set_p ()
28371debfc3dSmrg {
28381debfc3dSmrg   bitmap b = bitmap_gc_alloc ();
28391debfc3dSmrg 
28401debfc3dSmrg   ASSERT_FALSE (bitmap_single_bit_set_p (b));
28411debfc3dSmrg 
28421debfc3dSmrg   bitmap_set_range (b, 42, 1);
28431debfc3dSmrg   ASSERT_TRUE (bitmap_single_bit_set_p (b));
28441debfc3dSmrg   ASSERT_EQ (42, bitmap_first_set_bit (b));
28451debfc3dSmrg 
28461debfc3dSmrg   bitmap_set_range (b, 1066, 1);
28471debfc3dSmrg   ASSERT_FALSE (bitmap_single_bit_set_p (b));
28481debfc3dSmrg   ASSERT_EQ (42, bitmap_first_set_bit (b));
28491debfc3dSmrg 
28501debfc3dSmrg   bitmap_clear_range (b, 0, 100);
28511debfc3dSmrg   ASSERT_TRUE (bitmap_single_bit_set_p (b));
28521debfc3dSmrg   ASSERT_EQ (1066, bitmap_first_set_bit (b));
28531debfc3dSmrg }
28541debfc3dSmrg 
28551debfc3dSmrg /* Run all of the selftests within this file.  */
28561debfc3dSmrg 
28571debfc3dSmrg void
bitmap_c_tests()28581debfc3dSmrg bitmap_c_tests ()
28591debfc3dSmrg {
28601debfc3dSmrg   test_gc_alloc ();
28611debfc3dSmrg   test_set_range ();
28621debfc3dSmrg   test_clear_bit_in_middle ();
28631debfc3dSmrg   test_copying ();
28641debfc3dSmrg   test_bitmap_single_bit_set_p ();
28651debfc3dSmrg }
28661debfc3dSmrg 
28671debfc3dSmrg } // namespace selftest
28681debfc3dSmrg #endif /* CHECKING_P */
28691debfc3dSmrg 
28701debfc3dSmrg #include "gt-bitmap.h"
2871