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