Mercurial > hg > CbC > CbC_gcc
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 */ |