/* Functions to support general ended bitmaps.
Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005,
- 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
-#include "rtl.h"
-#include "flags.h"
#include "obstack.h"
#include "ggc.h"
#include "bitmap.h"
HOST_WIDEST_INT peak;
HOST_WIDEST_INT current;
int nsearches;
+ int search_iter;
};
/* Hashtable mapping bitmap names to descriptors. */
/* Inner list was just a singleton. */
bitmap_ggc_free = element->prev;
else
- element = GGC_NEW (bitmap_element);
+ element = ggc_alloc_bitmap_element_def ();
}
#ifdef GATHER_STATISTICS
{
bitmap map;
- map = GGC_NEW (struct bitmap_head_def);
+ map = ggc_alloc_bitmap_head_def ();
bitmap_initialize_stat (map, NULL PASS_MEM_STAT);
#ifdef GATHER_STATISTICS
register_overhead (map, sizeof (bitmap_head));
}
else
{
- gcc_assert (head->current);
+ gcc_checking_assert (head->current);
node->next = elt->next;
if (node->next)
node->next->prev = node;
bitmap_element *element;
unsigned int indx = bit / BITMAP_ELEMENT_ALL_BITS;
-#ifdef GATHER_STATISTICS
- head->desc->nsearches++;
-#endif
if (head->current == 0
|| head->indx == indx)
return head->current;
+#ifdef GATHER_STATISTICS
+ head->desc->nsearches++;
+#endif
if (head->indx < indx)
/* INDX is beyond head->indx. Search from head->current
for (element = head->current;
element->next != 0 && element->indx < indx;
element = element->next)
+#ifdef GATHER_STATISTICS
+ head->desc->search_iter++;
+#else
;
+#endif
else if (head->indx / 2 < indx)
/* INDX is less than head->indx and closer to head->indx than to
for (element = head->current;
element->prev != 0 && element->indx > indx;
element = element->prev)
+#ifdef GATHER_STATISTICS
+ head->desc->search_iter++;
+#else
;
+#endif
else
/* INDX is less than head->indx and closer to 0 than to
for (element = head->first;
element->next != 0 && element->indx < indx;
element = element->next)
+#ifdef GATHER_STATISTICS
+ head->desc->search_iter++;
+#else
;
+#endif
/* `element' is the nearest to the one we want. If it's not the one we
want, the one we want doesn't exist. */
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 (bitmap_element_zerop (ptr))
- bitmap_element_free (head, ptr);
+ {
+ 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))
+ bitmap_element_free (head, ptr);
+ }
return res;
}
BITMAP_WORD word;
unsigned ix;
- gcc_assert (elt);
+ gcc_checking_assert (elt);
bit_no = elt->indx * BITMAP_ELEMENT_ALL_BITS;
for (ix = 0; ix != BITMAP_ELEMENT_WORDS; ix++)
{
if (!(word & 0x1))
word >>= 1, bit_no += 1;
- gcc_assert (word & 1);
+ gcc_checking_assert (word & 1);
#endif
return bit_no;
}
BITMAP_WORD word;
int ix;
- gcc_assert (elt);
+ gcc_checking_assert (elt);
while (elt->next)
elt = elt->next;
bit_no = elt->indx * BITMAP_ELEMENT_ALL_BITS;
word >>= 1, bit_no += 1;
#endif
- gcc_assert (word & 1);
+ gcc_checking_assert (word & 1);
return bit_no;
}
\f
dst_elt = bitmap_elt_insert_after (dst, dst_prev, a_elt->indx);
else
dst_elt->indx = a_elt->indx;
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
{
BITMAP_WORD r = a_elt->bits[ix] & b_elt->bits[ix];
/* Ensure that dst->current is valid. */
dst->current = dst->first;
bitmap_elt_clear_from (dst, dst_elt);
- gcc_assert (!dst->current == !dst->first);
+ gcc_checking_assert (!dst->current == !dst->first);
if (dst->current)
dst->indx = dst->current->indx;
}
unsigned ix;
BITMAP_WORD ior = 0;
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
{
BITMAP_WORD r = a_elt->bits[ix] & b_elt->bits[ix];
}
}
bitmap_elt_clear_from (a, a_elt);
- gcc_assert (!a->current == !a->first);
- gcc_assert (!a->current || a->indx == a->current->indx);
+ gcc_checking_assert (!a->current == !a->first
+ && (!a->current || a->indx == a->current->indx));
}
{
unsigned ix;
- for (ix = BITMAP_ELEMENT_WORDS; 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];
if (!changed && dst_elt && dst_elt->indx == a_elt->indx)
{
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
{
BITMAP_WORD r = a_elt->bits[ix] & ~b_elt->bits[ix];
new_element = false;
}
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
{
BITMAP_WORD r = a_elt->bits[ix] & ~b_elt->bits[ix];
changed = true;
bitmap_elt_clear_from (dst, dst_elt);
}
- gcc_assert (!dst->current == !dst->first);
+ gcc_checking_assert (!dst->current == !dst->first);
if (dst->current)
dst->indx = dst->current->indx;
unsigned ix;
BITMAP_WORD ior = 0;
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ 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;
b_elt = b_elt->next;
}
}
- gcc_assert (!a->current == !a->first);
- gcc_assert (!a->current || a->indx == a->current->indx);
+ gcc_checking_assert (!a->current == !a->first
+ && (!a->current || a->indx == a->current->indx));
return changed != 0;
}
bitmap_element_link (head, elt);
}
- gcc_assert (elt->indx == first_index);
+ gcc_checking_assert (elt->indx == first_index);
elt_prev = elt->prev;
for (i = first_index; i <= last_index; i++)
{
unsigned ix;
BITMAP_WORD ior = 0;
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ 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;
b_elt = b_elt->next;
}
}
- gcc_assert (!a->current == !a->first);
- gcc_assert (!a->current || a->indx == a->current->indx);
+ gcc_checking_assert (!a->current == !a->first
+ && (!a->current || a->indx == a->current->indx));
return;
}
if (!changed && dst_elt && dst_elt->indx == a_elt->indx)
{
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ 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 = bitmap_elt_insert_after (dst, dst_prev, a_elt->indx);
else
dst_elt->indx = a_elt->indx;
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ 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
src = b_elt;
- gcc_assert (src);
+ gcc_checking_assert (src);
changed = bitmap_elt_copy (dst, dst_elt, dst_prev, src, changed);
}
return changed;
changed = true;
bitmap_elt_clear_from (dst, dst_elt);
}
- gcc_assert (!dst->current == !dst->first);
+ gcc_checking_assert (!dst->current == !dst->first);
if (dst->current)
dst->indx = dst->current->indx;
return changed;
a_elt = *a_prev_pnext;
}
- gcc_assert (!a->current == !a->first);
+ gcc_checking_assert (!a->current == !a->first);
if (a->current)
a->indx = a->current->indx;
return changed;
dst_elt = bitmap_elt_insert_after (dst, dst_prev, a_elt->indx);
else
dst_elt->indx = a_elt->indx;
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
{
BITMAP_WORD r = a_elt->bits[ix] ^ b_elt->bits[ix];
/* Ensure that dst->current is valid. */
dst->current = dst->first;
bitmap_elt_clear_from (dst, dst_elt);
- gcc_assert (!dst->current == !dst->first);
+ gcc_checking_assert (!dst->current == !dst->first);
if (dst->current)
dst->indx = dst->current->indx;
}
BITMAP_WORD ior = 0;
bitmap_element *next = a_elt->next;
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
{
BITMAP_WORD r = a_elt->bits[ix] ^ b_elt->bits[ix];
a_elt = next;
}
}
- gcc_assert (!a->current == !a->first);
+ gcc_checking_assert (!a->current == !a->first);
if (a->current)
a->indx = a->current->indx;
}
{
if (a_elt->indx != b_elt->indx)
return false;
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
if (a_elt->bits[ix] != b_elt->bits[ix])
return false;
}
b_elt = b_elt->next;
else
{
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ 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;
else
{
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
if (a_elt->bits[ix] & ~b_elt->bits[ix])
return true;
a_elt = a_elt->next;
BITMAP_WORD ior = 0;
tmp_elt.indx = b_elt->indx;
- for (ix = BITMAP_ELEMENT_WORDS; ix--;)
+ for (ix = 0; ix < BITMAP_ELEMENT_WORDS; ix++)
{
BITMAP_WORD r = b_elt->bits[ix] & ~kill_elt->bits[ix];
ior |= r;
changed = true;
bitmap_elt_clear_from (dst, dst_elt);
}
- gcc_assert (!dst->current == !dst->first);
+ 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_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;
+
+ 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;
+}
\f
/* Debugging function to print out the contents of a bitmap. */
-void
+DEBUG_FUNCTION void
debug_bitmap_file (FILE *file, const_bitmap head)
{
const bitmap_element *ptr;
- fprintf (file, "\nfirst = %p current = %p indx = %u\n",
+ fprintf (file, "\nfirst = " HOST_PTR_PRINTF
+ " current = " HOST_PTR_PRINTF " indx = %u\n",
(void *) head->first, (void *) head->current, head->indx);
for (ptr = head->first; ptr; ptr = ptr->next)
{
unsigned int i, j, col = 26;
- fprintf (file, "\t%p next = %p prev = %p indx = %u\n\t\tbits = {",
+ 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);
/* Function to be called from the debugger to print the contents
of a bitmap. */
-void
+DEBUG_FUNCTION void
debug_bitmap (const_bitmap head)
{
debug_bitmap_file (stdout, head);
/* Function to print out the contents of a bitmap. Unlike debug_bitmap_file,
it does not print anything but the bits. */
-void
+DEBUG_FUNCTION void
bitmap_print (FILE *file, const_bitmap head, const char *prefix, const char *suffix)
{
const char *comma = "";
sprintf (s, "%s:%i (%s)", s1, d->line, d->function);
s[41] = 0;
fprintf (stderr, "%-41s %8d %15"HOST_WIDEST_INT_PRINT"d %15"
- HOST_WIDEST_INT_PRINT"d %15"HOST_WIDEST_INT_PRINT"d %10d\n",
- s, d->created, d->allocated, d->peak, d->current, d->nsearches);
+ HOST_WIDEST_INT_PRINT"d %15"HOST_WIDEST_INT_PRINT"d %10d %10d\n",
+ s, d->created, d->allocated, d->peak, d->current, d->nsearches,
+ d->search_iter);
i->size += d->allocated;
i->count += d->created;
}
return;
fprintf (stderr, "\nBitmap Overall "
- " Allocated Peak Leak searched "
- " per search\n");
+ " Allocated Peak Leak searched "
+ " search itr\n");
fprintf (stderr, "---------------------------------------------------------------------------------\n");
info.count = 0;
info.size = 0;