src/share/vm/opto/indexSet.hpp

Fri, 07 Nov 2008 09:29:38 -0800

author
kvn
date
Fri, 07 Nov 2008 09:29:38 -0800
changeset 855
a1980da045cc
parent 435
a61af66fc99e
child 1907
c18cbe5936b8
permissions
-rw-r--r--

6462850: generate biased locking code in C2 ideal graph
Summary: Inline biased locking code in C2 ideal graph during macro nodes expansion
Reviewed-by: never

     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  */
    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.
    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.
    35 class IndexSet : public ResourceObj {
    36  friend class IndexSetIterator;
    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.
    44   // The length of the preallocated top level block array
    45   enum { preallocated_block_list_size = 16 };
    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.
    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   };
    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,
    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,
    69          bit_index_mask = right_n_bits(bit_index_length),
    70          word_index_mask = right_n_bits(word_index_length)
    71   };
    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   }
    85   //------------------------------ class BitBlock ----------------------------
    86   // The BitBlock class is a segment of a bitvector set.
    88   class BitBlock : public ResourceObj {
    89    friend class IndexSetIterator;
    90    friend class IndexSet;
    92    private:
    93     // All of BitBlocks fields and methods are declared private.  We limit
    94     // access to IndexSet and IndexSetIterator.
    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.
   100     union {
   101       uint32 _words[words_per_block];
   102       BitBlock *_next;
   103     } _data;
   105     // accessors
   106     uint32 *words() { return _data._words; }
   107     void set_next(BitBlock *next) { _data._next = next; }
   108     BitBlock *next() { return _data._next; }
   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.
   114     void clear() {
   115       memset(words(), 0, sizeof(uint32) * words_per_block);
   116     }
   118     bool member(uint element) {
   119       uint word_index = IndexSet::get_word_index(element);
   120       uint bit_index = IndexSet::get_bit_index(element);
   122       return ((words()[word_index] & (uint32)(0x1 << bit_index)) != 0);
   123     }
   125     bool insert(uint element) {
   126       uint word_index = IndexSet::get_word_index(element);
   127       uint bit_index = IndexSet::get_bit_index(element);
   129       uint32 bit = (0x1 << bit_index);
   130       uint32 before = words()[word_index];
   131       words()[word_index] = before | bit;
   132       return ((before & bit) != 0);
   133     }
   135     bool remove(uint element) {
   136       uint word_index = IndexSet::get_word_index(element);
   137       uint bit_index = IndexSet::get_bit_index(element);
   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   };
   146   //-------------------------- BitBlock allocation ---------------------------
   147  private:
   149   // All IndexSets share an arena from which they allocate BitBlocks.  Unused
   150   // BitBlocks are placed on a free list.
   152   // The number of BitBlocks to allocate at a time
   153   enum { bitblock_alloc_chunk_size = 50 };
   155   static Arena *arena() { return Compile::current()->indexSet_arena(); }
   157   static void populate_free_list();
   159  public:
   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);
   168    // This should probably be done in a static initializer
   169    _empty_block.clear();
   170   }
   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;
   179   //-------------------------- Members ------------------------------------------
   181   // The number of elements in the set
   182   uint      _count;
   184   // Our top level array of bitvector segments
   185   BitBlock **_blocks;
   187   BitBlock  *_preallocated_block_list[preallocated_block_list_size];
   189   // The number of top level array entries in use
   190   uint       _max_blocks;
   192   // Our assertions need to know the maximum number allowed in the set
   193 #ifdef ASSERT
   194   uint       _max_elements;
   195 #endif
   197   // The next IndexSet on the free list (not used at same time as count)
   198   IndexSet *_next;
   200  public:
   201   //-------------------------- Free list operations ------------------------------
   202   // Individual IndexSets can be placed on a free list.  This is done in PhaseLive.
   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   }
   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   }
   222  private:
   223   //-------------------------- Utility methods -----------------------------------
   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   }
   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   }
   240   // Get a BitBlock from the free list
   241   BitBlock *alloc_block();
   243   // Get a BitBlock from the free list and place it in the top level array
   244   BitBlock *alloc_block_containing(uint element);
   246   // Free a block from the top level array, placing it on the free BitBlock list
   247   void free_block(uint i);
   249  public:
   250   //-------------------------- Primitive set operations --------------------------
   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   }
   266   uint count() const { return _count; }
   268   bool is_empty() const { return _count == 0; }
   270   bool member(uint element) const {
   271     return get_block_containing(element)->member(element);
   272   }
   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   }
   293   bool remove(uint element) {
   294 #ifdef ASSERT
   295     if( VerifyOpto )
   296       check_watch("remove", element);
   297 #endif
   299     BitBlock *block = get_block_containing(element);
   300     bool present = block->remove(element);
   301     if (present) {
   302       _count--;
   303     }
   304     return present;
   305   }
   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);
   318   //------------------------- Construction, initialization -----------------------
   320   IndexSet() {}
   322   // This constructor is used for making a deep copy of a IndexSet.
   323   IndexSet(IndexSet *set);
   325   // Perform initialization on a IndexSet
   326   void initialize(uint max_element);
   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);
   333   // Exchange two sets
   334   void swap(IndexSet *set);
   336   //-------------------------- Debugging and statistics --------------------------
   338 #ifndef PRODUCT
   339   // Output a IndexSet for debugging
   340   void dump() const;
   341 #endif
   343 #ifdef ASSERT
   344   void tally_iteration_statistics() const;
   346   // BitBlock allocation statistics
   347   static uint _alloc_new;
   348   static uint _alloc_total;
   350   // Block density statistics
   351   static long _total_bits;
   352   static long _total_used_blocks;
   353   static long _total_unused_blocks;
   355   // Sanity tests
   356   void verify() const;
   358   static int _serial_count;
   359   int        _serial_number;
   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   }
   378  public:
   379   static void print_statistics();
   381 #endif
   382 };
   385 //-------------------------------- class IndexSetIterator --------------------
   386 // An iterator for IndexSets.
   388 class IndexSetIterator VALUE_OBJ_CLASS_SPEC {
   389  friend class IndexSet;
   391  public:
   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) };
   398   // For an integer of length window_size, what is the first set bit?
   399   static const byte _first_bit[table_size];
   401   // For an integer of length window_size, what is the second set bit?
   402   static const byte _second_bit[table_size];
   404  private:
   405   // The current word we are inspecting
   406   uint32                _current;
   408   // What element number are we currently on?
   409   uint                  _value;
   411   // The index of the next word we will inspect
   412   uint                  _next_word;
   414   // A pointer to the contents of the current block
   415   uint32               *_words;
   417   // The index of the next block we will inspect
   418   uint                  _next_block;
   420   // A pointer to the blocks in our set
   421   IndexSet::BitBlock **_blocks;
   423   // The number of blocks in the set
   424   uint                  _max_blocks;
   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;
   431   // Advance to the next non-empty word and return the next
   432   // element in the set.
   433   uint advance_and_next();
   436  public:
   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);
   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       }
   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 };

mercurial