/* Sparse array-based bitmaps.
   Copyright (C) 2007, 2008 Free Software Foundation, Inc.
   Contributed by Daniel Berlin <dberlin@dberlin.org>

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 "tm.h"
#include "rtl.h"
#include "flags.h"
#include "obstack.h"
#include "ebitmap.h"

/* The ebitmap data structure is a sparse bitmap structure that works
   by having two pieces:
   1. An array of all nonzero words in the structures, organized as
   an array of HOST_WIDE_INT's.
   2. A non-sparse bitmap saying which bitmap words are present in the
   array.

   As a consequence of this representation, testing whether a bit
   exists in the bitmap is faster than linked-list bitmaps.  For bits
   in words that are all zero, the time to test is O(1).  For bits in
   words that exist, it requires O(n/sizeof(word)) time to perform the
   test (ignoring the one element cache).  It also has much better
   locality than linked-list bitmaps.

   To test whether a bit exists, we do the following:
   1. Test whether the word the bit would appear in exists in the
   bitmap (O(1) check of the mask).  If not, fail.

   2. Population count the mask up to the word containing the bit, to
   find the place in the array the word would be (popcount is cached,
   but this is just as slow as the linked-list bitmap)
   3. Test the word to see if the bit exists.

   Just like linked-list bitmaps, we cache the last element that has
   been tested in order to speed up common access patterns.

   Most of the other speedups are simply due to better locality of the
   single contiguous array.

   As would be expected in a structure like this, insertion into an
   empty word in the middle requires moving bits to make room for the
   new word.   As most operations that perform sets perform them in
   order, this is rarely a problem.  We also take advantage of the
   same element cache to make repeated sets to the same word O(1).

   Operations on the entire bitmap are also more efficient than linked
   list bitmaps, as they are all operating on contiguous memory, and
   can be easily vectorized.  They are all O(number of words) +
   O(number of bits that may end up in the destination), as the
   appropriate operation is first performed on the word mask, and then
   only those elements that may generate results are touched.

   Memory wise, the ebitmap starts out using less memory than the
   linked-list bitmap, but its size in memory is technically bounded
   by ((index of the highest bit set) / (size of a word) + (index of
   the highest bit set) / ((size of a word) * (size of a word))) This
   is because the mask is non-sparse.  The mask could be transformed
   into a sparse bitmap at the cost of making bit testing
   *theoretically* slower (real world numbers have not been computed
   yet as to whether it matters or not).  */

/* #define EBITMAP_DEBUGGING  */

/* Find the last set bit in ebitmap MAP.  */

int
ebitmap_last_set_bit (ebitmap map)
{
  unsigned int i = 0;
  ebitmap_iterator ebi;
  bool foundbit = false;
  
  /* This is not the fastest way to do this, we could simply look for
     the popcount, and start there, but this function is not used
     anywhere speed critical.  */
  EXECUTE_IF_SET_IN_EBITMAP (map, 0, i, ebi)
    {
      foundbit = true;
    }
  

  if (foundbit)
    return i;
  return -1;
}

/* Grow or shrink the internal word array for MAP to NEWSIZE
   elements.  */

static inline void
ebitmap_array_grow (ebitmap map, unsigned int newsize)
{
  if (newsize <= map->n_elts)
    {
      map->n_elts = newsize;
      return;
    }

  newsize += newsize / 4;

  map->n_elts = newsize;
  map->elts = XRESIZEVEC (EBITMAP_ELT_TYPE, map->elts, newsize);
}

/* Grow the internal word array for MAP so it is at least SIZE
   elements.  Will not shrink the array if it is already big
   enough.  */

static inline void
ebitmap_array_maybe_grow (ebitmap map, unsigned int size)
{
  if (size >= map->n_elts)
    ebitmap_array_grow (map, size + 1);
}

/* Retrieve the IDX'th element from the word array for MAP.  */

static inline EBITMAP_ELT_TYPE
ebitmap_array_get (ebitmap map, unsigned int idx)
{
  gcc_assert (idx < map->n_elts);
  return map->elts[idx];
}

/* Retrieve a pointer to the IDX'th element from the word array for
   MAP.  If the element index is greater than the size of the array,
   the array will be grown to the correct size.  */

static inline EBITMAP_ELT_TYPE *
ebitmap_array_grow_get (ebitmap map, unsigned int idx)
{
  if (idx >= map->n_elts)
    ebitmap_array_grow (map, idx + 1);
  return &map->elts[idx];
}

/* Initialize the internal word array for MAP, so that it is SIZE
   elements.  */

static inline void
ebitmap_array_init (ebitmap map, unsigned int size)
{
  if (size > 0)
    {
      map->elts = XNEWVEC (EBITMAP_ELT_TYPE, size);
      map->n_elts = size;
    }
  else
    {
      map->n_elts = 0;
      map->elts = NULL;
    }
}

/* Free the internal word array for MAP.  */

static inline void
ebitmap_array_clear (ebitmap map)
{
  if (map->elts) 
    {
      free (map->elts);
      map->elts = NULL;
    }
  map->n_elts = 0;
}

/* Clear ebitmap MAP.  */

void
ebitmap_clear (ebitmap map)
{
  ebitmap_array_clear (map);
  sbitmap_zero (map->wordmask);
  map->wordmask = sbitmap_resize (map->wordmask, 1, 0);
  map->numwords = 0;
  map->cache = NULL;
  map->cacheindex = 0;
}

/* Allocate an ebitmap with enough room for SIZE bits to start out.  */

ebitmap
ebitmap_alloc (unsigned int size)
{
  ebitmap ret = XNEW (struct ebitmap_def);
  if (size == 0)
    size = EBITMAP_ELT_BITS;
  ebitmap_array_init (ret, (size + EBITMAP_ELT_BITS - 1) / EBITMAP_ELT_BITS);
  ret->wordmask = sbitmap_alloc_with_popcount (size);
  sbitmap_zero (ret->wordmask);
  ret->numwords = 0;
  ret->cache = NULL;
  ret->cacheindex = 0;

  return ret;
}

/* Clear BIT from ebitmap MAP.  */

void
ebitmap_clear_bit (ebitmap map, unsigned int bit)
{
  unsigned int wordindex = bit / EBITMAP_ELT_BITS;
  unsigned int eltwordindex = 0;
  unsigned int bitindex, shift;
  bool have_eltwordindex = false;
  EBITMAP_ELT_TYPE *elt_ptr;
  
  /* If the bit can't exist in our bitmap, just return.  */
  if (map->numwords == 0)
    return;

  if (wordindex >= map->wordmask->n_bits
      || !TEST_BIT (map->wordmask, wordindex))
    return;
  
  if (map->cache != NULL && map->cacheindex == wordindex)
    elt_ptr = map->cache;
  else
    {
      eltwordindex = sbitmap_popcount (map->wordmask, wordindex);
      elt_ptr = &map->elts[eltwordindex];
      have_eltwordindex = true;
    }
  
  bitindex = bit % EBITMAP_ELT_BITS;
  shift = bitindex;
  
  *(elt_ptr) &= ~(((EBITMAP_ELT_TYPE)1) << shift);

  /* Clear out the empty words.  */
  if (*(elt_ptr) == 0)
    {
      if (!have_eltwordindex)
	eltwordindex = sbitmap_popcount (map->wordmask, wordindex);
      
      if (map->cache != NULL && map->cacheindex == eltwordindex)
	map->cache = NULL;

      RESET_BIT (map->wordmask, wordindex);

      memmove(&map->elts[eltwordindex], &map->elts[eltwordindex + 1],
	      sizeof (EBITMAP_ELT_TYPE) * (map->numwords - eltwordindex));
      map->numwords--;
    }
}

/* Set BIT in ebitmap MAP.  */

void
ebitmap_set_bit (ebitmap map, unsigned int bit)
{
  unsigned int wordindex = bit / EBITMAP_ELT_BITS;
  unsigned int eltwordindex;
  unsigned int bitindex =   bit % EBITMAP_ELT_BITS;

  /* If we have this element cached, just set the bit in it.  */
  if (map->cache && map->cacheindex == wordindex)
    {
      (*map->cache) |= (EBITMAP_ELT_TYPE)1 << bitindex;
      return;
    }

  /* Resize the wordmask if necessary.  */
  if (wordindex >= map->wordmask->n_bits)
    map->wordmask = sbitmap_resize (map->wordmask, wordindex + 1, 0);

  /* Allocate a new word in the array and move whatever is in it's
     place, if necessary. */
  if (!TEST_BIT (map->wordmask, wordindex))
    {
      unsigned long count;
      unsigned int i;

      SET_BIT (map->wordmask, wordindex);
      count = sbitmap_popcount (map->wordmask, wordindex);
      gcc_assert (count <= map->numwords);

      for (i = map->numwords; i > count; i--)
	{
	  EBITMAP_ELT_TYPE *newelt;
	  newelt = ebitmap_array_grow_get (map, i);
	  *newelt = ebitmap_array_get (map, i - 1);
	}
      map->numwords++;
      eltwordindex = count;
      ebitmap_array_maybe_grow (map, eltwordindex);
      map->elts[eltwordindex] = 0;
    }
  else
    {
      eltwordindex = sbitmap_popcount (map->wordmask, wordindex);
    }

  /* Set the actual bit.  */
  bitindex = bit % EBITMAP_ELT_BITS;

  map->elts[eltwordindex] |= (EBITMAP_ELT_TYPE)1 << bitindex;
  map->cache = &map->elts[eltwordindex];
  map->cacheindex = wordindex;
}


/* Return true if MAP contains BIT.  */

bool
ebitmap_bit_p (ebitmap map, unsigned int bit)
{
  unsigned int wordindex = bit / EBITMAP_ELT_BITS;
  unsigned int bitindex= bit % EBITMAP_ELT_BITS;

  /* Trivial empty ebitmap case.  */
  if (map->numwords == 0)
    return false;

  if (map->cache && map->cacheindex == wordindex)
    return ((*map->cache) >> bitindex) & 1;

  /* If the wordindex is greater than the size of the wordmask, *or*
     it's not set in the wordmask, this bit can't exist in our
     ebitmap.  */
  if (wordindex >= map->wordmask->n_bits
      || !TEST_BIT (map->wordmask, wordindex))
    return false;

  /* Find the bit and test it.  */
  map->cacheindex = wordindex;
  wordindex = sbitmap_popcount (map->wordmask, wordindex);
  map->cache = &map->elts[wordindex];

  return (map->elts[wordindex] >> bitindex) & 1;
}

/* Copy ebitmap SRC to DST.  */

void
ebitmap_copy (ebitmap dst, ebitmap src)
{
  /* Blow away any existing wordmask, and copy the new one.  */
  sbitmap_free (dst->wordmask);
  dst->wordmask = sbitmap_alloc_with_popcount (src->wordmask->n_bits);
  sbitmap_copy (dst->wordmask, src->wordmask);

  /* Make sure our destination array is big enough, and then copy the
     actual words.  */
  ebitmap_array_grow (dst, src->numwords);
  memcpy (dst->elts, src->elts,
	  src->numwords * sizeof (EBITMAP_ELT_TYPE));
  dst->numwords = src->numwords;
  dst->cache = NULL;
}

/* Dump ebitmap BMAP to FILE.  */

void
dump_ebitmap (FILE *file, ebitmap bmap)
{
  unsigned int pos;
  unsigned int i;
  int res;
  unsigned int size;

  res = sbitmap_last_set_bit (bmap->wordmask);
  if (res == -1)
    size = 0;
  else
    size = (res + 1) * EBITMAP_ELT_BITS;

  fprintf (file, "n_words = %d, set = {", bmap->numwords);

  for (pos = 30, i = 0; i < size; i++)
    if (ebitmap_bit_p (bmap, i))
      {
	if (pos > 70)
	  {
	    fprintf (file, "\n  ");
	    pos = 0;
	  }

	pos += fprintf (file, "%d ", i);
      }

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

/* Dump ebitmap BMAP to stderr.  */

void
debug_ebitmap (ebitmap bmap)
{
  dump_ebitmap (stderr, bmap);
}

/* Perform the operation DST &= SRC.  */

void
ebitmap_and_into (ebitmap dst, ebitmap src)
{
  sbitmap_iterator sbi;
  unsigned int i;
  unsigned int neweltindex = 0;
  unsigned int dsteltindex = 0;
  unsigned int srceltindex = 0;

  gcc_assert (dst != src);

  dst->cache = NULL;

  /* Short circuit the empty bitmap cases.  */
  if (src->numwords == 0 || dst->numwords == 0)
    {
      ebitmap_clear (dst);
      return;
    }

  /* AND the masks, then walk the words that may actually appear in
     the result, AND'ing them.  */
  sbitmap_a_and_b (dst->wordmask, dst->wordmask, src->wordmask);

  EXECUTE_IF_SET_IN_SBITMAP (dst->wordmask, 0, i, sbi)
    {
      EBITMAP_ELT_TYPE tmpword = ebitmap_array_get (src, srceltindex++);
      tmpword &= ebitmap_array_get (dst, dsteltindex++);
      if (tmpword != 0)
	{
	  EBITMAP_ELT_TYPE *dstplace;
	  dstplace = ebitmap_array_grow_get (dst, neweltindex++);
	  *dstplace = tmpword;
	}
      else
	RESET_BIT (dst->wordmask, i);
    }
#ifdef EBITMAP_DEBUGGING
  {
    unsigned int i;

    for (i = 0; i <  dst->numwords; i++)
      gcc_assert (dst->elts[i] != 0);

    verify_popcount (dst->wordmask);
    gcc_assert (sbitmap_popcount (dst->wordmask,
				  dst->wordmask->n_bits) == dst->numwords);
  }
#endif
  dst->numwords = neweltindex;
}

/* Perform the operation DST = SRC1 & SRC2.  */

void
ebitmap_and (ebitmap dst, ebitmap src1, ebitmap src2)
{
  sbitmap_iterator sbi;
  unsigned int i;
  unsigned int neweltindex = 0;
  unsigned int src1eltindex = 0;
  unsigned int src2eltindex = 0;

  dst->cache = NULL;
  if (src1->numwords == 0 || src2->numwords == 0)
    {
      ebitmap_clear (dst);
      return;
    }

  dst->wordmask
    = sbitmap_resize (dst->wordmask,
		      MIN (src1->wordmask->n_bits, src2->wordmask->n_bits),
		      0);
  sbitmap_a_and_b (dst->wordmask, src1->wordmask, src2->wordmask);

  EXECUTE_IF_SET_IN_SBITMAP (dst->wordmask, 0, i, sbi)
    {
      bool src1hasword, src2hasword;

      src1hasword = TEST_BIT (src1->wordmask, i);
      src2hasword = TEST_BIT (src2->wordmask, i);

      if (src1hasword && src2hasword)
	{
	  EBITMAP_ELT_TYPE tmpword = ebitmap_array_get (src1, src1eltindex++);
	  tmpword &= ebitmap_array_get (src2, src2eltindex++);
	  if (tmpword != 0)
	    {
	      EBITMAP_ELT_TYPE *dstplace;
	      dstplace = ebitmap_array_grow_get (dst, neweltindex++);
	      *dstplace = tmpword;
	    }
	  else
	    RESET_BIT (dst->wordmask, i);
	}
      else if (src1hasword)
	src1eltindex++;
      else
	src2eltindex++;
    }
#ifdef EBITMAP_DEBUGGING
  {
    ebitmap_iterator ebi;
    unsigned int i;

    for (i = 0; i <  dst->numwords; i++)
      gcc_assert (dst->elts[i] != 0);

    EXECUTE_IF_SET_IN_EBITMAP (src1, 0, i, ebi)
      if (ebitmap_bit_p (src2, i))
	gcc_assert (ebitmap_bit_p (dst, i));

    for (i = 0; i <  dst->numwords; i++)
      gcc_assert (dst->elts[i] != 0);

    verify_popcount (dst->wordmask);
    gcc_assert (sbitmap_popcount (dst->wordmask,
				  dst->wordmask->n_bits) == dst->numwords);
  }
#endif
  dst->numwords = neweltindex;
}

/* Perform the operation DST |= SRC.  Return true if any bits in DST
   changed.  */

bool
ebitmap_ior_into (ebitmap dst, ebitmap src)
{
  unsigned int dstsize = dst->wordmask->n_bits;
  unsigned int srcsize = src->wordmask->n_bits;
  sbitmap_iterator sbi;
  unsigned int i;
  sbitmap tempmask;
  unsigned int neweltindex = 0;
  unsigned int dsteltindex = 0;
  unsigned int srceltindex = 0;
  bool changed = false;
  EBITMAP_ELT_TYPE *newarray;
  unsigned int newarraysize;
#ifdef EBITMAP_DEBUGGING
  ebitmap dstcopy = ebitmap_alloc (1);
  ebitmap_copy (dstcopy, dst);
#endif

  dst->cache = NULL;
  if (dst == src)
    return false;

  if (dst->numwords == 0 && src->numwords != 0)
    {
      ebitmap_copy (dst, src);
      return true;
    }
  else if (src->numwords == 0)
    return false;

  /* We can do without the temp mask if it's faster, but it would mean
     touching more words in the actual dense vector.  */
  tempmask = sbitmap_alloc (MAX (srcsize, dstsize));
  sbitmap_zero (tempmask);
  if (srcsize == dstsize)
    {
      sbitmap_a_or_b (tempmask, dst->wordmask, src->wordmask);
    }
  else
    {
      dst->wordmask = sbitmap_resize (dst->wordmask, MAX (srcsize, dstsize),
				      0);
      if (srcsize >= dstsize)
	{
	  sbitmap_copy_n (tempmask, dst->wordmask, dst->wordmask->size);
	  sbitmap_a_or_b (tempmask, tempmask, src->wordmask);
	}
      else
	{
	  sbitmap_copy_n (tempmask, src->wordmask, src->wordmask->size);
	  sbitmap_a_or_b (tempmask, tempmask, dst->wordmask);
	}
    }
  newarraysize = src->numwords + dst->numwords;
  newarray = XNEWVEC (EBITMAP_ELT_TYPE, newarraysize);

  EXECUTE_IF_SET_IN_SBITMAP (tempmask, 0, i, sbi)
    {
      bool dsthasword, srchasword;

      dsthasword = (i < dst->wordmask->n_bits
		    && TEST_BIT (dst->wordmask, i));
      srchasword = (i < src->wordmask->n_bits
		    && TEST_BIT (src->wordmask, i));

      if (dsthasword && srchasword)
	{
	  EBITMAP_ELT_TYPE tmpword = ebitmap_array_get (src, srceltindex++);
	  tmpword |= ebitmap_array_get (dst, dsteltindex);
	  if (!changed)
	    changed |= tmpword != ebitmap_array_get (dst, dsteltindex);
	  dsteltindex++;
	  newarray[neweltindex++] = tmpword;
	}
      else if (dsthasword)
	{
	  newarray [neweltindex++] = ebitmap_array_get (dst, dsteltindex++);
	}
      else
	{
	  newarray [neweltindex++] = ebitmap_array_get (src, srceltindex++);
	  gcc_assert (i < dst->wordmask->n_bits);
	  SET_BIT (dst->wordmask, i);
	  changed |= true;
	}
    }

  sbitmap_free (tempmask);
  if (changed)
    {
      dst->numwords = neweltindex;
      free (dst->elts);
      dst->elts = newarray;
      dst->n_elts = newarraysize;
    }
  else
    free (newarray);

#ifdef EBITMAP_DEBUGGING
  {
    ebitmap_iterator ebi;
    unsigned int i;

    for (i = 0; i <  dst->numwords; i++)
      gcc_assert (dst->elts[i] != 0);

    EXECUTE_IF_SET_IN_EBITMAP (src, 0, i, ebi)
      gcc_assert (ebitmap_bit_p (dst, i));
    EXECUTE_IF_SET_IN_EBITMAP (dstcopy, 0, i, ebi)
      gcc_assert (ebitmap_bit_p (dst, i));

    verify_popcount (dst->wordmask);
    gcc_assert (changed == !ebitmap_equal_p (dst, dstcopy));
    gcc_assert (sbitmap_popcount (dst->wordmask,
				  dst->wordmask->n_bits) == dst->numwords);
  }
#endif
  return changed;
}

/* Perform the operation DST = SRC1 | SRC2.  Return true if any bit
   in DST has changed.  */

bool
ebitmap_ior (ebitmap dst, ebitmap src1, ebitmap src2)
{
  unsigned int src1size = src1->wordmask->n_bits;
  unsigned int src2size = src2->wordmask->n_bits;
  sbitmap_iterator sbi;
  unsigned int i;
  sbitmap tempmask;
  unsigned int neweltindex = 0;
  unsigned int src1eltindex = 0;
  unsigned int src2eltindex = 0;
  bool changed = false;
  EBITMAP_ELT_TYPE *newarray;
  unsigned int newarraysize;
#ifdef EBITMAP_DEBUGGING
  ebitmap dstcopy = ebitmap_alloc (1);
  ebitmap_copy (dstcopy, dst);
#endif

  dst->cache = NULL;
  tempmask = sbitmap_alloc_with_popcount (MAX (src1size, src2size));
  sbitmap_zero (tempmask);
  if (src1size == src2size)
    {
      sbitmap_a_or_b (tempmask, src1->wordmask, src2->wordmask);
    }
  else
    {
      if (src1size >= src2size)
	{
	  sbitmap_copy_n (tempmask, src2->wordmask, src2->wordmask->size);
	  sbitmap_a_or_b (tempmask, tempmask, src1->wordmask);
	}
      else
	{
	  sbitmap_copy_n (tempmask, src1->wordmask, src1->wordmask->size);
	  sbitmap_a_or_b (tempmask, tempmask, src2->wordmask);
	}
    }
  newarraysize = src1->numwords + src2->numwords;
  newarray = XNEWVEC (EBITMAP_ELT_TYPE, newarraysize);

  EXECUTE_IF_SET_IN_SBITMAP (tempmask, 0, i, sbi)
    {
      bool src1hasword, src2hasword;
      EBITMAP_ELT_TYPE tmpword;
      src1hasword = (i < src1->wordmask->n_bits
		    && TEST_BIT (src1->wordmask, i));
      src2hasword = (i < src2->wordmask->n_bits
		    && TEST_BIT (src2->wordmask, i));

      if (src1hasword && src2hasword)
	{
	  tmpword = (ebitmap_array_get (src1, src1eltindex++)
		     | ebitmap_array_get (src2, src2eltindex++));
	  newarray[neweltindex++] = tmpword;
	}
      else if (src1hasword)
	{
	  tmpword = ebitmap_array_get (src1, src1eltindex++);
	  newarray [neweltindex++] = tmpword;
	}
      else
	{
	  tmpword = ebitmap_array_get (src2, src2eltindex++);
	  newarray [neweltindex++] = tmpword;
	}

      if (i >= dst->wordmask->n_bits || !TEST_BIT (dst->wordmask, i))
	{
	  changed = true;
	}
      else if (!changed)
	{
	  unsigned int count = sbitmap_popcount (dst->wordmask, i);
	  changed |= ebitmap_array_get (dst, count) != tmpword;
	}
    }

  if (changed)
    {
      sbitmap_free (dst->wordmask);
      dst->wordmask = tempmask;
      dst->numwords = neweltindex;
      free (dst->elts);
      dst->elts = newarray;
      dst->n_elts = newarraysize;
    }
  else
    {
      sbitmap_free (tempmask);
      free (newarray);
    }

#ifdef EBITMAP_DEBUGGING
  {
    ebitmap_iterator ebi;
    unsigned int i;

    for (i = 0; i <  dst->numwords; i++)
      gcc_assert (dst->elts[i] != 0);

    EXECUTE_IF_SET_IN_EBITMAP (src1, 0, i, ebi)
      gcc_assert (ebitmap_bit_p (dst, i));

    EXECUTE_IF_SET_IN_EBITMAP (src2, 0, i, ebi)
      gcc_assert (ebitmap_bit_p (dst, i));
  }
  verify_popcount (dst->wordmask);
  gcc_assert (changed == !ebitmap_equal_p (dst, dstcopy));
  gcc_assert (sbitmap_popcount (dst->wordmask,
				dst->wordmask->n_bits) == dst->numwords);
#endif

  return changed;
}

/* Perform the operation DST &= ~SRC.  Return true if any bit in DST
   has changed.  */

bool
ebitmap_and_compl_into (ebitmap dst, ebitmap src)
{
  bool changed = false;
  unsigned int i;
  unsigned int neweltindex = 0;
  unsigned int dsteltindex = 0;
  sbitmap_iterator sbi;
#ifdef EBITMAP_DEBUGGING
  ebitmap dstcopy = ebitmap_alloc (1);
  ebitmap_copy (dstcopy, dst);
#endif

  gcc_assert (dst != src);
  dst->cache = NULL;
  if (src->numwords == 0)
    return false;

  EXECUTE_IF_SET_IN_SBITMAP (dst->wordmask, 0, i, sbi)
    {
      bool srchasword;

      srchasword = (i < src->wordmask->n_bits
		    && TEST_BIT (src->wordmask, i));

      if (srchasword)
	{
	  unsigned int srccount = sbitmap_popcount (src->wordmask, i);
	  EBITMAP_ELT_TYPE tmpword = ebitmap_array_get (dst, dsteltindex);
	  tmpword &= ~(ebitmap_array_get (src, srccount));
	  if (!changed)
	    changed |= ebitmap_array_get (dst, dsteltindex) != tmpword;
	  dsteltindex++;
	  if (tmpword != 0)
	    {
	      EBITMAP_ELT_TYPE *dstplace;
	      dstplace = ebitmap_array_grow_get (dst, neweltindex++);
	      *dstplace = tmpword;
	    }
	  else
	    RESET_BIT (dst->wordmask, i);
	}
      else
	{
	  dsteltindex++;
	  neweltindex++;
	}
    }
#ifdef EBITMAP_DEBUGGING
  {
    unsigned int i;
    ebitmap_iterator ebi;

    EXECUTE_IF_SET_IN_EBITMAP (dstcopy, 0, i, ebi)
      {
	if (!ebitmap_bit_p (src, i))
	  gcc_assert (ebitmap_bit_p (dst, i));
      }

    for (i = 0; i <  dst->numwords; i++)
      gcc_assert (dst->elts[i] != 0);

    gcc_assert (sbitmap_popcount (dst->wordmask,
				  dst->wordmask->n_bits) == neweltindex);
    verify_popcount (dst->wordmask);
    gcc_assert (changed == !ebitmap_equal_p (dst, dstcopy));
    gcc_assert (sbitmap_popcount (dst->wordmask,
				  dst->wordmask->n_bits) == dst->numwords);
  }
#endif
  dst->numwords = neweltindex;
  /* sbitmap_popcount (dst->wordmask, -1); */

  return changed;
}

/* Perform the operation DST = SRC1 & ~SRC2.  Return true if any bit
   in DST has changed.  */

bool
ebitmap_and_compl (ebitmap dst, ebitmap src1, ebitmap src2)
{
  unsigned int src1size = src1->wordmask->n_bits;
  sbitmap_iterator sbi;
  unsigned int i;
  sbitmap tempmask;
  unsigned int neweltindex = 0;
  unsigned int src1eltindex = 0;
  bool changed = false;
  EBITMAP_ELT_TYPE *newarray;
  unsigned int newarraysize;

  /* XXX: Optimize like the into version.  */
  dst->cache = NULL;
  tempmask = sbitmap_alloc_with_popcount (src1size);
  sbitmap_zero (tempmask);
  sbitmap_copy (tempmask, src1->wordmask);

  newarraysize = src1->numwords;
  newarray = XNEWVEC (EBITMAP_ELT_TYPE, newarraysize);

  EXECUTE_IF_SET_IN_SBITMAP (src1->wordmask, 0, i, sbi)
    {
      bool src2hasword;
      EBITMAP_ELT_TYPE tmpword;

      src2hasword = (i < src2->wordmask->n_bits
		     && TEST_BIT (src2->wordmask, i));

      if (src2hasword)
	{
	  unsigned int src2count = sbitmap_popcount (src2->wordmask, i);
	  tmpword = ebitmap_array_get (src1, src1eltindex++)
	            & ~(ebitmap_array_get (src2, src2count));
	  if (tmpword)
	    {
	      newarray[neweltindex++] = tmpword;
	    }
	  else
	    RESET_BIT (tempmask, i);

	}
      else
	{
	  tmpword = ebitmap_array_get (src1, src1eltindex++);
	  gcc_assert (tmpword != 0);
	  newarray[neweltindex++] = tmpword;
	}

      if (i >= dst->wordmask->n_bits || !TEST_BIT (dst->wordmask, i))
	{
	  changed = true;
	}
      else if (!changed)
	{
	  unsigned int count = sbitmap_popcount (dst->wordmask, i);
	  changed |= ebitmap_array_get (dst, count) != tmpword;
	}
    }
  if (changed)
    {
      sbitmap_free (dst->wordmask);
      dst->wordmask = tempmask;
      dst->numwords = neweltindex;
      free (dst->elts);
      dst->elts = newarray;
      dst->n_elts = newarraysize;
    }
  else
    {
      free (tempmask);
      free (newarray);
    }
#ifdef EBITMAP_DEBUGGING
  {
    unsigned int i;
    ebitmap_iterator ebi;

    EXECUTE_IF_SET_IN_EBITMAP (src1, 0, i, ebi)
      {
	if (!ebitmap_bit_p (src2, i))
	  gcc_assert (ebitmap_bit_p (dst, i));
      }
  for (i = 0; i <  dst->numwords; i++)
    gcc_assert (dst->elts[i] != 0);

  verify_popcount (dst->wordmask);
  gcc_assert (sbitmap_popcount (dst->wordmask,
				dst->wordmask->n_bits) == dst->numwords);
  }
#endif
  return changed;
}

/* Perform the operation DST = A | (B & ~C).  */

bool
ebitmap_ior_and_compl (ebitmap dst, ebitmap a, ebitmap b, ebitmap c)
{
  bool changed;
  ebitmap temp = ebitmap_alloc (1);
#ifdef EBITMAP_DEBUGGING
  ebitmap dstcopy = ebitmap_alloc (1);
  ebitmap_copy (dstcopy, dst);
#endif

  dst->cache = NULL;
  ebitmap_and_compl (temp, b, c);
  changed = ebitmap_ior (dst, a, temp);
#ifdef EBITMAP_DEBUGGING
  {
    ebitmap_iterator ebi;
    unsigned int i;

    EXECUTE_IF_SET_IN_EBITMAP (a, 0, i, ebi)
      gcc_assert (ebitmap_bit_p (dst, i));

    EXECUTE_IF_SET_IN_EBITMAP (b, 0, i, ebi)
      if (!ebitmap_bit_p (c, i))
	gcc_assert (ebitmap_bit_p (dst, i));
    gcc_assert (changed == !ebitmap_equal_p (dst, dstcopy));
  }
#endif
  ebitmap_free (temp);

  return changed;
}

/* Return true if ebitmap DST is equal to ebitmap SRC.  */

bool
ebitmap_equal_p (ebitmap dst, ebitmap src)
{
  unsigned int which = MIN (dst->wordmask->size, src->wordmask->size);

  if (dst->numwords != src->numwords)
    return false;

  /* sbitmap_equal compares up to the size of the first argument, so
     if the two sbitmaps are not equally sized, we need to pass the
     smaller one as the first argument, or it will crash.  */
  if (which == dst->wordmask->size
      && !sbitmap_equal (dst->wordmask, src->wordmask))
    return false;
  else if (which == src->wordmask->size
	   && !sbitmap_equal (src->wordmask, dst->wordmask))
    return false;

  return memcmp (dst->elts, src->elts,
		 dst->numwords * sizeof (EBITMAP_ELT_TYPE)) == 0;
  return true;
}
