X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fbitmap.c;h=8d7f1b2aa9536e52528449f0211c08fc84b75f1d;hb=285f2354dc334dac2c0068737cca7d6fa58b1898;hp=5e841e067a5e5fd2b8da5b2cdefbdfdf7a2069f5;hpb=b8ede6a91143ce8a77cd3216bda7559ea931ac7f;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/bitmap.c b/gcc/bitmap.c index 5e841e067a5..8d7f1b2aa95 100644 --- a/gcc/bitmap.c +++ b/gcc/bitmap.c @@ -1,6 +1,6 @@ /* Functions to support general ended bitmaps. Copyright (C) 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, - 2006, 2007 Free Software Foundation, Inc. + 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -21,9 +21,6 @@ along with GCC; see the file COPYING3. If not see #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" @@ -37,11 +34,12 @@ struct bitmap_descriptor const char *function; const char *file; int line; - int allocated; int created; - int peak; - int current; + HOST_WIDEST_INT allocated; + HOST_WIDEST_INT peak; + HOST_WIDEST_INT current; int nsearches; + int search_iter; }; /* Hashtable mapping bitmap names to descriptors. */ @@ -87,7 +85,7 @@ bitmap_descriptor (const char *file, const char *function, int line) slot = (struct bitmap_descriptor **) htab_find_slot_with_hash (bitmap_desc_hash, &loc, htab_hash_pointer (file) + line, - 1); + INSERT); if (*slot) return *slot; *slot = XCNEW (struct bitmap_descriptor); @@ -229,7 +227,7 @@ bitmap_element_allocate (bitmap head) /* 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 @@ -291,7 +289,7 @@ bitmap_elt_clear_from (bitmap head, bitmap_element *elt) /* Clear a bitmap by freeing the linked list. */ -inline void +void bitmap_clear (bitmap head) { if (head->first) @@ -356,7 +354,7 @@ bitmap_obstack_alloc_stat (bitmap_obstack *bit_obstack MEM_STAT_DECL) bit_obstack = &bitmap_default_obstack; map = bit_obstack->heads; if (map) - bit_obstack->heads = (void *)map->first; + bit_obstack->heads = (struct bitmap_head_def *) map->first; else map = XOBNEW (&bit_obstack->obstack, bitmap_head); bitmap_initialize_stat (map, bit_obstack PASS_MEM_STAT); @@ -374,7 +372,7 @@ bitmap_gc_alloc_stat (ALONE_MEM_STAT_DECL) { 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)); @@ -391,7 +389,7 @@ bitmap_obstack_free (bitmap map) if (map) { bitmap_clear (map); - map->first = (void *)map->obstack->heads; + map->first = (bitmap_element *) map->obstack->heads; #ifdef GATHER_STATISTICS register_overhead (map, -((int)sizeof (bitmap_head))); #endif @@ -498,7 +496,7 @@ bitmap_elt_insert_after (bitmap head, bitmap_element *elt, unsigned int indx) } else { - gcc_assert (head->current); + gcc_checking_assert (head->current); node->next = elt->next; if (node->next) node->next->prev = node; @@ -556,12 +554,12 @@ bitmap_find_bit (bitmap head, unsigned int bit) 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 @@ -569,7 +567,11 @@ bitmap_find_bit (bitmap head, unsigned int bit) 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 @@ -577,7 +579,11 @@ bitmap_find_bit (bitmap head, unsigned int bit) 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 @@ -585,7 +591,11 @@ bitmap_find_bit (bitmap head, unsigned int bit) 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. */ @@ -611,11 +621,13 @@ bitmap_clear_bit (bitmap head, int bit) 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; } @@ -767,7 +779,7 @@ bitmap_first_set_bit (const_bitmap a) 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++) { @@ -802,10 +814,63 @@ bitmap_first_set_bit (const_bitmap a) if (!(word & 0x1)) word >>= 1, bit_no += 1; - gcc_assert (word & 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 = a->current ? a->current : a->first; + unsigned bit_no; + BITMAP_WORD word; + int ix; + + 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 >= 0; ix--) + { + word = elt->bits[ix]; + if (word) + goto found_bit; + } + gcc_unreachable (); + found_bit: + bit_no += ix * BITMAP_WORD_BITS; + + /* Binary search for the last set bit. */ +#if GCC_VERSION >= 3004 + gcc_assert (sizeof(long) == sizeof (word)); + bit_no += sizeof (long) * 8 - __builtin_ctzl (word); +#else +#if BITMAP_WORD_BITS > 64 +#error "Fill out the table." +#endif +#if BITMAP_WORD_BITS > 32 + if ((word & 0xffffffff00000000)) + word >>= 32, bit_no += 32; +#endif + if (word & 0xffff0000) + word >>= 16, bit_no += 16; + if (!(word & 0xff00)) + word >>= 8, bit_no += 8; + if (!(word & 0xf0)) + word >>= 4, bit_no += 4; + if (!(word & 12)) + word >>= 2, bit_no += 2; + if (!(word & 2)) + word >>= 1, bit_no += 1; +#endif + + gcc_checking_assert (word & 1); + return bit_no; +} /* DST = A & B. */ @@ -842,7 +907,7 @@ bitmap_and (bitmap dst, const_bitmap a, const_bitmap b) 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]; @@ -861,7 +926,7 @@ bitmap_and (bitmap dst, const_bitmap a, const_bitmap b) /* 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; } @@ -894,7 +959,7 @@ bitmap_and_into (bitmap a, const_bitmap b) 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]; @@ -909,8 +974,8 @@ bitmap_and_into (bitmap a, const_bitmap b) } } 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)); } @@ -926,7 +991,7 @@ bitmap_elt_copy (bitmap dst, bitmap_element *dst_elt, bitmap_element *dst_prev, { 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]; @@ -990,7 +1055,7 @@ bitmap_and_compl (bitmap dst, const_bitmap a, const_bitmap b) 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]; @@ -1016,7 +1081,7 @@ bitmap_and_compl (bitmap dst, const_bitmap a, const_bitmap b) 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]; @@ -1053,7 +1118,7 @@ bitmap_and_compl (bitmap dst, const_bitmap a, const_bitmap b) 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; @@ -1093,7 +1158,7 @@ bitmap_and_compl_into (bitmap a, const_bitmap b) 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; @@ -1109,8 +1174,8 @@ bitmap_and_compl_into (bitmap a, const_bitmap b) 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; } @@ -1141,7 +1206,7 @@ bitmap_set_range (bitmap head, unsigned int start, unsigned int count) 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++) { @@ -1387,7 +1452,7 @@ bitmap_compl_and_into (bitmap a, const_bitmap b) 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; @@ -1404,8 +1469,8 @@ bitmap_compl_and_into (bitmap a, const_bitmap b) 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; } @@ -1428,7 +1493,7 @@ bitmap_elt_ior (bitmap dst, bitmap_element *dst_elt, bitmap_element *dst_prev, 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]) @@ -1445,7 +1510,7 @@ bitmap_elt_ior (bitmap dst, bitmap_element *dst_elt, bitmap_element *dst_prev, 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; @@ -1462,7 +1527,7 @@ bitmap_elt_ior (bitmap dst, bitmap_element *dst_elt, bitmap_element *dst_prev, else src = b_elt; - gcc_assert (src); + gcc_checking_assert (src); changed = bitmap_elt_copy (dst, dst_elt, dst_prev, src, changed); } return changed; @@ -1510,7 +1575,7 @@ bitmap_ior (bitmap dst, const_bitmap a, const_bitmap b) 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; @@ -1549,7 +1614,7 @@ bitmap_ior_into (bitmap a, const_bitmap b) 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; @@ -1584,7 +1649,7 @@ bitmap_xor (bitmap dst, const_bitmap a, const_bitmap b) 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]; @@ -1627,7 +1692,7 @@ bitmap_xor (bitmap dst, const_bitmap a, const_bitmap b) /* 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; } @@ -1669,7 +1734,7 @@ bitmap_xor_into (bitmap a, const_bitmap b) 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]; @@ -1684,7 +1749,7 @@ bitmap_xor_into (bitmap a, const_bitmap b) a_elt = next; } } - gcc_assert (!a->current == !a->first); + gcc_checking_assert (!a->current == !a->first); if (a->current) a->indx = a->current->indx; } @@ -1706,7 +1771,7 @@ bitmap_equal_p (const_bitmap a, const_bitmap b) { 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; } @@ -1731,7 +1796,7 @@ bitmap_intersect_p (const_bitmap a, const_bitmap b) 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; @@ -1758,7 +1823,7 @@ bitmap_intersect_compl_p (const_bitmap a, const_bitmap b) 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; @@ -1814,7 +1879,7 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b, const_bitmap k 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; @@ -1866,7 +1931,7 @@ bitmap_ior_and_compl (bitmap dst, const_bitmap a, const_bitmap b, const_bitmap k 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; @@ -1889,22 +1954,102 @@ bitmap_ior_and_compl_into (bitmap a, const_bitmap from1, const_bitmap from2) 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; +} /* 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); @@ -1930,7 +2075,7 @@ debug_bitmap_file (FILE *file, const_bitmap head) /* 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); @@ -1939,7 +2084,7 @@ debug_bitmap (const_bitmap 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 = ""; @@ -1960,8 +2105,8 @@ bitmap_print (FILE *file, const_bitmap head, const char *prefix, const char *suf /* Used to accumulate statistics about bitmap sizes. */ struct output_info { + HOST_WIDEST_INT size; int count; - int size; }; /* Called via htab_traverse. Output bitmap descriptor pointed out by SLOT @@ -1981,8 +2126,10 @@ print_statistics (void **slot, void *b) s1 = s2 + 4; sprintf (s, "%s:%i (%s)", s1, d->line, d->function); s[41] = 0; - fprintf (stderr, "%-41s %6d %10d %10d %10d %10d\n", s, - d->created, d->allocated, d->peak, d->current, d->nsearches); + fprintf (stderr, "%-41s %8d %15"HOST_WIDEST_INT_PRINT"d %15" + 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; } @@ -2000,14 +2147,14 @@ dump_bitmap_statistics (void) 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; htab_traverse (bitmap_desc_hash, print_statistics, &info); fprintf (stderr, "---------------------------------------------------------------------------------\n"); - fprintf (stderr, "%-40s %7d %10d\n", + fprintf (stderr, "%-40s %9d %15"HOST_WIDEST_INT_PRINT"d\n", "Total", info.count, info.size); fprintf (stderr, "---------------------------------------------------------------------------------\n"); #endif