src/share/vm/opto/indexSet.hpp

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

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

mercurial