1 /* 2 * Copyright (c) 1998, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #ifndef SHARE_OPTO_INDEXSET_HPP 26 #define SHARE_OPTO_INDEXSET_HPP 27 28 #include "memory/allocation.hpp" 29 #include "memory/resourceArea.hpp" 30 #include "opto/compile.hpp" 31 #include "opto/regmask.hpp" 32 #include "utilities/count_trailing_zeros.hpp" 33 34 // This file defines the IndexSet class, a set of sparse integer indices. 35 // This data structure is used by the compiler in its liveness analysis and 36 // during register allocation. 37 38 //-------------------------------- class IndexSet ---------------------------- 39 // An IndexSet is a piece-wise bitvector. At the top level, we have an array 40 // of pointers to bitvector chunks called BitBlocks. Each BitBlock has a fixed 41 // size and is allocated from a shared free list. The bits which are set in 42 // each BitBlock correspond to the elements of the set. 43 44 class IndexSet : public ResourceObj { 45 friend class IndexSetIterator; 46 47 public: 48 // When we allocate an IndexSet, it starts off with an array of top level block 49 // pointers of a set length. This size is intended to be large enough for the 50 // majority of IndexSets. In the cases when this size is not large enough, 51 // a separately allocated array is used. 52 53 // The length of the preallocated top level block array 54 enum { preallocated_block_list_size = 16 }; 55 56 // Elements of a IndexSet get decomposed into three fields. The highest order 57 // bits are the block index, which tell which high level block holds the element. 58 // Within that block, the word index indicates which word holds the element. 59 // Finally, the bit index determines which single bit within that word indicates 60 // membership of the element in the set. 61 62 // The lengths of the index bitfields 63 enum { 64 // Each block consists of 256 bits 65 block_index_length = 8, 66 // Split over 4 or 8 words depending on bitness 67 word_index_length = block_index_length - LogBitsPerWord, 68 bit_index_length = block_index_length - word_index_length, 69 }; 70 71 // Derived constants used for manipulating the index bitfields 72 enum { 73 bit_index_offset = 0, // not used 74 word_index_offset = bit_index_length, 75 block_index_offset = bit_index_length + word_index_length, 76 77 bits_per_word = 1 << bit_index_length, 78 words_per_block = 1 << word_index_length, 79 bits_per_block = bits_per_word * words_per_block, 80 81 bit_index_mask = right_n_bits(bit_index_length), 82 word_index_mask = right_n_bits(word_index_length) 83 }; 84 85 // These routines are used for extracting the block, word, and bit index 86 // from an element. get_block_index(uint element)87 static uint get_block_index(uint element) { 88 return element >> block_index_offset; 89 } get_word_index(uint element)90 static uint get_word_index(uint element) { 91 return mask_bits(element >> word_index_offset,word_index_mask); 92 } get_bit_index(uint element)93 static uint get_bit_index(uint element) { 94 return mask_bits(element, bit_index_mask); 95 } 96 97 //------------------------------ class BitBlock ---------------------------- 98 // The BitBlock class is a segment of a bitvector set. 99 100 class BitBlock : public ResourceObj { 101 friend class IndexSetIterator; 102 friend class IndexSet; 103 104 private: 105 // All of BitBlocks fields and methods are declared private. We limit 106 // access to IndexSet and IndexSetIterator. 107 108 // A BitBlock is composed of some number of 32- or 64-bit words. When a BitBlock 109 // is not in use by any IndexSet, it is stored on a free list. The next field 110 // is used by IndexSet to maintain this free list. 111 112 union { 113 uintptr_t _words[words_per_block]; 114 BitBlock *_next; 115 } _data; 116 117 // accessors words()118 uintptr_t* words() { return _data._words; } set_next(BitBlock * next)119 void set_next(BitBlock *next) { _data._next = next; } next()120 BitBlock *next() { return _data._next; } 121 122 // Operations. A BitBlock supports four simple operations, 123 // clear(), member(), insert(), and remove(). These methods do 124 // not assume that the block index has been masked out. 125 clear()126 void clear() { 127 memset(words(), 0, sizeof(uintptr_t) * words_per_block); 128 } 129 member(uint element)130 bool member(uint element) { 131 uint word_index = IndexSet::get_word_index(element); 132 uintptr_t bit_index = IndexSet::get_bit_index(element); 133 134 return ((words()[word_index] & (uintptr_t(1) << bit_index)) != 0); 135 } 136 insert(uint element)137 bool insert(uint element) { 138 uint word_index = IndexSet::get_word_index(element); 139 uintptr_t bit_index = IndexSet::get_bit_index(element); 140 141 uintptr_t bit = uintptr_t(1) << bit_index; 142 uintptr_t before = words()[word_index]; 143 words()[word_index] = before | bit; 144 return ((before & bit) != 0); 145 } 146 remove(uint element)147 bool remove(uint element) { 148 uint word_index = IndexSet::get_word_index(element); 149 uintptr_t bit_index = IndexSet::get_bit_index(element); 150 151 uintptr_t bit = uintptr_t(1) << bit_index; 152 uintptr_t before = words()[word_index]; 153 words()[word_index] = before & ~bit; 154 return ((before & bit) != 0); 155 } 156 }; 157 158 //-------------------------- BitBlock allocation --------------------------- 159 private: 160 161 // All IndexSets share an arena from which they allocate BitBlocks. Unused 162 // BitBlocks are placed on a free list. 163 164 // The number of BitBlocks to allocate at a time 165 enum { bitblock_alloc_chunk_size = 50 }; 166 arena()167 static Arena *arena() { return Compile::current()->indexSet_arena(); } 168 169 static void populate_free_list(); 170 171 public: 172 173 // Invalidate the current free BitBlock list and begin allocation 174 // from a new arena. It is essential that this method is called whenever 175 // the Arena being used for BitBlock allocation is reset. reset_memory(Compile * compile,Arena * arena)176 static void reset_memory(Compile* compile, Arena *arena) { 177 compile->set_indexSet_free_block_list(NULL); 178 compile->set_indexSet_arena(arena); 179 180 // This should probably be done in a static initializer 181 _empty_block.clear(); 182 } 183 184 private: 185 friend class BitBlock; 186 // A distinguished BitBlock which always remains empty. When a new IndexSet is 187 // created, all of its top level BitBlock pointers are initialized to point to 188 // this. 189 static BitBlock _empty_block; 190 191 //-------------------------- Members ------------------------------------------ 192 193 // The number of elements in the set 194 uint _count; 195 196 // The current upper limit of blocks that has been allocated and might be in use 197 uint _current_block_limit; 198 199 // Our top level array of bitvector segments 200 BitBlock **_blocks; 201 202 BitBlock *_preallocated_block_list[preallocated_block_list_size]; 203 204 // The number of top level array entries in use 205 uint _max_blocks; 206 207 // Our assertions need to know the maximum number allowed in the set 208 #ifdef ASSERT 209 uint _max_elements; 210 #endif 211 212 // The next IndexSet on the free list (not used at same time as count) 213 IndexSet *_next; 214 215 public: 216 //-------------------------- Free list operations ------------------------------ 217 // Individual IndexSets can be placed on a free list. This is done in PhaseLive. 218 next()219 IndexSet *next() { 220 return _next; 221 } 222 set_next(IndexSet * next)223 void set_next(IndexSet *next) { 224 _next = next; 225 } 226 227 private: 228 //-------------------------- Utility methods ----------------------------------- 229 230 // Get the block which holds element get_block_containing(uint element) const231 BitBlock *get_block_containing(uint element) const { 232 assert(element < _max_elements, "element out of bounds"); 233 return _blocks[get_block_index(element)]; 234 } 235 236 // Set a block in the top level array set_block(uint index,BitBlock * block)237 void set_block(uint index, BitBlock *block) { 238 _blocks[index] = block; 239 } 240 241 // Get a BitBlock from the free list 242 BitBlock *alloc_block(); 243 244 // Get a BitBlock from the free list and place it in the top level array 245 BitBlock *alloc_block_containing(uint element); 246 247 // Free a block from the top level array, placing it on the free BitBlock list 248 void free_block(uint i); 249 250 public: 251 //-------------------------- Primitive set operations -------------------------- 252 clear()253 void clear() { 254 _count = 0; 255 for (uint i = 0; i < _current_block_limit; i++) { 256 BitBlock *block = _blocks[i]; 257 if (block != &_empty_block) { 258 free_block(i); 259 } 260 } 261 _current_block_limit = 0; 262 } 263 count() const264 uint count() const { return _count; } 265 is_empty() const266 bool is_empty() const { return _count == 0; } 267 member(uint element) const268 bool member(uint element) const { 269 return get_block_containing(element)->member(element); 270 } 271 insert(uint element)272 bool insert(uint element) { 273 if (element == 0) { 274 return 0; 275 } 276 BitBlock *block = get_block_containing(element); 277 if (block == &_empty_block) { 278 block = alloc_block_containing(element); 279 } 280 bool present = block->insert(element); 281 if (!present) { 282 _count++; 283 } 284 return !present; 285 } 286 remove(uint element)287 bool remove(uint element) { 288 BitBlock *block = get_block_containing(element); 289 bool present = block->remove(element); 290 if (present) { 291 _count--; 292 } 293 return present; 294 } 295 296 //-------------------------- Compound set operations ------------------------ 297 // Compute the union of all elements of one and two which interfere 298 // with the RegMask mask. If the degree of the union becomes 299 // exceeds fail_degree, the union bails out. The underlying set is 300 // cleared before the union is performed. 301 uint lrg_union(uint lr1, uint lr2, 302 const uint fail_degree, 303 const class PhaseIFG *ifg, 304 const RegMask &mask); 305 306 307 //------------------------- Construction, initialization ----------------------- 308 IndexSet()309 IndexSet() {} 310 311 // This constructor is used for making a deep copy of a IndexSet. 312 IndexSet(IndexSet *set); 313 314 // Perform initialization on a IndexSet 315 void initialize(uint max_element); 316 317 // Initialize a IndexSet. If the top level BitBlock array needs to be 318 // allocated, do it from the proffered arena. BitBlocks are still allocated 319 // from the static Arena member. 320 void initialize(uint max_element, Arena *arena); 321 322 // Exchange two sets 323 void swap(IndexSet *set); 324 325 //-------------------------- Debugging and statistics -------------------------- 326 327 #ifndef PRODUCT 328 // Output a IndexSet for debugging 329 void dump() const; 330 #endif 331 332 #ifdef ASSERT 333 void tally_iteration_statistics() const; 334 335 // BitBlock allocation statistics 336 static julong _alloc_new; 337 static julong _alloc_total; 338 339 // Block density statistics 340 static julong _total_bits; 341 static julong _total_used_blocks; 342 static julong _total_unused_blocks; 343 344 // Sanity tests 345 void verify() const; 346 347 static int _serial_count; 348 int _serial_number; 349 350 // Check to see if the serial number of the current set is the one we're tracing. 351 // If it is, print a message. check_watch(const char * operation,uint operand) const352 void check_watch(const char *operation, uint operand) const { 353 if (IndexSetWatch != 0) { 354 if (IndexSetWatch == -1 || _serial_number == IndexSetWatch) { 355 tty->print_cr("IndexSet %d : %s ( %d )", _serial_number, operation, operand); 356 } 357 } 358 } check_watch(const char * operation) const359 void check_watch(const char *operation) const { 360 if (IndexSetWatch != 0) { 361 if (IndexSetWatch == -1 || _serial_number == IndexSetWatch) { 362 tty->print_cr("IndexSet %d : %s", _serial_number, operation); 363 } 364 } 365 } 366 367 public: 368 static void print_statistics(); 369 370 #endif 371 }; 372 373 374 //-------------------------------- class IndexSetIterator -------------------- 375 // An iterator for IndexSets. 376 377 class IndexSetIterator { 378 friend class IndexSet; 379 380 private: 381 // The current word we are inspecting 382 uintptr_t _current; 383 384 // What element number are we currently on? 385 uint _value; 386 387 // The index of the next word we will inspect 388 uint _next_word; 389 390 // The index of the next block we will inspect 391 uint _next_block; 392 393 // The number of blocks in the set 394 uint _max_blocks; 395 396 // A pointer to the contents of the current block 397 uintptr_t* _words; 398 399 // A pointer to the blocks in our set 400 IndexSet::BitBlock **_blocks; 401 402 // If the iterator was created from a non-const set, we replace 403 // non-canonical empty blocks with the _empty_block pointer. If 404 // _set is NULL, we do no replacement. 405 IndexSet *_set; 406 407 // Advance to the next non-empty word and return the next 408 // element in the set. 409 uint advance_and_next(); 410 411 public: 412 413 // If an iterator is built from a constant set then empty blocks 414 // are not canonicalized. IndexSetIterator(IndexSet * set)415 IndexSetIterator(IndexSet *set) : 416 _current(0), 417 _value(0), 418 _next_word(IndexSet::words_per_block), 419 _next_block(0), 420 _max_blocks(set->is_empty() ? 0 : set->_current_block_limit), 421 _words(NULL), 422 _blocks(set->_blocks), 423 _set(set) { 424 #ifdef ASSERT 425 if (CollectIndexSetStatistics) { 426 set->tally_iteration_statistics(); 427 } 428 set->check_watch("traversed", set->count()); 429 #endif 430 } 431 IndexSetIterator(const IndexSet * set)432 IndexSetIterator(const IndexSet *set) : 433 _current(0), 434 _value(0), 435 _next_word(IndexSet::words_per_block), 436 _next_block(0), 437 _max_blocks(set->is_empty() ? 0 : set->_current_block_limit), 438 _words(NULL), 439 _blocks(set->_blocks), 440 _set(NULL) 441 { 442 #ifdef ASSERT 443 if (CollectIndexSetStatistics) { 444 set->tally_iteration_statistics(); 445 } 446 // We don't call check_watch from here to avoid bad recursion. 447 // set->check_watch("traversed const", set->count()); 448 #endif 449 } 450 451 // Return the next element of the set. next_value()452 uint next_value() { 453 uintptr_t current = _current; 454 assert(current != 0, "sanity"); 455 uint advance = count_trailing_zeros(current); 456 assert(((current >> advance) & 0x1) == 1, "sanity"); 457 _current = (current >> advance) - 1; 458 _value += advance; 459 return _value; 460 } 461 462 // Return the next element of the set. Return 0 when done. next()463 uint next() { 464 if (_current != 0) { 465 return next_value(); 466 } else if (_next_word < IndexSet::words_per_block || _next_block < _max_blocks) { 467 return advance_and_next(); 468 } else { 469 return 0; 470 } 471 } 472 473 }; 474 475 #endif // SHARE_OPTO_INDEXSET_HPP 476