/* Functions to support general ended bitmaps.
   Copyright (C) 1997-2022 Free Software Foundation, Inc.

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "bitmap.h"
#include "selftest.h"

/* Memory allocation statistics purpose instance.  */
mem_alloc_description<bitmap_usage> bitmap_mem_desc;

/* Static zero-initialized bitmap obstack used for default initialization
   of bitmap_head.  */
bitmap_obstack bitmap_head::crashme;

static bitmap_element *bitmap_tree_listify_from (bitmap, bitmap_element *);

/* Register new bitmap.  */
void
bitmap_register (bitmap b MEM_STAT_DECL)
{
  static unsigned alloc_descriptor_max_uid = 1;
  gcc_assert (b->alloc_descriptor == 0);
  b->alloc_descriptor = alloc_descriptor_max_uid++;

  bitmap_mem_desc.register_descriptor (b->get_descriptor (), BITMAP_ORIGIN,
				       false FINAL_PASS_MEM_STAT);
}

/* Account the overhead.  */
static void
register_overhead (bitmap b, size_t amount)
{
  unsigned *d = b->get_descriptor ();
  if (bitmap_mem_desc.contains_descriptor_for_instance (d))
    bitmap_mem_desc.register_instance_overhead (amount, d);
}

/* Release the overhead.  */
static void
release_overhead (bitmap b, size_t amount, bool remove_from_map)
{
  unsigned *d = b->get_descriptor ();
  if (bitmap_mem_desc.contains_descriptor_for_instance (d))
    bitmap_mem_desc.release_instance_overhead (d, amount, remove_from_map);
}


/* Global data */
bitmap_element bitmap_zero_bits;  /* An element of all zero bits.  */
bitmap_obstack bitmap_default_obstack;    /* The default bitmap obstack.  */
static int bitmap_default_obstack_depth;
static GTY((deletable)) bitmap_element *bitmap_ggc_free; /* Freelist of
							    GC'd elements.  */


/* Bitmap memory management.  */

/* Add ELT to the appropriate freelist.  */
static inline void
bitmap_elem_to_freelist (bitmap head, bitmap_element *elt)
{
  bitmap_obstack *bit_obstack = head->obstack;

  if (GATHER_STATISTICS)
    release_overhead (head, sizeof (bitmap_element), false);

  elt->next = NULL;
  elt->indx = -1;
  if (bit_obstack)
    {
      elt->prev = bit_obstack->elements;
      bit_obstack->elements = elt;
    }
  else
    {
      elt->prev = bitmap_ggc_free;
      bitmap_ggc_free = elt;
    }
}

/* Allocate a bitmap element.  The bits are cleared, but nothing else is.  */

static inline bitmap_element *
bitmap_element_allocate (bitmap head)
{
  bitmap_element *element;
  bitmap_obstack *bit_obstack = head->obstack;

  if (bit_obstack)
    {
      element = bit_obstack->elements;

      if (element)
	/* Use up the inner list first before looking at the next
	   element of the outer list.  */
	if (element->next)
	  {
	    bit_obstack->elements = element->next;
	    bit_obstack->elements->prev = element->prev;
	  }
	else
	  /*  Inner list was just a singleton.  */
	  bit_obstack->elements = element->prev;
      else
	element = XOBNEW (&bit_obstack->obstack, bitmap_element);
    }
  else
    {
      element = bitmap_ggc_free;
      if (element)
	/* Use up the inner list first before looking at the next
	   element of the outer list.  */
	if (element->next)
	  {
	    bitmap_ggc_free = element->next;
	    bitmap_ggc_free->prev = element->prev;
	  }
	else
	  /*  Inner list was just a singleton.  */
	  bitmap_ggc_free = element->prev;
      else
	element = ggc_alloc<bitmap_element> ();
    }

  if (GATHER_STATISTICS)
    register_overhead (head, sizeof (bitmap_element));

  memset (element->bits, 0, sizeof (element->bits));

  return element;
}

/* Remove ELT and all following elements from bitmap HEAD.
   Put the released elements in the freelist for HEAD.  */

void
bitmap_elt_clear_from (bitmap head, bitmap_element *elt)
{
  bitmap_element *prev;
  bitmap_obstack *bit_obstack = head->obstack;

  if (!elt)
    return;

  if (head->tree_form)
    elt = bitmap_tree_listify_from (head, elt);

  if (GATHER_STATISTICS)
    {
      int n = 0;
      for (prev = elt; prev; prev = prev->next)
	n++;
      release_overhead (head, sizeof (bitmap_element) * n, false);
    }

  prev = elt->prev;
  if (prev)
    {
      prev->next = NULL;
      if (head->current->indx > prev->indx)
	{
	  head->current = prev;
	  head->indx = prev->indx;
	}
    }
  else
    {
      head->first = NULL;
      head->current = NULL;
      head->indx = 0;
    }

  /* Put the entire list onto the freelist in one operation. */
  if (bit_obstack)
    {
      elt->prev = bit_obstack->elements;
      bit_obstack->elements = elt;
    }
  else
    {
      elt->prev = bitmap_ggc_free;
      bitmap_ggc_free = elt;
    }
}

/* Linked-list view of bitmaps.

   In this representation, the bitmap elements form a double-linked list
   with elements sorted by increasing index.  */

/* Link the bitmap element into the current bitmap linked list.  */

static inline void
bitmap_list_link_element (bitmap head, bitmap_element *element)
{
  unsigned int indx = element->indx;
  bitmap_element *ptr;

  gcc_checking_assert (!head->tree_form);

  /* If this is the first and only element, set it in.  */
  if (head->first == 0)
    {
      element->next = element->prev = 0;
      head->first = element;
    }

  /* If this index is less than that of the current element, it goes someplace
     before the current element.  */
  else if (indx < head->indx)
    {
      for (ptr = head->current;
	   ptr->prev != 0 && ptr->prev->indx > indx;
	   ptr = ptr->prev)
	;

      if (ptr->prev)
	ptr->prev->next = element;
      else
	head->first = element;

      element->prev = ptr->prev;
      element->next = ptr;
      ptr->prev = element;
    }

  /* Otherwise, it must go someplace after the current element.  */
  else
    {
      for (ptr = head->current;
	   ptr->next != 0 && ptr->next->indx < indx;
	   ptr = ptr->next)
	;

      if (ptr->next)
	ptr->next->prev = element;

      element->next = ptr->next;
      element->prev = ptr;
      ptr->next = element;
    }

  /* Set up so this is the first element searched.  */
  head->current = element;
  head->indx = indx;
}

/* Unlink the bitmap element from the current bitmap linked list,
   and return it to the freelist.  */

static inline void
bitmap_list_unlink_element (bitmap head, bitmap_element *element,
			    bool to_freelist = true)
{
  bitmap_element *next = element->next;
  bitmap_element *prev = element->prev;

  gcc_checking_assert (!head->tree_form);

  if (prev)
    prev->next = next;

  if (next)
    next->prev = prev;

  if (head->first == element)
    head->first = next;

  /* Since the first thing we try is to insert before current,
     make current the next entry in preference to the previous.  */
  if (head->current == element)
    {
      head->current = next != 0 ? next : prev;
      if (head->current)
	head->indx = head->current->indx;
      else
	head->indx = 0;
    }

  if (to_freelist)
    bitmap_elem_to_freelist (head, element);
}

/* Insert a new uninitialized element (or NODE if not NULL) into bitmap
   HEAD after element ELT.  If ELT is NULL, insert the element at the start.
   Return the new element.  */

static bitmap_element *
bitmap_list_insert_element_after (bitmap head,
				  bitmap_element *elt, unsigned int indx,
				  bitmap_element *node = NULL)
{
  if (!node)
    node = bitmap_element_allocate (head);
  node->indx = indx;

  gcc_checking_assert (!head->tree_form);

  if (!elt)
    {
      if (!head->current)
	{
	  head->current = node;
	  head->indx = indx;
	}
      node->next = head->first;
      if (node->next)
	node->next->prev = node;
      head->first = node;
      node->prev = NULL;
    }
  else
    {
      gcc_checking_assert (head->current);
      node->next = elt->next;
      if (node->next)
	node->next->prev = node;
      elt->next = node;
      node->prev = elt;
    }
  return node;
}

/* Return the element for INDX, or NULL if the element doesn't exist.
   Update the `current' field even if we can't find an element that  
   would hold the bitmap's bit to make eventual allocation
   faster.  */

static inline bitmap_element *
bitmap_list_find_element (bitmap head, unsigned int indx)
{
  bitmap_element *element;

  if (head->current == NULL
      || head->indx == indx)
    return head->current;

  if (head->current == head->first
      && head->first->next == NULL)
    return NULL;

  /* Usage can be NULL due to allocated bitmaps for which we do not
     call initialize function.  */
  bitmap_usage *usage = NULL;
  if (GATHER_STATISTICS)
    usage = bitmap_mem_desc.get_descriptor_for_instance (head);

  /* This bitmap has more than one element, and we're going to look
     through the elements list.  Count that as a search.  */
  if (GATHER_STATISTICS && usage)
    usage->m_nsearches++;

  if (head->indx < indx)
    /* INDX is beyond head->indx.  Search from head->current
       forward.  */
    for (element = head->current;
	 element->next != 0 && element->indx < indx;
	 element = element->next)
      {
	if (GATHER_STATISTICS && usage)
	  usage->m_search_iter++;
      }

  else if (head->indx / 2 < indx)
    /* INDX is less than head->indx and closer to head->indx than to
       0.  Search from head->current backward.  */
    for (element = head->current;
	 element->prev != 0 && element->indx > indx;
	 element = element->prev)
      {
	if (GATHER_STATISTICS && usage)
	  usage->m_search_iter++;
      }

  else
    /* INDX is less than head->indx and closer to 0 than to
       head->indx.  Search from head->first forward.  */
    for (element = head->first;
	 element->next != 0 && element->indx < indx;
	 element = element->next)
      {
	if (GATHER_STATISTICS && usage)
	  usage->m_search_iter++;
      }

  /* `element' is the nearest to the one we want.  If it's not the one we
     want, the one we want doesn't exist.  */
  gcc_checking_assert (element != NULL);
  head->current = element;
  head->indx = element->indx;
  if (element->indx != indx)
    element = 0;
  return element;
}


/* Splay-tree view of bitmaps.

   This is an almost one-to-one the implementatin of the simple top-down
   splay tree in Sleator and Tarjan's "Self-adjusting Binary Search Trees".
   It is probably not the most efficient form of splay trees, but it should
   be good enough to experiment with this idea of bitmaps-as-trees.
   
   For all functions below, the variable or function argument "t" is a node
   in the tree, and "e" is a temporary or new node in the tree.  The rest
   is sufficiently straigh-forward (and very well explained in the paper)
   that comment would only clutter things.  */

static inline void
bitmap_tree_link_left (bitmap_element * &t, bitmap_element * &l)
{
  l->next = t;
  l = t;
  t = t->next;
}

static inline void
bitmap_tree_link_right (bitmap_element * &t, bitmap_element * &r)
{
  r->prev = t;
  r = t;
  t = t->prev;
}

static inline void
bitmap_tree_rotate_left (bitmap_element * &t)
{
  bitmap_element *e = t->next;
  t->next = t->next->prev;
  e->prev = t;
  t = e;
}

static inline void
bitmap_tree_rotate_right (bitmap_element * &t)
{
  bitmap_element *e = t->prev;
  t->prev = t->prev->next;
  e->next = t;
  t = e;
}

static bitmap_element *
bitmap_tree_splay (bitmap head, bitmap_element *t, unsigned int indx)
{
  bitmap_element N, *l, *r;

  if (t == NULL)
    return NULL;

  bitmap_usage *usage = NULL;
  if (GATHER_STATISTICS)
    usage = bitmap_mem_desc.get_descriptor_for_instance (head);

  N.prev = N.next = NULL;
  l = r = &N;

  while (indx != t->indx)
    {
      if (GATHER_STATISTICS && usage)
	usage->m_search_iter++;

      if (indx < t->indx)
	{
	  if (t->prev != NULL && indx < t->prev->indx)
	    bitmap_tree_rotate_right (t);
	  if (t->prev == NULL)
	    break;
	  bitmap_tree_link_right (t, r);
	}
      else if (indx > t->indx)
	{
	  if (t->next != NULL && indx > t->next->indx)
	    bitmap_tree_rotate_left (t);
	  if (t->next == NULL)
	    break;
	  bitmap_tree_link_left (t, l);
	}
    }

  l->next = t->prev;
  r->prev = t->next;
  t->prev = N.next;
  t->next = N.prev;
  return t;
}

/* Link bitmap element E into the current bitmap splay tree.  */

static inline void
bitmap_tree_link_element (bitmap head, bitmap_element *e)
{
  if (head->first == NULL)
    e->prev = e->next = NULL;
  else
    {
      bitmap_element *t = bitmap_tree_splay (head, head->first, e->indx);
      if (e->indx < t->indx)
	{
	  e->prev = t->prev;
	  e->next = t;
	  t->prev = NULL;
	}
      else if (e->indx > t->indx)
	{
	  e->next = t->next;
	  e->prev = t;
	  t->next = NULL;
	}
      else
	gcc_unreachable ();
    }
  head->first = e;
  head->current = e;
  head->indx = e->indx;
}

/* Unlink bitmap element E from the current bitmap splay tree,
   and return it to the freelist.  */

static void
bitmap_tree_unlink_element (bitmap head, bitmap_element *e)
{
  bitmap_element *t = bitmap_tree_splay (head, head->first, e->indx);

  gcc_checking_assert (t == e);

  if (e->prev == NULL)
    t = e->next;
  else
    {
      t = bitmap_tree_splay (head, e->prev, e->indx);
      t->next = e->next;
    }
  head->first = t;
  head->current = t;
  head->indx = (t != NULL) ? t->indx : 0;

  bitmap_elem_to_freelist (head, e);
}

/* Return the element for INDX, or NULL if the element doesn't exist.  */

static inline bitmap_element *
bitmap_tree_find_element (bitmap head, unsigned int indx)
{
  if (head->current == NULL
      || head->indx == indx)
    return head->current;

  /* Usage can be NULL due to allocated bitmaps for which we do not
     call initialize function.  */
  bitmap_usage *usage = NULL;
  if (GATHER_STATISTICS)
    usage = bitmap_mem_desc.get_descriptor_for_instance (head);

  /* This bitmap has more than one element, and we're going to look
     through the elements list.  Count that as a search.  */
  if (GATHER_STATISTICS && usage)
    usage->m_nsearches++;

  bitmap_element *element = bitmap_tree_splay (head, head->first, indx);
  gcc_checking_assert (element != NULL);
  head->first = element;
  head->current = element;
  head->indx = element->indx;
  if (element->indx != indx)
    element = 0;
  return element;
}

/* Converting bitmap views from linked-list to tree and vice versa.  */

/* Splice element E and all elements with a larger index from
   bitmap HEAD, convert the spliced elements to the linked-list
   view, and return the head of the list (which should be E again),  */

static bitmap_element *
bitmap_tree_listify_from (bitmap head, bitmap_element *e)
{
  bitmap_element *t, *erb;

  /* Detach the right branch from E (all elements with indx > E->indx),
     and splay E to the root.  */
  erb = e->next;
  e->next = NULL;
  t = bitmap_tree_splay (head, head->first, e->indx);
  gcc_checking_assert (t == e);

  /* Because E has no right branch, and we rotated it to the root,
     the left branch is the new root.  */
  t = e->prev;
  head->first = t;
  head->current = t;
  head->indx = (t != NULL) ? t->indx : 0;

  /* Detach the tree from E, and re-attach the right branch of E.  */
  e->prev = NULL;
  e->next = erb;

  /* The tree is now valid again.  Now we need to "un-tree" E.
     It is imperative that a non-recursive implementation is used
     for this, because splay trees have a worst case depth of O(N)
     for a tree with N nodes.  A recursive implementation could
     result in a stack overflow for a sufficiently large, unbalanced
     bitmap tree.  */

  auto_vec<bitmap_element *, 32> stack;
  auto_vec<bitmap_element *, 32> sorted_elements;
  bitmap_element *n = e;

  while (true)
    {
      while (n != NULL)
	{
	  stack.safe_push (n);
	  n = n->prev;
	}

      if (stack.is_empty ())
	break;

      n = stack.pop ();
      sorted_elements.safe_push (n);
      n = n->next;
    }

  gcc_assert (sorted_elements[0] == e);

  bitmap_element *prev = NULL;
  unsigned ix;
  FOR_EACH_VEC_ELT (sorted_elements, ix, n)
    {
      if (prev != NULL)
        prev->next = n;
      n->prev = prev;
      n->next = NULL;
      prev = n;
    }

  return e;
}

/* Convert bitmap HEAD from splay-tree view to linked-list view.  */

void
bitmap_list_view (bitmap head)
{
  bitmap_element *ptr;

  gcc_assert (head->tree_form);

  ptr = head->first;
  if (ptr)
    {
      while (ptr->prev)
	bitmap_tree_rotate_right (ptr);
      head->first = ptr;
      head->first = bitmap_tree_listify_from (head, ptr);
    }

  head->tree_form = false;
  if (!head->current)
    {
      head->current = head->first;
      head->indx = head->current ? head->current->indx : 0;
    }
}

/* Convert bitmap HEAD from linked-list view to splay-tree view.
   This is simply a matter of dropping the prev or next pointers
   and setting the tree_form flag.  The tree will balance itself
   if and when it is used.  */

void
bitmap_tree_view (bitmap head)
{
  bitmap_element *ptr;

  gcc_assert (! head->tree_form);

  ptr = head->first;
  while (ptr)
    {
      ptr->prev = NULL;
      ptr = ptr->next;
    }

  head->tree_form = true;
}

/* Clear a bitmap by freeing all its elements.  */

void
bitmap_clear (bitmap head)
{
  if (head->first == NULL)
    return;
  if (head->tree_form)
    {
      bitmap_element *e, *t;
      for (e = head->first; e->prev; e = e->prev)
	/* Loop to find the element with the smallest index.  */ ;
      t = bitmap_tree_splay (head, head->first, e->indx);
      gcc_checking_assert (t == e);
      head->first = t;
    }
  bitmap_elt_clear_from (head, head->first);
}

/* Initialize a bitmap obstack.  If BIT_OBSTACK is NULL, initialize
   the default bitmap obstack.  */

void
bitmap_obstack_initialize (bitmap_obstack *bit_obstack)
{
  if (!bit_obstack)
    {
      if (bitmap_default_obstack_depth++)
	return;
      bit_obstack = &bitmap_default_obstack;
    }

#if !defined(__GNUC__) || (__GNUC__ < 2)
#define __alignof__(type) 0
#endif

  bit_obstack->elements = NULL;
  bit_obstack->heads = NULL;
  obstack_specify_allocation (&bit_obstack->obstack, OBSTACK_CHUNK_SIZE,
			      __alignof__ (bitmap_element),
			      obstack_chunk_alloc,
			      obstack_chunk_free);
}

/* Release the memory from a bitmap obstack.  If BIT_OBSTACK is NULL,
   release the default bitmap obstack.  */

void
bitmap_obstack_release (bitmap_obstack *bit_obstack)
{
  if (!bit_obstack)
    {
      if (--bitmap_default_obstack_depth)
	{
	  gcc_assert (bitmap_default_obstack_depth > 0);
	  return;
	}
      bit_obstack = &bitmap_default_obstack;
    }

  bit_obstack->elements = NULL;
  bit_obstack->heads = NULL;
  obstack_free (&bit_obstack->obstack, NULL);
}

/* Create a new bitmap on an obstack.  If BIT_OBSTACK is NULL, create
   it on the default bitmap obstack.  */

bitmap
bitmap_alloc (bitmap_obstack *bit_obstack MEM_STAT_DECL)
{
  bitmap map;

  if (!bit_obstack)
    bit_obstack = &bitmap_default_obstack;
  map = bit_obstack->heads;
  if (map)
    bit_obstack->heads = (class bitmap_head *) map->first;
  else
    map = XOBNEW (&bit_obstack->obstack, bitmap_head);
  bitmap_initialize (map, bit_obstack PASS_MEM_STAT);

  if (GATHER_STATISTICS)
    register_overhead (map, sizeof (bitmap_head));

  return map;
}

/* Create a new GCd bitmap.  */

bitmap
bitmap_gc_alloc (ALONE_MEM_STAT_DECL)
{
  bitmap map;

  map = ggc_alloc<bitmap_head> ();
  bitmap_initialize (map, NULL PASS_MEM_STAT);

  if (GATHER_STATISTICS)
    register_overhead (map, sizeof (bitmap_head));

  return map;
}

/* Release an obstack allocated bitmap.  */

void
bitmap_obstack_free (bitmap map)
{
  if (map)
    {
      bitmap_clear (map);
      map->first = (bitmap_element *) map->obstack->heads;

      if (GATHER_STATISTICS)
	release_overhead (map, sizeof (bitmap_head), true);

      map->obstack->heads = map;
    }
}


/* Return nonzero if all bits in an element are zero.  */

static inline int
bitmap_element_zerop (const bitmap_element *element)
{
#if BITMAP_ELEMENT_WORDS == 2
  return (element->bits[0] | element->bits[1]) == 0;
#else
  unsigned i;

  for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
    if (element->bits[i] != 0)
      return 0;

  return 1;
#endif
}

/* Copy a bitmap to another bitmap.  */

void
bitmap_copy (bitmap to, const_bitmap from)
{
  const bitmap_element *from_ptr;
  bitmap_element *to_ptr = 0;

  gcc_checking_assert (!to->tree_form && !from->tree_form);

  bitmap_clear (to);

  /* Copy elements in forward direction one at a time.  */
  for (from_ptr = from->first; from_ptr; from_ptr = from_ptr->next)
    {
      bitmap_element *to_elt = bitmap_element_allocate (to);

      to_elt->indx = from_ptr->indx;
      memcpy (to_elt->bits, from_ptr->bits, sizeof (to_elt->bits));

      /* Here we have a special case of bitmap_list_link_element,
         for the case where we know the links are being entered
	 in sequence.  */
      if (to_ptr == 0)
	{
	  to->first = to->current = to_elt;
	  to->indx = from_ptr->indx;
	  to_elt->next = to_elt->prev = 0;
	}
      else
	{
	  to_elt->prev = to_ptr;
	  to_elt->next = 0;
	  to_ptr->next = to_elt;
	}

      to_ptr = to_elt;
    }
}

/* Move a bitmap to another bitmap.  */

void
bitmap_move (bitmap to, bitmap from)
{
  gcc_assert (to->obstack == from->obstack);

  bitmap_clear (to);

  size_t sz = 0;
  if (GATHER_STATISTICS)
    {
      for (bitmap_element *e = to->first; e; e = e->next)
	sz += sizeof (bitmap_element);
      register_overhead (to, sz);
    }

  *to = *from;

  if (GATHER_STATISTICS)
    release_overhead (from, sz, false);
}

/* Clear a single bit in a bitmap.  Return true if the bit changed.  */

bool
bitmap_clear_bit (bitmap head, int bit)
{
  unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
  bitmap_element *ptr;

  if (!head->tree_form)
    ptr = bitmap_list_find_element (head, indx);
  else
    ptr = bitmap_tree_find_element (head, indx);
  if (ptr != 0)
    {
      unsigned bit_num  = bit % BITMAP_WORD_BITS;
      unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
      BITMAP_WORD bit_val = ((BITMAP_WORD) 1) << bit_num;
      bool res = (ptr->bits[word_num] & bit_val) != 0;
      if (res)
	{
	  ptr->bits[word_num] &= ~bit_val;
	  /* If we cleared the entire word, free up the element.  */
	  if (!ptr->bits[word_num]
	      && bitmap_element_zerop (ptr))
	    {
	      if (!head->tree_form)
		bitmap_list_unlink_element (head, ptr);
	      else
		bitmap_tree_unlink_element (head, ptr);
	    }
	}

      return res;
    }

  return false;
}

/* Set a single bit in a bitmap.  Return true if the bit changed.  */

bool
bitmap_set_bit (bitmap head, int bit)
{
  unsigned indx = bit / BITMAP_ELEMENT_ALL_BITS;
  bitmap_element *ptr;
  if (!head->tree_form)
    ptr = bitmap_list_find_element (head, indx);
  else
    ptr = bitmap_tree_find_element (head, indx);
  unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
  unsigned bit_num  = bit % BITMAP_WORD_BITS;
  BITMAP_WORD bit_val = ((BITMAP_WORD) 1) << bit_num;

  if (ptr != 0)
    {
      bool res = (ptr->bits[word_num] & bit_val) == 0;
      if (res)
	ptr->bits[word_num] |= bit_val;
      return res;
    }

  ptr = bitmap_element_allocate (head);
  ptr->indx = bit / BITMAP_ELEMENT_ALL_BITS;
  ptr->bits[word_num] = bit_val;
  if (!head->tree_form)
    bitmap_list_link_element (head, ptr);
  else
    bitmap_tree_link_element (head, ptr);
  return true;
}

/* Return whether a bit is set within a bitmap.  */

bool
bitmap_bit_p (const_bitmap head, int bit)
{
  unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
  const bitmap_element *ptr;
  unsigned bit_num;
  unsigned word_num;

  if (!head->tree_form)
    ptr = bitmap_list_find_element (const_cast<bitmap> (head), indx);
  else
    ptr = bitmap_tree_find_element (const_cast<bitmap> (head), indx);
  if (ptr == 0)
    return 0;

  bit_num = bit % BITMAP_WORD_BITS;
  word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;

  return (ptr->bits[word_num] >> bit_num) & 1;
}

/* Set CHUNK_SIZE bits at a time in bitmap HEAD.
   Store CHUNK_VALUE starting at bits CHUNK * chunk_size.
   This is the set routine for viewing bitmap as a multi-bit sparse array.  */

void
bitmap_set_aligned_chunk (bitmap head, unsigned int chunk,
			  unsigned int chunk_size, BITMAP_WORD chunk_value)
{
  // Ensure chunk size is a power of 2 and fits in BITMAP_WORD.
  gcc_checking_assert (pow2p_hwi (chunk_size));
  gcc_checking_assert (chunk_size < (sizeof (BITMAP_WORD) * CHAR_BIT));

  // Ensure chunk_value is within range of chunk_size bits.
  BITMAP_WORD max_value = (1 << chunk_size) - 1;
  gcc_checking_assert (chunk_value <= max_value);

  unsigned bit = chunk * chunk_size;
  unsigned indx = bit / BITMAP_ELEMENT_ALL_BITS;
  bitmap_element *ptr;
  if (!head->tree_form)
    ptr = bitmap_list_find_element (head, indx);
  else
    ptr = bitmap_tree_find_element (head, indx);
  unsigned word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;
  unsigned bit_num  = bit % BITMAP_WORD_BITS;
  BITMAP_WORD bit_val = chunk_value << bit_num;
  BITMAP_WORD mask = ~(max_value << bit_num);

  if (ptr != 0)
    {
      ptr->bits[word_num] &= mask;
      ptr->bits[word_num] |= bit_val;
      return;
    }

  ptr = bitmap_element_allocate (head);
  ptr->indx = bit / BITMAP_ELEMENT_ALL_BITS;
  ptr->bits[word_num] = bit_val;
  if (!head->tree_form)
    bitmap_list_link_element (head, ptr);
  else
    bitmap_tree_link_element (head, ptr);
}

/* This is the get routine for viewing bitmap as a multi-bit sparse array.
   Return a set of CHUNK_SIZE consecutive bits from HEAD, starting at bit
   CHUNK * chunk_size.   */

BITMAP_WORD
bitmap_get_aligned_chunk (const_bitmap head, unsigned int chunk,
			  unsigned int chunk_size)
{
  // Ensure chunk size is a power of 2, fits in BITMAP_WORD and is in range.
  gcc_checking_assert (pow2p_hwi (chunk_size));
  gcc_checking_assert (chunk_size < (sizeof (BITMAP_WORD) * CHAR_BIT));

  BITMAP_WORD max_value = (1 << chunk_size) - 1;
  unsigned bit = chunk * chunk_size;
  unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
  const bitmap_element *ptr;
  unsigned bit_num;
  unsigned word_num;

  if (!head->tree_form)
    ptr = bitmap_list_find_element (const_cast<bitmap> (head), indx);
  else
    ptr = bitmap_tree_find_element (const_cast<bitmap> (head), indx);
  if (ptr == 0)
    return 0;

  bit_num = bit % BITMAP_WORD_BITS;
  word_num = bit / BITMAP_WORD_BITS % BITMAP_ELEMENT_WORDS;

  // Return 4 bits.
  return (ptr->bits[word_num] >> bit_num) & max_value;
}

#if GCC_VERSION < 3400
/* Table of number of set bits in a character, indexed by value of char.  */
static const unsigned char popcount_table[] =
{
    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,
    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,
    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,
    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,
    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,
    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,
    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,
    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,
};

static unsigned long
bitmap_popcount (BITMAP_WORD a)
{
  unsigned long ret = 0;
  unsigned i;

  /* Just do this the table way for now  */
  for (i = 0; i < BITMAP_WORD_BITS; i+= 8)
    ret += popcount_table[(a >> i) & 0xff];
  return ret;
}
#endif

/* Count and return the number of bits set in the bitmap word BITS.  */
static unsigned long
bitmap_count_bits_in_word (const BITMAP_WORD *bits)
{
  unsigned long count = 0;

  for (unsigned ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
    {
#if GCC_VERSION >= 3400
      /* Note that popcountl matches BITMAP_WORD in type, so the actual size
	 of BITMAP_WORD is not material.  */
      count += __builtin_popcountl (bits[ix]);
#else
      count += bitmap_popcount (bits[ix]);
#endif
    }
  return count;
}

/* Count the number of bits set in the bitmap, and return it.  */

unsigned long
bitmap_count_bits (const_bitmap a)
{
  unsigned long count = 0;
  const bitmap_element *elt;

  gcc_checking_assert (!a->tree_form);
  for (elt = a->first; elt; elt = elt->next)
    count += bitmap_count_bits_in_word (elt->bits);

  return count;
}

/* Count the number of unique bits set in A and B and return it.  */

unsigned long
bitmap_count_unique_bits (const_bitmap a, const_bitmap b)
{
  unsigned long count = 0;
  const bitmap_element *elt_a, *elt_b;

  for (elt_a = a->first, elt_b = b->first; elt_a && elt_b; )
    {
      /* If we're at different indices, then count all the bits
	 in the lower element.  If we're at the same index, then
	 count the bits in the IOR of the two elements.  */
      if (elt_a->indx < elt_b->indx)
	{
	  count += bitmap_count_bits_in_word (elt_a->bits);
	  elt_a = elt_a->next;
	}
      else if (elt_b->indx < elt_a->indx)
	{
	  count += bitmap_count_bits_in_word (elt_b->bits);
	  elt_b = elt_b->next;
	}
      else
	{
	  BITMAP_WORD bits[BITMAP_ELEMENT_WORDS];
	  for (unsigned ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
	    bits[ix] = elt_a->bits[ix] | elt_b->bits[ix];
	  count += bitmap_count_bits_in_word (bits);
	  elt_a = elt_a->next;
	  elt_b = elt_b->next;
	}
    }
  return count;
}

/* Return true if the bitmap has a single bit set.  Otherwise return
   false.  */

bool
bitmap_single_bit_set_p (const_bitmap a)
{
  unsigned long count = 0;
  const bitmap_element *elt;
  unsigned ix;

  if (bitmap_empty_p (a))
    return false;

  elt = a->first;

  /* As there are no completely empty bitmap elements, a second one
     means we have more than one bit set.  */
  if (elt->next != NULL
      && (!a->tree_form || elt->prev != NULL))
    return false;

  for (ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
    {
#if GCC_VERSION >= 3400
      /* Note that popcountl matches BITMAP_WORD in type, so the actual size
	 of BITMAP_WORD is not material.  */
      count += __builtin_popcountl (elt->bits[ix]);
#else
      count += bitmap_popcount (elt->bits[ix]);
#endif
      if (count > 1)
	return false;
    }

  return count == 1;
}


/* Return the bit number of the first set bit in the bitmap.  The
   bitmap must be non-empty.  */

unsigned
bitmap_first_set_bit (const_bitmap a)
{
  const bitmap_element *elt = a->first;
  unsigned bit_no;
  BITMAP_WORD word;
  unsigned ix;

  gcc_checking_assert (elt);

  if (a->tree_form)
    while (elt->prev)
      elt = elt->prev;

  bit_no = elt->indx * BITMAP_ELEMENT_ALL_BITS;
  for (ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
    {
      word = elt->bits[ix];
      if (word)
	goto found_bit;
    }
  gcc_unreachable ();
 found_bit:
  bit_no += ix * BITMAP_WORD_BITS;

#if GCC_VERSION >= 3004
  gcc_assert (sizeof (long) == sizeof (word));
  bit_no += __builtin_ctzl (word);
#else
  /* Binary search for the first set bit.  */
#if BITMAP_WORD_BITS > 64
#error "Fill out the table."
#endif
#if BITMAP_WORD_BITS > 32
  if (!(word & 0xffffffff))
    word >>= 32, bit_no += 32;
#endif
  if (!(word & 0xffff))
    word >>= 16, bit_no += 16;
  if (!(word & 0xff))
    word >>= 8, bit_no += 8;
  if (!(word & 0xf))
    word >>= 4, bit_no += 4;
  if (!(word & 0x3))
    word >>= 2, bit_no += 2;
  if (!(word & 0x1))
    word >>= 1, bit_no += 1;

 gcc_checking_assert (word & 1);
#endif
 return bit_no;
}

/* Return the bit number of the first set bit in the bitmap.  The
   bitmap must be non-empty.  */

unsigned
bitmap_last_set_bit (const_bitmap a)
{
  const bitmap_element *elt;
  unsigned bit_no;
  BITMAP_WORD word;
  int ix;

  if (a->tree_form)
    elt = a->first;
  else
    elt = a->current ? a->current : a->first;
  gcc_checking_assert (elt);

  while (elt->next)
    elt = elt->next;

  bit_no = elt->indx * BITMAP_ELEMENT_ALL_BITS;
  for (ix = BITMAP_ELEMENT_WORDS - 1; ix >= 1; ix--)
    {
      word = elt->bits[ix];
      if (word)
	goto found_bit;
    }
  gcc_assert (elt->bits[ix] != 0);
 found_bit:
  bit_no += ix * BITMAP_WORD_BITS;
#if GCC_VERSION >= 3004
  gcc_assert (sizeof (long) == sizeof (word));
  bit_no += BITMAP_WORD_BITS - __builtin_clzl (word) - 1;
#else
  /* Hopefully this is a twos-complement host...  */
  BITMAP_WORD x = word;
  x |= (x >> 1);
  x |= (x >> 2);
  x |= (x >> 4);
  x |= (x >> 8);
  x |= (x >> 16);
#if BITMAP_WORD_BITS > 32
  x |= (x >> 32);
#endif
  bit_no += bitmap_popcount (x) - 1;
#endif

  return bit_no;
}


/* DST = A & B.  */

void
bitmap_and (bitmap dst, const_bitmap a, const_bitmap b)
{
  bitmap_element *dst_elt = dst->first;
  const bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  bitmap_element *dst_prev = NULL;

  gcc_checking_assert (!dst->tree_form && !a->tree_form && !b->tree_form);
  gcc_assert (dst != a && dst != b);

  if (a == b)
    {
      bitmap_copy (dst, a);
      return;
    }

  while (a_elt && b_elt)
    {
      if (a_elt->indx < b_elt->indx)
	a_elt = a_elt->next;
      else if (b_elt->indx < a_elt->indx)
	b_elt = b_elt->next;
      else
	{
	  /* Matching elts, generate A & B.  */
	  unsigned ix;
	  BITMAP_WORD ior = 0;

	  if (!dst_elt)
	    dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
							a_elt->indx);
	  else
	    dst_elt->indx = a_elt->indx;
	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    {
	      BITMAP_WORD r = a_elt->bits[ix] & b_elt->bits[ix];

	      dst_elt->bits[ix] = r;
	      ior |= r;
	    }
	  if (ior)
	    {
	      dst_prev = dst_elt;
	      dst_elt = dst_elt->next;
	    }
	  a_elt = a_elt->next;
	  b_elt = b_elt->next;
	}
    }
  /* Ensure that dst->current is valid.  */
  dst->current = dst->first;
  bitmap_elt_clear_from (dst, dst_elt);
  gcc_checking_assert (!dst->current == !dst->first);
  if (dst->current)
    dst->indx = dst->current->indx;
}

/* A &= B.  Return true if A changed.  */

bool
bitmap_and_into (bitmap a, const_bitmap b)
{
  bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  bitmap_element *next;
  bool changed = false;

  gcc_checking_assert (!a->tree_form && !b->tree_form);

  if (a == b)
    return false;

  while (a_elt && b_elt)
    {
      if (a_elt->indx < b_elt->indx)
	{
	  next = a_elt->next;
	  bitmap_list_unlink_element (a, a_elt);
	  a_elt = next;
	  changed = true;
	}
      else if (b_elt->indx < a_elt->indx)
	b_elt = b_elt->next;
      else
	{
	  /* Matching elts, generate A &= B.  */
	  unsigned ix;
	  BITMAP_WORD ior = 0;

	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    {
	      BITMAP_WORD r = a_elt->bits[ix] & b_elt->bits[ix];
	      if (a_elt->bits[ix] != r)
		changed = true;
	      a_elt->bits[ix] = r;
	      ior |= r;
	    }
	  next = a_elt->next;
	  if (!ior)
	    bitmap_list_unlink_element (a, a_elt);
	  a_elt = next;
	  b_elt = b_elt->next;
	}
    }

  if (a_elt)
    {
      changed = true;
      bitmap_elt_clear_from (a, a_elt);
    }

  gcc_checking_assert (!a->current == !a->first
		       && (!a->current || a->indx == a->current->indx));

  return changed;
}


/* Insert an element equal to SRC_ELT after DST_PREV, overwriting DST_ELT
   if non-NULL.  CHANGED is true if the destination bitmap had already been
   changed; the new value of CHANGED is returned.  */

static inline bool
bitmap_elt_copy (bitmap dst, bitmap_element *dst_elt, bitmap_element *dst_prev,
		 const bitmap_element *src_elt, bool changed)
{
  if (!changed && dst_elt && dst_elt->indx == src_elt->indx)
    {
      unsigned ix;

      for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	if (src_elt->bits[ix] != dst_elt->bits[ix])
	  {
	    dst_elt->bits[ix] = src_elt->bits[ix];
	    changed = true;
	  }
    }
  else
    {
      changed = true;
      if (!dst_elt)
	dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
						    src_elt->indx);
      else
	dst_elt->indx = src_elt->indx;
      memcpy (dst_elt->bits, src_elt->bits, sizeof (dst_elt->bits));
    }
  return changed;
}



/* DST = A & ~B  */

bool
bitmap_and_compl (bitmap dst, const_bitmap a, const_bitmap b)
{
  bitmap_element *dst_elt = dst->first;
  const bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  bitmap_element *dst_prev = NULL;
  bitmap_element **dst_prev_pnext = &dst->first;
  bool changed = false;

  gcc_checking_assert (!dst->tree_form && !a->tree_form && !b->tree_form);
  gcc_assert (dst != a && dst != b);

  if (a == b)
    {
      changed = !bitmap_empty_p (dst);
      bitmap_clear (dst);
      return changed;
    }

  while (a_elt)
    {
      while (b_elt && b_elt->indx < a_elt->indx)
	b_elt = b_elt->next;

      if (!b_elt || b_elt->indx > a_elt->indx)
	{
	  changed = bitmap_elt_copy (dst, dst_elt, dst_prev, a_elt, changed);
	  dst_prev = *dst_prev_pnext;
	  dst_prev_pnext = &dst_prev->next;
	  dst_elt = *dst_prev_pnext;
	  a_elt = a_elt->next;
	}

      else
	{
	  /* Matching elts, generate A & ~B.  */
	  unsigned ix;
	  BITMAP_WORD ior = 0;

	  if (!changed && dst_elt && dst_elt->indx == a_elt->indx)
	    {
	      for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
		{
		  BITMAP_WORD r = a_elt->bits[ix] & ~b_elt->bits[ix];

		  if (dst_elt->bits[ix] != r)
		    {
		      changed = true;
		      dst_elt->bits[ix] = r;
		    }
		  ior |= r;
		}
	    }
	  else
	    {
	      bool new_element;
	      if (!dst_elt || dst_elt->indx > a_elt->indx)
		{
		  dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
							      a_elt->indx);
		  new_element = true;
		}
	      else
		{
		  dst_elt->indx = a_elt->indx;
		  new_element = false;
		}

	      for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
		{
		  BITMAP_WORD r = a_elt->bits[ix] & ~b_elt->bits[ix];

		  dst_elt->bits[ix] = r;
		  ior |= r;
		}

	      if (ior)
	        changed = true;
	      else
	        {
	          changed |= !new_element;
		  bitmap_list_unlink_element (dst, dst_elt);
		  dst_elt = *dst_prev_pnext;
		}
	    }

	  if (ior)
	    {
	      dst_prev = *dst_prev_pnext;
	      dst_prev_pnext = &dst_prev->next;
	      dst_elt = *dst_prev_pnext;
	    }
	  a_elt = a_elt->next;
	  b_elt = b_elt->next;
	}
    }

  /* Ensure that dst->current is valid.  */
  dst->current = dst->first;

  if (dst_elt)
    {
      changed = true;
      bitmap_elt_clear_from (dst, dst_elt);
    }
  gcc_checking_assert (!dst->current == !dst->first);
  if (dst->current)
    dst->indx = dst->current->indx;

  return changed;
}

/* A &= ~B. Returns true if A changes */

bool
bitmap_and_compl_into (bitmap a, const_bitmap b)
{
  bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  bitmap_element *next;
  BITMAP_WORD changed = 0;

  gcc_checking_assert (!a->tree_form && !b->tree_form);

  if (a == b)
    {
      if (bitmap_empty_p (a))
	return false;
      else
	{
	  bitmap_clear (a);
	  return true;
	}
    }

  while (a_elt && b_elt)
    {
      if (a_elt->indx < b_elt->indx)
	a_elt = a_elt->next;
      else if (b_elt->indx < a_elt->indx)
	b_elt = b_elt->next;
      else
	{
	  /* Matching elts, generate A &= ~B.  */
	  unsigned ix;
	  BITMAP_WORD ior = 0;

	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    {
	      BITMAP_WORD cleared = a_elt->bits[ix] & b_elt->bits[ix];
	      BITMAP_WORD r = a_elt->bits[ix] ^ cleared;

	      a_elt->bits[ix] = r;
	      changed |= cleared;
	      ior |= r;
	    }
	  next = a_elt->next;
	  if (!ior)
	    bitmap_list_unlink_element (a, a_elt);
	  a_elt = next;
	  b_elt = b_elt->next;
	}
    }
  gcc_checking_assert (!a->current == !a->first
		       && (!a->current || a->indx == a->current->indx));
  return changed != 0;
}

/* Set COUNT bits from START in HEAD.  */
void
bitmap_set_range (bitmap head, unsigned int start, unsigned int count)
{
  unsigned int first_index, end_bit_plus1, last_index;
  bitmap_element *elt, *elt_prev;
  unsigned int i;

  gcc_checking_assert (!head->tree_form);

  if (!count)
    return;

  if (count == 1)
    {
      bitmap_set_bit (head, start);
      return;
    }

  first_index = start / BITMAP_ELEMENT_ALL_BITS;
  end_bit_plus1 = start + count;
  last_index = (end_bit_plus1 - 1) / BITMAP_ELEMENT_ALL_BITS;
  elt = bitmap_list_find_element (head, first_index);

  /* If bitmap_list_find_element returns zero, the current is the closest block
     to the result.  Otherwise, just use bitmap_element_allocate to
     ensure ELT is set; in the loop below, ELT == NULL means "insert
     at the end of the bitmap".  */
  if (!elt)
    {
      elt = bitmap_element_allocate (head);
      elt->indx = first_index;
      bitmap_list_link_element (head, elt);
    }

  gcc_checking_assert (elt->indx == first_index);
  elt_prev = elt->prev;
  for (i = first_index; i <= last_index; i++)
    {
      unsigned elt_start_bit = i * BITMAP_ELEMENT_ALL_BITS;
      unsigned elt_end_bit_plus1 = elt_start_bit + BITMAP_ELEMENT_ALL_BITS;

      unsigned int first_word_to_mod;
      BITMAP_WORD first_mask;
      unsigned int last_word_to_mod;
      BITMAP_WORD last_mask;
      unsigned int ix;

      if (!elt || elt->indx != i)
	elt = bitmap_list_insert_element_after (head, elt_prev, i);

      if (elt_start_bit <= start)
	{
	  /* The first bit to turn on is somewhere inside this
	     elt.  */
	  first_word_to_mod = (start - elt_start_bit) / BITMAP_WORD_BITS;

	  /* This mask should have 1s in all bits >= start position. */
	  first_mask =
	    (((BITMAP_WORD) 1) << ((start % BITMAP_WORD_BITS))) - 1;
	  first_mask = ~first_mask;
	}
      else
	{
	  /* The first bit to turn on is below this start of this elt.  */
	  first_word_to_mod = 0;
	  first_mask = ~(BITMAP_WORD) 0;
	}

      if (elt_end_bit_plus1 <= end_bit_plus1)
	{
	  /* The last bit to turn on is beyond this elt.  */
	  last_word_to_mod = BITMAP_ELEMENT_WORDS - 1;
	  last_mask = ~(BITMAP_WORD) 0;
	}
      else
	{
	  /* The last bit to turn on is inside to this elt.  */
	  last_word_to_mod =
	    (end_bit_plus1 - elt_start_bit) / BITMAP_WORD_BITS;

	  /* The last mask should have 1s below the end bit.  */
	  last_mask =
	    (((BITMAP_WORD) 1) << ((end_bit_plus1 % BITMAP_WORD_BITS))) - 1;
	}

      if (first_word_to_mod == last_word_to_mod)
	{
	  BITMAP_WORD mask = first_mask & last_mask;
	  elt->bits[first_word_to_mod] |= mask;
	}
      else
	{
	  elt->bits[first_word_to_mod] |= first_mask;
	  if (BITMAP_ELEMENT_WORDS > 2)
	    for (ix = first_word_to_mod + 1; ix < last_word_to_mod; ix++)
	      elt->bits[ix] = ~(BITMAP_WORD) 0;
	  elt->bits[last_word_to_mod] |= last_mask;
	}

      elt_prev = elt;
      elt = elt->next;
    }

  head->current = elt ? elt : elt_prev;
  head->indx = head->current->indx;
}

/* Clear COUNT bits from START in HEAD.  */
void
bitmap_clear_range (bitmap head, unsigned int start, unsigned int count)
{
  unsigned int first_index, end_bit_plus1, last_index;
  bitmap_element *elt;

  gcc_checking_assert (!head->tree_form);

  if (!count)
    return;

  if (count == 1)
    {
      bitmap_clear_bit (head, start);
      return;
    }

  first_index = start / BITMAP_ELEMENT_ALL_BITS;
  end_bit_plus1 = start + count;
  last_index = (end_bit_plus1 - 1) / BITMAP_ELEMENT_ALL_BITS;
  elt = bitmap_list_find_element (head, first_index);

  /* If bitmap_list_find_element returns zero, the current is the closest block
     to the result.  If the current is less than first index, find the
     next one.  Otherwise, just set elt to be current.  */
  if (!elt)
    {
      if (head->current)
	{
	  if (head->indx < first_index)
	    {
	      elt = head->current->next;
	      if (!elt)
		return;
	    }
	  else
	    elt = head->current;
	}
      else
	return;
    }

  while (elt && (elt->indx <= last_index))
    {
      bitmap_element * next_elt = elt->next;
      unsigned elt_start_bit = (elt->indx) * BITMAP_ELEMENT_ALL_BITS;
      unsigned elt_end_bit_plus1 = elt_start_bit + BITMAP_ELEMENT_ALL_BITS;


      if (elt_start_bit >= start && elt_end_bit_plus1 <= end_bit_plus1)
	/* Get rid of the entire elt and go to the next one.  */
	bitmap_list_unlink_element (head, elt);
      else
	{
	  /* Going to have to knock out some bits in this elt.  */
	  unsigned int first_word_to_mod;
	  BITMAP_WORD first_mask;
	  unsigned int last_word_to_mod;
	  BITMAP_WORD last_mask;
	  unsigned int i;
	  bool clear = true;

	  if (elt_start_bit <= start)
	    {
	      /* The first bit to turn off is somewhere inside this
		 elt.  */
	      first_word_to_mod = (start - elt_start_bit) / BITMAP_WORD_BITS;

	      /* This mask should have 1s in all bits >= start position. */
	      first_mask =
		(((BITMAP_WORD) 1) << ((start % BITMAP_WORD_BITS))) - 1;
	      first_mask = ~first_mask;
	    }
	  else
	    {
	      /* The first bit to turn off is below this start of this elt.  */
	      first_word_to_mod = 0;
	      first_mask = 0;
	      first_mask = ~first_mask;
	    }

	  if (elt_end_bit_plus1 <= end_bit_plus1)
	    {
	      /* The last bit to turn off is beyond this elt.  */
	      last_word_to_mod = BITMAP_ELEMENT_WORDS - 1;
	      last_mask = 0;
	      last_mask = ~last_mask;
	    }
	  else
	    {
	      /* The last bit to turn off is inside to this elt.  */
	      last_word_to_mod =
		(end_bit_plus1 - elt_start_bit) / BITMAP_WORD_BITS;

	      /* The last mask should have 1s below the end bit.  */
	      last_mask =
		(((BITMAP_WORD) 1) << (((end_bit_plus1) % BITMAP_WORD_BITS))) - 1;
	    }


	  if (first_word_to_mod == last_word_to_mod)
	    {
	      BITMAP_WORD mask = first_mask & last_mask;
	      elt->bits[first_word_to_mod] &= ~mask;
	    }
	  else
	    {
	      elt->bits[first_word_to_mod] &= ~first_mask;
	      if (BITMAP_ELEMENT_WORDS > 2)
	        for (i = first_word_to_mod + 1; i < last_word_to_mod; i++)
		  elt->bits[i] = 0;
	      elt->bits[last_word_to_mod] &= ~last_mask;
	    }
	  for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
	    if (elt->bits[i])
	      {
		clear = false;
		break;
	      }
	  /* Check to see if there are any bits left.  */
	  if (clear)
	    bitmap_list_unlink_element (head, elt);
	}
      elt = next_elt;
    }

  if (elt)
    {
      head->current = elt;
      head->indx = head->current->indx;
    }
}

/* A = ~A & B. */

void
bitmap_compl_and_into (bitmap a, const_bitmap b)
{
  bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  bitmap_element *a_prev = NULL;
  bitmap_element *next;

  gcc_checking_assert (!a->tree_form && !b->tree_form);
  gcc_assert (a != b);

  if (bitmap_empty_p (a))
    {
      bitmap_copy (a, b);
      return;
    }
  if (bitmap_empty_p (b))
    {
      bitmap_clear (a);
      return;
    }

  while (a_elt || b_elt)
    {
      if (!b_elt || (a_elt && a_elt->indx < b_elt->indx))
	{
	  /* A is before B.  Remove A */
	  next = a_elt->next;
	  a_prev = a_elt->prev;
	  bitmap_list_unlink_element (a, a_elt);
	  a_elt = next;
	}
      else if (!a_elt || b_elt->indx < a_elt->indx)
	{
	  /* B is before A.  Copy B. */
	  next = bitmap_list_insert_element_after (a, a_prev, b_elt->indx);
	  memcpy (next->bits, b_elt->bits, sizeof (next->bits));
	  a_prev = next;
	  b_elt = b_elt->next;
	}
      else
	{
	  /* Matching elts, generate A = ~A & B.  */
	  unsigned ix;
	  BITMAP_WORD ior = 0;

	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    {
	      BITMAP_WORD cleared = a_elt->bits[ix] & b_elt->bits[ix];
	      BITMAP_WORD r = b_elt->bits[ix] ^ cleared;

	      a_elt->bits[ix] = r;
	      ior |= r;
	    }
	  next = a_elt->next;
	  if (!ior)
	    bitmap_list_unlink_element (a, a_elt);
	  else
	    a_prev = a_elt;
	  a_elt = next;
	  b_elt = b_elt->next;
	}
    }
  gcc_checking_assert (!a->current == !a->first
		       && (!a->current || a->indx == a->current->indx));
  return;
}


/* Insert an element corresponding to A_ELT | B_ELT after DST_PREV,
   overwriting DST_ELT if non-NULL.  CHANGED is true if the destination bitmap
   had already been changed; the new value of CHANGED is returned.  */

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)
{
  gcc_assert (a_elt || b_elt);

  if (a_elt && b_elt && a_elt->indx == b_elt->indx)
    {
      /* Matching elts, generate A | B.  */
      unsigned ix;

      if (!changed && dst_elt && dst_elt->indx == a_elt->indx)
	{
	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    {
	      BITMAP_WORD r = a_elt->bits[ix] | b_elt->bits[ix];
	      if (r != dst_elt->bits[ix])
		{
		  dst_elt->bits[ix] = r;
		  changed = true;
		}
	    }
	}
      else
	{
	  changed = true;
	  if (!dst_elt)
	    dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
							a_elt->indx);
	  else
	    dst_elt->indx = a_elt->indx;
	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    {
	      BITMAP_WORD r = a_elt->bits[ix] | b_elt->bits[ix];
	      dst_elt->bits[ix] = r;
	    }
	}
    }
  else
    {
      /* Copy a single element.  */
      const bitmap_element *src;

      if (!b_elt || (a_elt && a_elt->indx < b_elt->indx))
	src = a_elt;
      else
	src = b_elt;

      gcc_checking_assert (src);
      changed = bitmap_elt_copy (dst, dst_elt, dst_prev, src, changed);
    }
  return changed;
}


/* DST = A | B.  Return true if DST changes.  */

bool
bitmap_ior (bitmap dst, const_bitmap a, const_bitmap b)
{
  bitmap_element *dst_elt = dst->first;
  const bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  bitmap_element *dst_prev = NULL;
  bitmap_element **dst_prev_pnext = &dst->first;
  bool changed = false;

  gcc_checking_assert (!dst->tree_form && !a->tree_form && !b->tree_form);
  gcc_assert (dst != a && dst != b);

  while (a_elt || b_elt)
    {
      changed = bitmap_elt_ior (dst, dst_elt, dst_prev, a_elt, b_elt, changed);

      if (a_elt && b_elt && a_elt->indx == b_elt->indx)
	{
	  a_elt = a_elt->next;
	  b_elt = b_elt->next;
	}
      else
	{
	  if (a_elt && (!b_elt || a_elt->indx <= b_elt->indx))
            a_elt = a_elt->next;
          else if (b_elt && (!a_elt || b_elt->indx <= a_elt->indx))
            b_elt = b_elt->next;
	}

      dst_prev = *dst_prev_pnext;
      dst_prev_pnext = &dst_prev->next;
      dst_elt = *dst_prev_pnext;
    }

  if (dst_elt)
    {
      changed = true;
      /* Ensure that dst->current is valid.  */
      dst->current = dst->first;
      bitmap_elt_clear_from (dst, dst_elt);
    }
  gcc_checking_assert (!dst->current == !dst->first);
  if (dst->current)
    dst->indx = dst->current->indx;
  return changed;
}

/* A |= B.  Return true if A changes.  */

bool
bitmap_ior_into (bitmap a, const_bitmap b)
{
  bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  bitmap_element *a_prev = NULL;
  bitmap_element **a_prev_pnext = &a->first;
  bool changed = false;

  gcc_checking_assert (!a->tree_form && !b->tree_form);
  if (a == b)
    return false;

  while (b_elt)
    {
      /* If A lags behind B, just advance it.  */
      if (!a_elt || a_elt->indx == b_elt->indx)
	{
	  changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, b_elt, changed);
	  b_elt = b_elt->next;
	}
      else if (a_elt->indx > b_elt->indx)
	{
          changed = bitmap_elt_copy (a, NULL, a_prev, b_elt, changed);
	  b_elt = b_elt->next;
	}

      a_prev = *a_prev_pnext;
      a_prev_pnext = &a_prev->next;
      a_elt = *a_prev_pnext;
    }

  gcc_checking_assert (!a->current == !a->first);
  if (a->current)
    a->indx = a->current->indx;
  return changed;
}

/* A |= B.  Return true if A changes.  Free B (re-using its storage
   for the result).  */

bool
bitmap_ior_into_and_free (bitmap a, bitmap *b_)
{
  bitmap b = *b_;
  bitmap_element *a_elt = a->first;
  bitmap_element *b_elt = b->first;
  bitmap_element *a_prev = NULL;
  bitmap_element **a_prev_pnext = &a->first;
  bool changed = false;

  gcc_checking_assert (!a->tree_form && !b->tree_form);
  gcc_assert (a->obstack == b->obstack);
  if (a == b)
    return false;

  while (b_elt)
    {
      /* If A lags behind B, just advance it.  */
      if (!a_elt || a_elt->indx == b_elt->indx)
	{
	  changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, b_elt, changed);
	  b_elt = b_elt->next;
	}
      else if (a_elt->indx > b_elt->indx)
	{
	  bitmap_element *b_elt_next = b_elt->next;
	  bitmap_list_unlink_element (b, b_elt, false);
	  bitmap_list_insert_element_after (a, a_prev, b_elt->indx, b_elt);
	  b_elt = b_elt_next;
	}

      a_prev = *a_prev_pnext;
      a_prev_pnext = &a_prev->next;
      a_elt = *a_prev_pnext;
    }

  gcc_checking_assert (!a->current == !a->first);
  if (a->current)
    a->indx = a->current->indx;

  if (b->obstack)
    BITMAP_FREE (*b_);
  else
    bitmap_clear (b);
  return changed;
}

/* DST = A ^ B  */

void
bitmap_xor (bitmap dst, const_bitmap a, const_bitmap b)
{
  bitmap_element *dst_elt = dst->first;
  const bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  bitmap_element *dst_prev = NULL;

  gcc_checking_assert (!dst->tree_form && !a->tree_form && !b->tree_form);
  gcc_assert (dst != a && dst != b);

  if (a == b)
    {
      bitmap_clear (dst);
      return;
    }

  while (a_elt || b_elt)
    {
      if (a_elt && b_elt && a_elt->indx == b_elt->indx)
	{
	  /* Matching elts, generate A ^ B.  */
	  unsigned ix;
	  BITMAP_WORD ior = 0;

	  if (!dst_elt)
	    dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
							a_elt->indx);
	  else
	    dst_elt->indx = a_elt->indx;
	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    {
	      BITMAP_WORD r = a_elt->bits[ix] ^ b_elt->bits[ix];

	      ior |= r;
	      dst_elt->bits[ix] = r;
	    }
	  a_elt = a_elt->next;
	  b_elt = b_elt->next;
	  if (ior)
	    {
	      dst_prev = dst_elt;
	      dst_elt = dst_elt->next;
	    }
	}
      else
	{
	  /* Copy a single element.  */
	  const bitmap_element *src;

	  if (!b_elt || (a_elt && a_elt->indx < b_elt->indx))
	    {
	      src = a_elt;
	      a_elt = a_elt->next;
	    }
	  else
	    {
	      src = b_elt;
	      b_elt = b_elt->next;
	    }

	  if (!dst_elt)
	    dst_elt = bitmap_list_insert_element_after (dst, dst_prev,
							src->indx);
	  else
	    dst_elt->indx = src->indx;
	  memcpy (dst_elt->bits, src->bits, sizeof (dst_elt->bits));
	  dst_prev = dst_elt;
	  dst_elt = dst_elt->next;
	}
    }
  /* Ensure that dst->current is valid.  */
  dst->current = dst->first;
  bitmap_elt_clear_from (dst, dst_elt);
  gcc_checking_assert (!dst->current == !dst->first);
  if (dst->current)
    dst->indx = dst->current->indx;
}

/* A ^= B */

void
bitmap_xor_into (bitmap a, const_bitmap b)
{
  bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  bitmap_element *a_prev = NULL;

  gcc_checking_assert (!a->tree_form && !b->tree_form);

  if (a == b)
    {
      bitmap_clear (a);
      return;
    }

  while (b_elt)
    {
      if (!a_elt || b_elt->indx < a_elt->indx)
	{
	  /* Copy b_elt.  */
	  bitmap_element *dst = bitmap_list_insert_element_after (a, a_prev,
								  b_elt->indx);
	  memcpy (dst->bits, b_elt->bits, sizeof (dst->bits));
	  a_prev = dst;
	  b_elt = b_elt->next;
	}
      else if (a_elt->indx < b_elt->indx)
	{
	  a_prev = a_elt;
	  a_elt = a_elt->next;
	}
      else
	{
	  /* Matching elts, generate A ^= B.  */
	  unsigned ix;
	  BITMAP_WORD ior = 0;
	  bitmap_element *next = a_elt->next;

	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    {
	      BITMAP_WORD r = a_elt->bits[ix] ^ b_elt->bits[ix];

	      ior |= r;
	      a_elt->bits[ix] = r;
	    }
	  b_elt = b_elt->next;
	  if (ior)
	    a_prev = a_elt;
	  else
	    bitmap_list_unlink_element (a, a_elt);
	  a_elt = next;
	}
    }
  gcc_checking_assert (!a->current == !a->first);
  if (a->current)
    a->indx = a->current->indx;
}

/* Return true if two bitmaps are identical.
   We do not bother with a check for pointer equality, as that never
   occurs in practice.  */

bool
bitmap_equal_p (const_bitmap a, const_bitmap b)
{
  const bitmap_element *a_elt;
  const bitmap_element *b_elt;
  unsigned ix;

  gcc_checking_assert (!a->tree_form && !b->tree_form);

  for (a_elt = a->first, b_elt = b->first;
       a_elt && b_elt;
       a_elt = a_elt->next, b_elt = b_elt->next)
    {
      if (a_elt->indx != b_elt->indx)
	return false;
      for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	if (a_elt->bits[ix] != b_elt->bits[ix])
	  return false;
    }
  return !a_elt && !b_elt;
}

/* Return true if A AND B is not empty.  */

bool
bitmap_intersect_p (const_bitmap a, const_bitmap b)
{
  const bitmap_element *a_elt;
  const bitmap_element *b_elt;
  unsigned ix;

  gcc_checking_assert (!a->tree_form && !b->tree_form);

  for (a_elt = a->first, b_elt = b->first;
       a_elt && b_elt;)
    {
      if (a_elt->indx < b_elt->indx)
	a_elt = a_elt->next;
      else if (b_elt->indx < a_elt->indx)
	b_elt = b_elt->next;
      else
	{
	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    if (a_elt->bits[ix] & b_elt->bits[ix])
	      return true;
	  a_elt = a_elt->next;
	  b_elt = b_elt->next;
	}
    }
  return false;
}

/* Return true if A AND NOT B is not empty.  */

bool
bitmap_intersect_compl_p (const_bitmap a, const_bitmap b)
{
  const bitmap_element *a_elt;
  const bitmap_element *b_elt;
  unsigned ix;

  gcc_checking_assert (!a->tree_form && !b->tree_form);

  for (a_elt = a->first, b_elt = b->first;
       a_elt && b_elt;)
    {
      if (a_elt->indx < b_elt->indx)
	return true;
      else if (b_elt->indx < a_elt->indx)
	b_elt = b_elt->next;
      else
	{
	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    if (a_elt->bits[ix] & ~b_elt->bits[ix])
	      return true;
	  a_elt = a_elt->next;
	  b_elt = b_elt->next;
	}
    }
  return a_elt != NULL;
}


/* DST = A | (FROM1 & ~FROM2).  Return true if DST changes.  */

bool
bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b, const_bitmap kill)
{
  bool changed = false;

  bitmap_element *dst_elt = dst->first;
  const bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  const bitmap_element *kill_elt = kill->first;
  bitmap_element *dst_prev = NULL;
  bitmap_element **dst_prev_pnext = &dst->first;

  gcc_checking_assert (!dst->tree_form && !a->tree_form && !b->tree_form
		       && !kill->tree_form);
  gcc_assert (dst != a && dst != b && dst != kill);

  /* Special cases.  We don't bother checking for bitmap_equal_p (b, kill).  */
  if (b == kill || bitmap_empty_p (b))
    {
      changed = !bitmap_equal_p (dst, a);
      if (changed)
	bitmap_copy (dst, a);
      return changed;
    }
  if (bitmap_empty_p (kill))
    return bitmap_ior (dst, a, b);
  if (bitmap_empty_p (a))
    return bitmap_and_compl (dst, b, kill);

  while (a_elt || b_elt)
    {
      bool new_element = false;

      if (b_elt)
	while (kill_elt && kill_elt->indx < b_elt->indx)
	  kill_elt = kill_elt->next;

      if (b_elt && kill_elt && kill_elt->indx == b_elt->indx
	  && (!a_elt || a_elt->indx >= b_elt->indx))
        {
	  bitmap_element tmp_elt;
	  unsigned ix;

	  BITMAP_WORD ior = 0;
	  tmp_elt.indx = b_elt->indx;
	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
            {
              BITMAP_WORD r = b_elt->bits[ix] & ~kill_elt->bits[ix];
              ior |= r;
              tmp_elt.bits[ix] = r;
            }

	  if (ior)
	    {
	      changed = bitmap_elt_ior (dst, dst_elt, dst_prev,
				        a_elt, &tmp_elt, changed);
	      new_element = true;
	      if (a_elt && a_elt->indx == b_elt->indx)
                a_elt = a_elt->next;
	    }

	  b_elt = b_elt->next;
	  kill_elt = kill_elt->next;
	}
      else
	{
	  changed = bitmap_elt_ior (dst, dst_elt, dst_prev,
				    a_elt, b_elt, changed);
	  new_element = true;

          if (a_elt && b_elt && a_elt->indx == b_elt->indx)
	    {
	      a_elt = a_elt->next;
	      b_elt = b_elt->next;
	    }
          else
	    {
	      if (a_elt && (!b_elt || a_elt->indx <= b_elt->indx))
                a_elt = a_elt->next;
              else if (b_elt && (!a_elt || b_elt->indx <= a_elt->indx))
                b_elt = b_elt->next;
	    }
	}

      if (new_element)
	{
	  dst_prev = *dst_prev_pnext;
	  dst_prev_pnext = &dst_prev->next;
	  dst_elt = *dst_prev_pnext;
	}
    }

  if (dst_elt)
    {
      changed = true;
      /* Ensure that dst->current is valid.  */
      dst->current = dst->first;
      bitmap_elt_clear_from (dst, dst_elt);
    }
  gcc_checking_assert (!dst->current == !dst->first);
  if (dst->current)
    dst->indx = dst->current->indx;

  return changed;
}

/* A |= (B & ~C).  Return true if A changes.  */

bool
bitmap_ior_and_compl_into (bitmap a, const_bitmap b, const_bitmap c)
{
  bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  const bitmap_element *c_elt = c->first;
  bitmap_element and_elt;
  bitmap_element *a_prev = NULL;
  bitmap_element **a_prev_pnext = &a->first;
  bool changed = false;
  unsigned ix;

  gcc_checking_assert (!a->tree_form && !b->tree_form && !c->tree_form);

  if (a == b)
    return false;
  if (bitmap_empty_p (c))
    return bitmap_ior_into (a, b);
  else if (bitmap_empty_p (a))
    return bitmap_and_compl (a, b, c);

  and_elt.indx = -1;
  while (b_elt)
    {
      /* Advance C.  */
      while (c_elt && c_elt->indx < b_elt->indx)
	c_elt = c_elt->next;

      const bitmap_element *and_elt_ptr;
      if (c_elt && c_elt->indx == b_elt->indx)
	{
	  BITMAP_WORD overall = 0;
	  and_elt_ptr = &and_elt;
	  and_elt.indx = b_elt->indx;
	  for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	    {
	      and_elt.bits[ix] = b_elt->bits[ix] & ~c_elt->bits[ix];
	      overall |= and_elt.bits[ix];
	    }
	  if (!overall)
	    {
	      b_elt = b_elt->next;
	      continue;
	    }
	}
      else
	and_elt_ptr = b_elt;

      b_elt = b_elt->next;

      /* Now find a place to insert AND_ELT.  */
      do
	{
	  ix = a_elt ? a_elt->indx : and_elt_ptr->indx;
          if (ix == and_elt_ptr->indx)
	    changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt,
				      and_elt_ptr, changed);
          else if (ix > and_elt_ptr->indx)
	    changed = bitmap_elt_copy (a, NULL, a_prev, and_elt_ptr, changed);

          a_prev = *a_prev_pnext;
          a_prev_pnext = &a_prev->next;
          a_elt = *a_prev_pnext;

          /* If A lagged behind B/C, we advanced it so loop once more.  */
	}
      while (ix < and_elt_ptr->indx);
    }

  gcc_checking_assert (!a->current == !a->first);
  if (a->current)
    a->indx = a->current->indx;
  return changed;
}

/* A |= (B & C).  Return true if A changes.  */

bool
bitmap_ior_and_into (bitmap a, const_bitmap b, const_bitmap c)
{
  bitmap_element *a_elt = a->first;
  const bitmap_element *b_elt = b->first;
  const bitmap_element *c_elt = c->first;
  bitmap_element and_elt;
  bitmap_element *a_prev = NULL;
  bitmap_element **a_prev_pnext = &a->first;
  bool changed = false;
  unsigned ix;

  gcc_checking_assert (!a->tree_form && !b->tree_form && !c->tree_form);

  if (b == c)
    return bitmap_ior_into (a, b);
  if (bitmap_empty_p (b) || bitmap_empty_p (c))
    return false;

  and_elt.indx = -1;
  while (b_elt && c_elt)
    {
      BITMAP_WORD overall;

      /* Find a common item of B and C.  */
      while (b_elt->indx != c_elt->indx)
	{
          if (b_elt->indx < c_elt->indx)
	    {
	      b_elt = b_elt->next;
	      if (!b_elt)
		goto done;
	    }
          else
	    {
	      c_elt = c_elt->next;
	      if (!c_elt)
		goto done;
	    }
	}

      overall = 0;
      and_elt.indx = b_elt->indx;
      for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
	{
	  and_elt.bits[ix] = b_elt->bits[ix] & c_elt->bits[ix];
	  overall |= and_elt.bits[ix];
	}

      b_elt = b_elt->next;
      c_elt = c_elt->next;
      if (!overall)
	continue;

      /* Now find a place to insert AND_ELT.  */
      do
	{
	  ix = a_elt ? a_elt->indx : and_elt.indx;
          if (ix == and_elt.indx)
	    changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, &and_elt, changed);
          else if (ix > and_elt.indx)
	    changed = bitmap_elt_copy (a, NULL, a_prev, &and_elt, changed);

          a_prev = *a_prev_pnext;
          a_prev_pnext = &a_prev->next;
          a_elt = *a_prev_pnext;

          /* If A lagged behind B/C, we advanced it so loop once more.  */
	}
      while (ix < and_elt.indx);
    }

 done:
  gcc_checking_assert (!a->current == !a->first);
  if (a->current)
    a->indx = a->current->indx;
  return changed;
}

/* Compute hash of bitmap (for purposes of hashing).  */

hashval_t
bitmap_hash (const_bitmap head)
{
  const bitmap_element *ptr;
  BITMAP_WORD hash = 0;
  int ix;

  gcc_checking_assert (!head->tree_form);

  for (ptr = head->first; ptr; ptr = ptr->next)
    {
      hash ^= ptr->indx;
      for (ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
	hash ^= ptr->bits[ix];
    }
  return (hashval_t)hash;
}


/* Function to obtain a vector of bitmap elements in bit order from
   HEAD in tree view.  */

static void
bitmap_tree_to_vec (vec<bitmap_element *> &elts, const_bitmap head)
{
  gcc_checking_assert (head->tree_form);
  auto_vec<bitmap_element *, 32> stack;
  bitmap_element *e = head->first;
  while (true)
    {
      while (e != NULL)
	{
	  stack.safe_push (e);
	  e = e->prev;
	}
      if (stack.is_empty ())
	break;

      e = stack.pop ();
      elts.safe_push (e);
      e = e->next;
    }
}

/* Debugging function to print out the contents of a bitmap element.  */

DEBUG_FUNCTION void
debug_bitmap_elt_file (FILE *file, const bitmap_element *ptr)
{
  unsigned int i, j, col = 26;

  fprintf (file, "\t" HOST_PTR_PRINTF " next = " HOST_PTR_PRINTF
	   " prev = " HOST_PTR_PRINTF " indx = %u\n\t\tbits = {",
	   (const void*) ptr, (const void*) ptr->next,
	   (const void*) ptr->prev, ptr->indx);

  for (i = 0; i < BITMAP_ELEMENT_WORDS; i++)
    for (j = 0; j < BITMAP_WORD_BITS; j++)
      if ((ptr->bits[i] >> j) & 1)
	{
	  if (col > 70)
	    {
	      fprintf (file, "\n\t\t\t");
	      col = 24;
	    }

	  fprintf (file, " %u", (ptr->indx * BITMAP_ELEMENT_ALL_BITS
				 + i * BITMAP_WORD_BITS + j));
	  col += 4;
	}

  fprintf (file, " }\n");
}

/* Debugging function to print out the contents of a bitmap.  */

DEBUG_FUNCTION void
debug_bitmap_file (FILE *file, const_bitmap head)
{
  const bitmap_element *ptr;

  fprintf (file, "\nfirst = " HOST_PTR_PRINTF
	   " current = " HOST_PTR_PRINTF " indx = %u\n",
	   (void *) head->first, (void *) head->current, head->indx);

  if (head->tree_form)
    {
      auto_vec<bitmap_element *, 32> elts;
      bitmap_tree_to_vec (elts, head);
      for (unsigned i = 0; i < elts.length (); ++i)
	debug_bitmap_elt_file (file, elts[i]);
    }
  else
    for (ptr = head->first; ptr; ptr = ptr->next)
      debug_bitmap_elt_file (file, ptr);
}

/* Function to be called from the debugger to print the contents
   of a bitmap.  */

DEBUG_FUNCTION void
debug_bitmap (const_bitmap head)
{
  debug_bitmap_file (stderr, head);
}

/* Function to print out the contents of a bitmap.  Unlike debug_bitmap_file,
   it does not print anything but the bits.  */

DEBUG_FUNCTION void
bitmap_print (FILE *file, const_bitmap head, const char *prefix,
	      const char *suffix)
{
  const char *comma = "";
  unsigned i;

  fputs (prefix, file);
  if (head->tree_form)
    {
      auto_vec<bitmap_element *, 32> elts;
      bitmap_tree_to_vec (elts, head);
      for (i = 0; i < elts.length (); ++i)
	for (unsigned ix = 0; ix != BITMAP_ELEMENT_WORDS; ++ix)
	  {
	    BITMAP_WORD word = elts[i]->bits[ix];
	    for (unsigned bit = 0; bit != BITMAP_WORD_BITS; ++bit)
	      if (word & ((BITMAP_WORD)1 << bit))
		{
		  fprintf (file, "%s%d", comma,
			   (bit + BITMAP_WORD_BITS * ix
			    + elts[i]->indx * BITMAP_ELEMENT_ALL_BITS));
		  comma = ", ";
		}
	  }
    }
  else
    {
      bitmap_iterator bi;
      EXECUTE_IF_SET_IN_BITMAP (head, 0, i, bi)
	{
	  fprintf (file, "%s%d", comma, i);
	  comma = ", ";
	}
    }
  fputs (suffix, file);
}

/* Output per-bitmap memory usage statistics.  */
void
dump_bitmap_statistics (void)
{
  if (!GATHER_STATISTICS)
    return;

  bitmap_mem_desc.dump (BITMAP_ORIGIN);
}

DEBUG_FUNCTION void
debug (const bitmap_head &ref)
{
  dump_bitmap (stderr, &ref);
}

DEBUG_FUNCTION void
debug (const bitmap_head *ptr)
{
  if (ptr)
    debug (*ptr);
  else
    fprintf (stderr, "<nil>\n");
}

DEBUG_FUNCTION void
debug (const auto_bitmap &ref)
{
  debug ((const bitmap_head &) ref);
}

DEBUG_FUNCTION void
debug (const auto_bitmap *ptr)
{
  debug ((const bitmap_head *) ptr);
}

void
bitmap_head::dump ()
{
  debug (this);
}

#if CHECKING_P

namespace selftest {

/* Selftests for bitmaps.  */

/* Freshly-created bitmaps ought to be empty.  */

static void
test_gc_alloc ()
{
  bitmap b = bitmap_gc_alloc ();
  ASSERT_TRUE (bitmap_empty_p (b));
}

/* Verify bitmap_set_range.  */

static void
test_set_range ()
{
  bitmap b = bitmap_gc_alloc ();
  ASSERT_TRUE (bitmap_empty_p (b));

  bitmap_set_range (b, 7, 5);
  ASSERT_FALSE (bitmap_empty_p (b));
  ASSERT_EQ (5, bitmap_count_bits (b));

  /* Verify bitmap_bit_p at the boundaries.  */
  ASSERT_FALSE (bitmap_bit_p (b, 6));
  ASSERT_TRUE (bitmap_bit_p (b, 7));
  ASSERT_TRUE (bitmap_bit_p (b, 11));
  ASSERT_FALSE (bitmap_bit_p (b, 12));
}

/* Verify splitting a range into two pieces using bitmap_clear_bit.  */

static void
test_clear_bit_in_middle ()
{
  bitmap b = bitmap_gc_alloc ();

  /* Set b to [100..200].  */
  bitmap_set_range (b, 100, 100);
  ASSERT_EQ (100, bitmap_count_bits (b));

  /* Clear a bit in the middle.  */
  bool changed = bitmap_clear_bit (b, 150);
  ASSERT_TRUE (changed);
  ASSERT_EQ (99, bitmap_count_bits (b));
  ASSERT_TRUE (bitmap_bit_p (b, 149));
  ASSERT_FALSE (bitmap_bit_p (b, 150));
  ASSERT_TRUE (bitmap_bit_p (b, 151));
}

/* Verify bitmap_copy.  */

static void
test_copying ()
{
  bitmap src = bitmap_gc_alloc ();
  bitmap_set_range (src, 40, 10);

  bitmap dst = bitmap_gc_alloc ();
  ASSERT_FALSE (bitmap_equal_p (src, dst));
  bitmap_copy (dst, src);
  ASSERT_TRUE (bitmap_equal_p (src, dst));

  /* Verify that we can make them unequal again...  */
  bitmap_set_range (src, 70, 5);
  ASSERT_FALSE (bitmap_equal_p (src, dst));

  /* ...and that changing src after the copy didn't affect
     the other: */
  ASSERT_FALSE (bitmap_bit_p (dst, 70));
}

/* Verify bitmap_single_bit_set_p.  */

static void
test_bitmap_single_bit_set_p ()
{
  bitmap b = bitmap_gc_alloc ();

  ASSERT_FALSE (bitmap_single_bit_set_p (b));

  bitmap_set_range (b, 42, 1);
  ASSERT_TRUE (bitmap_single_bit_set_p (b));
  ASSERT_EQ (42, bitmap_first_set_bit (b));

  bitmap_set_range (b, 1066, 1);
  ASSERT_FALSE (bitmap_single_bit_set_p (b));
  ASSERT_EQ (42, bitmap_first_set_bit (b));

  bitmap_clear_range (b, 0, 100);
  ASSERT_TRUE (bitmap_single_bit_set_p (b));
  ASSERT_EQ (1066, bitmap_first_set_bit (b));
}

/* Verify accessing aligned bit chunks works as expected.  */

static void
test_aligned_chunk (unsigned num_bits)
{
  bitmap b = bitmap_gc_alloc ();
  int limit = 2 ^ num_bits;

  int index = 3;
  for (int x = 0; x < limit; x++)
    {
      bitmap_set_aligned_chunk (b, index, num_bits, (BITMAP_WORD) x);
      ASSERT_TRUE ((int) bitmap_get_aligned_chunk (b, index, num_bits) == x);
      ASSERT_TRUE ((int) bitmap_get_aligned_chunk (b, index + 1,
						   num_bits) == 0);
      ASSERT_TRUE ((int) bitmap_get_aligned_chunk (b, index - 1,
						   num_bits) == 0);
      index += 3;
    }
  index = 3;
  for (int x = 0; x < limit ; x++)
    {
      ASSERT_TRUE ((int) bitmap_get_aligned_chunk (b, index, num_bits) == x);
      index += 3;
    }
}

/* Run all of the selftests within this file.  */

void
bitmap_cc_tests ()
{
  test_gc_alloc ();
  test_set_range ();
  test_clear_bit_in_middle ();
  test_copying ();
  test_bitmap_single_bit_set_p ();
  /* Test 2, 4 and 8 bit aligned chunks.  */
  test_aligned_chunk (2);
  test_aligned_chunk (4);
  test_aligned_chunk (8);
}

} // namespace selftest
#endif /* CHECKING_P */

#include "gt-bitmap.h"
