comparison gcc/bitmap.h @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Functions to support general ended bitmaps. 1 /* Functions to support general ended bitmaps.
2 Copyright (C) 1997-2018 Free Software Foundation, Inc. 2 Copyright (C) 1997-2020 Free Software Foundation, Inc.
3 3
4 This file is part of GCC. 4 This file is part of GCC.
5 5
6 GCC is free software; you can redistribute it and/or modify it under 6 GCC is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License as published by the Free 7 the terms of the GNU General Public License as published by the Free
208 of enumeration, and does also *not* support logical operations on sets. 208 of enumeration, and does also *not* support logical operations on sets.
209 The binary tree representation is only supposed to be used for sets 209 The binary tree representation is only supposed to be used for sets
210 on which many random-access membership tests will happen. */ 210 on which many random-access membership tests will happen. */
211 211
212 #include "obstack.h" 212 #include "obstack.h"
213 #include "array-traits.h"
213 214
214 /* Bitmap memory usage. */ 215 /* Bitmap memory usage. */
215 struct bitmap_usage: public mem_usage 216 class bitmap_usage: public mem_usage
216 { 217 {
218 public:
217 /* Default contructor. */ 219 /* Default contructor. */
218 bitmap_usage (): m_nsearches (0), m_search_iter (0) {} 220 bitmap_usage (): m_nsearches (0), m_search_iter (0) {}
219 /* Constructor. */ 221 /* Constructor. */
220 bitmap_usage (size_t allocated, size_t times, size_t peak, 222 bitmap_usage (size_t allocated, size_t times, size_t peak,
221 uint64_t nsearches, uint64_t search_iter) 223 uint64_t nsearches, uint64_t search_iter)
237 inline void 239 inline void
238 dump (mem_location *loc, mem_usage &total) const 240 dump (mem_location *loc, mem_usage &total) const
239 { 241 {
240 char *location_string = loc->to_string (); 242 char *location_string = loc->to_string ();
241 243
242 fprintf (stderr, "%-48s %10" PRIu64 ":%5.1f%%" 244 fprintf (stderr, "%-48s " PRsa (9) ":%5.1f%%"
243 "%10" PRIu64 "%10" PRIu64 ":%5.1f%%" 245 PRsa (9) PRsa (9) ":%5.1f%%"
244 "%12" PRIu64 "%12" PRIu64 "%10s\n", 246 PRsa (11) PRsa (11) "%10s\n",
245 location_string, (uint64_t)m_allocated, 247 location_string, SIZE_AMOUNT (m_allocated),
246 get_percent (m_allocated, total.m_allocated), 248 get_percent (m_allocated, total.m_allocated),
247 (uint64_t)m_peak, (uint64_t)m_times, 249 SIZE_AMOUNT (m_peak), SIZE_AMOUNT (m_times),
248 get_percent (m_times, total.m_times), 250 get_percent (m_times, total.m_times),
249 m_nsearches, m_search_iter, 251 SIZE_AMOUNT (m_nsearches), SIZE_AMOUNT (m_search_iter),
250 loc->m_ggc ? "ggc" : "heap"); 252 loc->m_ggc ? "ggc" : "heap");
251 253
252 free (location_string); 254 free (location_string);
253 } 255 }
254 256
256 static inline void 258 static inline void
257 dump_header (const char *name) 259 dump_header (const char *name)
258 { 260 {
259 fprintf (stderr, "%-48s %11s%16s%17s%12s%12s%10s\n", name, "Leak", "Peak", 261 fprintf (stderr, "%-48s %11s%16s%17s%12s%12s%10s\n", name, "Leak", "Peak",
260 "Times", "N searches", "Search iter", "Type"); 262 "Times", "N searches", "Search iter", "Type");
261 print_dash_line ();
262 } 263 }
263 264
264 /* Number search operations. */ 265 /* Number search operations. */
265 uint64_t m_nsearches; 266 uint64_t m_nsearches;
266 /* Number of search iterations. */ 267 /* Number of search iterations. */
286 /* Number of bits in each actual element of a bitmap. */ 287 /* Number of bits in each actual element of a bitmap. */
287 288
288 #define BITMAP_ELEMENT_ALL_BITS (BITMAP_ELEMENT_WORDS * BITMAP_WORD_BITS) 289 #define BITMAP_ELEMENT_ALL_BITS (BITMAP_ELEMENT_WORDS * BITMAP_WORD_BITS)
289 290
290 /* Obstack for allocating bitmaps and elements from. */ 291 /* Obstack for allocating bitmaps and elements from. */
291 struct GTY (()) bitmap_obstack { 292 struct bitmap_obstack {
292 struct bitmap_element *elements; 293 struct bitmap_element *elements;
293 struct bitmap_head *heads; 294 bitmap_head *heads;
294 struct obstack GTY ((skip)) obstack; 295 struct obstack obstack;
295 }; 296 };
296 297
297 /* Bitmap set element. We use a linked list to hold only the bits that 298 /* Bitmap set element. We use a linked list to hold only the bits that
298 are set. This allows for use to grow the bitset dynamically without 299 are set. This allows for use to grow the bitset dynamically without
299 having to realloc and copy a giant bit array. 300 having to realloc and copy a giant bit array.
304 element) that are connected by the next fields. The prev pointer 305 element) that are connected by the next fields. The prev pointer
305 is undefined for interior elements. This allows 306 is undefined for interior elements. This allows
306 bitmap_elt_clear_from to be implemented in unit time rather than 307 bitmap_elt_clear_from to be implemented in unit time rather than
307 linear in the number of elements to be freed. */ 308 linear in the number of elements to be freed. */
308 309
309 struct GTY((chain_next ("%h.next"), chain_prev ("%h.prev"))) bitmap_element { 310 struct GTY((chain_next ("%h.next"))) bitmap_element {
310 /* In list form, the next element in the linked list; 311 /* In list form, the next element in the linked list;
311 in tree form, the left child node in the tree. */ 312 in tree form, the left child node in the tree. */
312 struct bitmap_element *next; 313 struct bitmap_element *next;
313 /* In list form, the previous element in the linked list; 314 /* In list form, the previous element in the linked list;
314 in tree form, the right child node in the tree. */ 315 in tree form, the right child node in the tree. */
320 }; 321 };
321 322
322 /* Head of bitmap linked list. The 'current' member points to something 323 /* Head of bitmap linked list. The 'current' member points to something
323 already pointed to by the chain started by first, so GTY((skip)) it. */ 324 already pointed to by the chain started by first, so GTY((skip)) it. */
324 325
325 struct GTY(()) bitmap_head { 326 class GTY(()) bitmap_head {
327 public:
328 static bitmap_obstack crashme;
329 /* Poison obstack to not make it not a valid initialized GC bitmap. */
330 CONSTEXPR bitmap_head()
331 : indx (0), tree_form (false), padding (0), alloc_descriptor (0), first (NULL),
332 current (NULL), obstack (&crashme)
333 {}
326 /* Index of last element looked at. */ 334 /* Index of last element looked at. */
327 unsigned int indx; 335 unsigned int indx;
328 /* False if the bitmap is in list form; true if the bitmap is in tree form. 336 /* False if the bitmap is in list form; true if the bitmap is in tree form.
329 Bitmap iterators only work on bitmaps in list form. */ 337 Bitmap iterators only work on bitmaps in list form. */
330 bool tree_form; 338 unsigned tree_form: 1;
339 /* Next integer is shifted, so padding is needed. */
340 unsigned padding: 2;
341 /* Bitmap UID used for memory allocation statistics. */
342 unsigned alloc_descriptor: 29;
331 /* In list form, the first element in the linked list; 343 /* In list form, the first element in the linked list;
332 in tree form, the root of the tree. */ 344 in tree form, the root of the tree. */
333 bitmap_element *first; 345 bitmap_element *first;
334 /* Last element looked at. */ 346 /* Last element looked at. */
335 bitmap_element * GTY((skip(""))) current; 347 bitmap_element * GTY((skip(""))) current;
336 /* Obstack to allocate elements from. If NULL, then use GGC allocation. */ 348 /* Obstack to allocate elements from. If NULL, then use GGC allocation. */
337 bitmap_obstack *obstack; 349 bitmap_obstack * GTY((skip(""))) obstack;
350
351 /* Dump bitmap. */
338 void dump (); 352 void dump ();
353
354 /* Get bitmap descriptor UID casted to an unsigned integer pointer.
355 Shift the descriptor because pointer_hash<Type>::hash is
356 doing >> 3 shift operation. */
357 unsigned *get_descriptor ()
358 {
359 return (unsigned *)(ptrdiff_t)(alloc_descriptor << 3);
360 }
339 }; 361 };
340 362
341 /* Global data */ 363 /* Global data */
342 extern bitmap_element bitmap_zero_bits; /* Zero bitmap element */ 364 extern bitmap_element bitmap_zero_bits; /* Zero bitmap element */
343 extern bitmap_obstack bitmap_default_obstack; /* Default bitmap obstack */ 365 extern bitmap_obstack bitmap_default_obstack; /* Default bitmap obstack */
392 extern void bitmap_compl_and_into (bitmap, const_bitmap); 414 extern void bitmap_compl_and_into (bitmap, const_bitmap);
393 extern void bitmap_clear_range (bitmap, unsigned int, unsigned int); 415 extern void bitmap_clear_range (bitmap, unsigned int, unsigned int);
394 extern void bitmap_set_range (bitmap, unsigned int, unsigned int); 416 extern void bitmap_set_range (bitmap, unsigned int, unsigned int);
395 extern bool bitmap_ior (bitmap, const_bitmap, const_bitmap); 417 extern bool bitmap_ior (bitmap, const_bitmap, const_bitmap);
396 extern bool bitmap_ior_into (bitmap, const_bitmap); 418 extern bool bitmap_ior_into (bitmap, const_bitmap);
419 extern bool bitmap_ior_into_and_free (bitmap, bitmap *);
397 extern void bitmap_xor (bitmap, const_bitmap, const_bitmap); 420 extern void bitmap_xor (bitmap, const_bitmap, const_bitmap);
398 extern void bitmap_xor_into (bitmap, const_bitmap); 421 extern void bitmap_xor_into (bitmap, const_bitmap);
399 422
400 /* DST = A | (B & C). Return true if DST changes. */ 423 /* DST = A | (B & C). Return true if DST changes. */
401 extern bool bitmap_ior_and_into (bitmap DST, const_bitmap B, const_bitmap C); 424 extern bool bitmap_ior_and_into (bitmap DST, const_bitmap B, const_bitmap C);
411 434
412 /* Set a single bit in a bitmap. Return true if the bit changed. */ 435 /* Set a single bit in a bitmap. Return true if the bit changed. */
413 extern bool bitmap_set_bit (bitmap, int); 436 extern bool bitmap_set_bit (bitmap, int);
414 437
415 /* Return true if a bit is set in a bitmap. */ 438 /* Return true if a bit is set in a bitmap. */
416 extern int bitmap_bit_p (bitmap, int); 439 extern int bitmap_bit_p (const_bitmap, int);
417 440
418 /* Debug functions to print a bitmap. */ 441 /* Debug functions to print a bitmap. */
419 extern void debug_bitmap (const_bitmap); 442 extern void debug_bitmap (const_bitmap);
420 extern void debug_bitmap_file (FILE *, const_bitmap); 443 extern void debug_bitmap_file (FILE *, const_bitmap);
421 444
434 static inline void 457 static inline void
435 bitmap_initialize (bitmap head, bitmap_obstack *obstack CXX_MEM_STAT_INFO) 458 bitmap_initialize (bitmap head, bitmap_obstack *obstack CXX_MEM_STAT_INFO)
436 { 459 {
437 head->first = head->current = NULL; 460 head->first = head->current = NULL;
438 head->indx = head->tree_form = 0; 461 head->indx = head->tree_form = 0;
462 head->padding = 0;
463 head->alloc_descriptor = 0;
439 head->obstack = obstack; 464 head->obstack = obstack;
440 if (GATHER_STATISTICS) 465 if (GATHER_STATISTICS)
441 bitmap_register (head PASS_MEM_STAT); 466 bitmap_register (head PASS_MEM_STAT);
467 }
468
469 /* Release a bitmap (but not its head). This is suitable for pairing with
470 bitmap_initialize. */
471
472 static inline void
473 bitmap_release (bitmap head)
474 {
475 bitmap_clear (head);
476 /* Poison the obstack pointer so the obstack can be safely released.
477 Do not zero it as the bitmap then becomes initialized GC. */
478 head->obstack = &bitmap_head::crashme;
442 } 479 }
443 480
444 /* Allocate and free bitmaps from obstack, malloc and gc'd memory. */ 481 /* Allocate and free bitmaps from obstack, malloc and gc'd memory. */
445 extern bitmap bitmap_alloc (bitmap_obstack *obstack CXX_MEM_STAT_INFO); 482 extern bitmap bitmap_alloc (bitmap_obstack *obstack CXX_MEM_STAT_INFO);
446 #define BITMAP_ALLOC bitmap_alloc 483 #define BITMAP_ALLOC bitmap_alloc
918 #endif 955 #endif
919 956
920 bitmap_head m_bits; 957 bitmap_head m_bits;
921 }; 958 };
922 959
960 /* Base class for bitmap_view; see there for details. */
961 template<typename T, typename Traits = array_traits<T> >
962 class base_bitmap_view
963 {
964 public:
965 typedef typename Traits::element_type array_element_type;
966
967 base_bitmap_view (const T &, bitmap_element *);
968 operator const_bitmap () const { return &m_head; }
969
970 private:
971 base_bitmap_view (const base_bitmap_view &);
972
973 bitmap_head m_head;
974 };
975
976 /* Provides a read-only bitmap view of a single integer bitmask or a
977 constant-sized array of integer bitmasks, or of a wrapper around such
978 bitmasks. */
979 template<typename T, typename Traits>
980 class bitmap_view<T, Traits, true> : public base_bitmap_view<T, Traits>
981 {
982 public:
983 bitmap_view (const T &array)
984 : base_bitmap_view<T, Traits> (array, m_bitmap_elements) {}
985
986 private:
987 /* How many bitmap_elements we need to hold a full T. */
988 static const size_t num_bitmap_elements
989 = CEIL (CHAR_BIT
990 * sizeof (typename Traits::element_type)
991 * Traits::constant_size,
992 BITMAP_ELEMENT_ALL_BITS);
993 bitmap_element m_bitmap_elements[num_bitmap_elements];
994 };
995
996 /* Initialize the view for array ARRAY, using the array of bitmap
997 elements in BITMAP_ELEMENTS (which is known to contain enough
998 entries). */
999 template<typename T, typename Traits>
1000 base_bitmap_view<T, Traits>::base_bitmap_view (const T &array,
1001 bitmap_element *bitmap_elements)
1002 {
1003 m_head.obstack = NULL;
1004
1005 /* The code currently assumes that each element of ARRAY corresponds
1006 to exactly one bitmap_element. */
1007 const size_t array_element_bits = CHAR_BIT * sizeof (array_element_type);
1008 STATIC_ASSERT (BITMAP_ELEMENT_ALL_BITS % array_element_bits == 0);
1009 size_t array_step = BITMAP_ELEMENT_ALL_BITS / array_element_bits;
1010 size_t array_size = Traits::size (array);
1011
1012 /* Process each potential bitmap_element in turn. The loop is written
1013 this way rather than per array element because usually there are
1014 only a small number of array elements per bitmap element (typically
1015 two or four). The inner loops should therefore unroll completely. */
1016 const array_element_type *array_elements = Traits::base (array);
1017 unsigned int indx = 0;
1018 for (size_t array_base = 0;
1019 array_base < array_size;
1020 array_base += array_step, indx += 1)
1021 {
1022 /* How many array elements are in this particular bitmap_element. */
1023 unsigned int array_count
1024 = (STATIC_CONSTANT_P (array_size % array_step == 0)
1025 ? array_step : MIN (array_step, array_size - array_base));
1026
1027 /* See whether we need this bitmap element. */
1028 array_element_type ior = array_elements[array_base];
1029 for (size_t i = 1; i < array_count; ++i)
1030 ior |= array_elements[array_base + i];
1031 if (ior == 0)
1032 continue;
1033
1034 /* Grab the next bitmap element and chain it. */
1035 bitmap_element *bitmap_element = bitmap_elements++;
1036 if (m_head.current)
1037 m_head.current->next = bitmap_element;
1038 else
1039 m_head.first = bitmap_element;
1040 bitmap_element->prev = m_head.current;
1041 bitmap_element->next = NULL;
1042 bitmap_element->indx = indx;
1043 m_head.current = bitmap_element;
1044 m_head.indx = indx;
1045
1046 /* Fill in the bits of the bitmap element. */
1047 if (array_element_bits < BITMAP_WORD_BITS)
1048 {
1049 /* Multiple array elements fit in one element of
1050 bitmap_element->bits. */
1051 size_t array_i = array_base;
1052 for (unsigned int word_i = 0; word_i < BITMAP_ELEMENT_WORDS;
1053 ++word_i)
1054 {
1055 BITMAP_WORD word = 0;
1056 for (unsigned int shift = 0;
1057 shift < BITMAP_WORD_BITS && array_i < array_size;
1058 shift += array_element_bits)
1059 word |= array_elements[array_i++] << shift;
1060 bitmap_element->bits[word_i] = word;
1061 }
1062 }
1063 else
1064 {
1065 /* Array elements are the same size as elements of
1066 bitmap_element->bits, or are an exact multiple of that size. */
1067 unsigned int word_i = 0;
1068 for (unsigned int i = 0; i < array_count; ++i)
1069 for (unsigned int shift = 0; shift < array_element_bits;
1070 shift += BITMAP_WORD_BITS)
1071 bitmap_element->bits[word_i++]
1072 = array_elements[array_base + i] >> shift;
1073 while (word_i < BITMAP_ELEMENT_WORDS)
1074 bitmap_element->bits[word_i++] = 0;
1075 }
1076 }
1077 }
1078
923 #endif /* GCC_BITMAP_H */ 1079 #endif /* GCC_BITMAP_H */