src/share/vm/opto/indexSet.hpp

changeset 0
f90c822e73f8
child 6876
710a3c8b516e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/share/vm/opto/indexSet.hpp	Wed Apr 27 01:25:04 2016 +0800
     1.3 @@ -0,0 +1,471 @@
     1.4 +/*
     1.5 + * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
     1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.7 + *
     1.8 + * This code is free software; you can redistribute it and/or modify it
     1.9 + * under the terms of the GNU General Public License version 2 only, as
    1.10 + * published by the Free Software Foundation.
    1.11 + *
    1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
    1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    1.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    1.15 + * version 2 for more details (a copy is included in the LICENSE file that
    1.16 + * accompanied this code).
    1.17 + *
    1.18 + * You should have received a copy of the GNU General Public License version
    1.19 + * 2 along with this work; if not, write to the Free Software Foundation,
    1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    1.21 + *
    1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    1.23 + * or visit www.oracle.com if you need additional information or have any
    1.24 + * questions.
    1.25 + *
    1.26 + */
    1.27 +
    1.28 +#ifndef SHARE_VM_OPTO_INDEXSET_HPP
    1.29 +#define SHARE_VM_OPTO_INDEXSET_HPP
    1.30 +
    1.31 +#include "memory/allocation.hpp"
    1.32 +#include "memory/resourceArea.hpp"
    1.33 +#include "opto/compile.hpp"
    1.34 +#include "opto/regmask.hpp"
    1.35 +
    1.36 +// This file defines the IndexSet class, a set of sparse integer indices.
    1.37 +// This data structure is used by the compiler in its liveness analysis and
    1.38 +// during register allocation.
    1.39 +
    1.40 +//-------------------------------- class IndexSet ----------------------------
    1.41 +// An IndexSet is a piece-wise bitvector.  At the top level, we have an array
    1.42 +// of pointers to bitvector chunks called BitBlocks.  Each BitBlock has a fixed
    1.43 +// size and is allocated from a shared free list.  The bits which are set in
    1.44 +// each BitBlock correspond to the elements of the set.
    1.45 +
    1.46 +class IndexSet : public ResourceObj {
    1.47 + friend class IndexSetIterator;
    1.48 +
    1.49 + public:
    1.50 +  // When we allocate an IndexSet, it starts off with an array of top level block
    1.51 +  // pointers of a set length.  This size is intended to be large enough for the
    1.52 +  // majority of IndexSets.  In the cases when this size is not large enough,
    1.53 +  // a separately allocated array is used.
    1.54 +
    1.55 +  // The length of the preallocated top level block array
    1.56 +  enum { preallocated_block_list_size = 16 };
    1.57 +
    1.58 +  // Elements of a IndexSet get decomposed into three fields.  The highest order
    1.59 +  // bits are the block index, which tell which high level block holds the element.
    1.60 +  // Within that block, the word index indicates which word holds the element.
    1.61 +  // Finally, the bit index determines which single bit within that word indicates
    1.62 +  // membership of the element in the set.
    1.63 +
    1.64 +  // The lengths of the index bitfields
    1.65 +  enum { bit_index_length = 5,
    1.66 +         word_index_length = 3,
    1.67 +         block_index_length = 8 // not used
    1.68 +  };
    1.69 +
    1.70 +  // Derived constants used for manipulating the index bitfields
    1.71 +  enum {
    1.72 +         bit_index_offset = 0, // not used
    1.73 +         word_index_offset = bit_index_length,
    1.74 +         block_index_offset = bit_index_length + word_index_length,
    1.75 +
    1.76 +         bits_per_word = 1 << bit_index_length,
    1.77 +         words_per_block = 1 << word_index_length,
    1.78 +         bits_per_block = bits_per_word * words_per_block,
    1.79 +
    1.80 +         bit_index_mask = right_n_bits(bit_index_length),
    1.81 +         word_index_mask = right_n_bits(word_index_length)
    1.82 +  };
    1.83 +
    1.84 +  // These routines are used for extracting the block, word, and bit index
    1.85 +  // from an element.
    1.86 +  static uint get_block_index(uint element) {
    1.87 +    return element >> block_index_offset;
    1.88 +  }
    1.89 +  static uint get_word_index(uint element) {
    1.90 +    return mask_bits(element >> word_index_offset,word_index_mask);
    1.91 +  }
    1.92 +  static uint get_bit_index(uint element) {
    1.93 +    return mask_bits(element,bit_index_mask);
    1.94 +  }
    1.95 +
    1.96 +  //------------------------------ class BitBlock ----------------------------
    1.97 +  // The BitBlock class is a segment of a bitvector set.
    1.98 +
    1.99 +  class BitBlock : public ResourceObj {
   1.100 +   friend class IndexSetIterator;
   1.101 +   friend class IndexSet;
   1.102 +
   1.103 +   private:
   1.104 +    // All of BitBlocks fields and methods are declared private.  We limit
   1.105 +    // access to IndexSet and IndexSetIterator.
   1.106 +
   1.107 +    // A BitBlock is composed of some number of 32 bit words.  When a BitBlock
   1.108 +    // is not in use by any IndexSet, it is stored on a free list.  The next field
   1.109 +    // is used by IndexSet to mainting this free list.
   1.110 +
   1.111 +    union {
   1.112 +      uint32 _words[words_per_block];
   1.113 +      BitBlock *_next;
   1.114 +    } _data;
   1.115 +
   1.116 +    // accessors
   1.117 +    uint32 *words() { return _data._words; }
   1.118 +    void set_next(BitBlock *next) { _data._next = next; }
   1.119 +    BitBlock *next() { return _data._next; }
   1.120 +
   1.121 +    // Operations.  A BitBlock supports four simple operations,
   1.122 +    // clear(), member(), insert(), and remove().  These methods do
   1.123 +    // not assume that the block index has been masked out.
   1.124 +
   1.125 +    void clear() {
   1.126 +      memset(words(), 0, sizeof(uint32) * words_per_block);
   1.127 +    }
   1.128 +
   1.129 +    bool member(uint element) {
   1.130 +      uint word_index = IndexSet::get_word_index(element);
   1.131 +      uint bit_index = IndexSet::get_bit_index(element);
   1.132 +
   1.133 +      return ((words()[word_index] & (uint32)(0x1 << bit_index)) != 0);
   1.134 +    }
   1.135 +
   1.136 +    bool insert(uint element) {
   1.137 +      uint word_index = IndexSet::get_word_index(element);
   1.138 +      uint bit_index = IndexSet::get_bit_index(element);
   1.139 +
   1.140 +      uint32 bit = (0x1 << bit_index);
   1.141 +      uint32 before = words()[word_index];
   1.142 +      words()[word_index] = before | bit;
   1.143 +      return ((before & bit) != 0);
   1.144 +    }
   1.145 +
   1.146 +    bool remove(uint element) {
   1.147 +      uint word_index = IndexSet::get_word_index(element);
   1.148 +      uint bit_index = IndexSet::get_bit_index(element);
   1.149 +
   1.150 +      uint32 bit = (0x1 << bit_index);
   1.151 +      uint32 before = words()[word_index];
   1.152 +      words()[word_index] = before & ~bit;
   1.153 +      return ((before & bit) != 0);
   1.154 +    }
   1.155 +  };
   1.156 +
   1.157 +  //-------------------------- BitBlock allocation ---------------------------
   1.158 + private:
   1.159 +
   1.160 +  // All IndexSets share an arena from which they allocate BitBlocks.  Unused
   1.161 +  // BitBlocks are placed on a free list.
   1.162 +
   1.163 +  // The number of BitBlocks to allocate at a time
   1.164 +  enum { bitblock_alloc_chunk_size = 50 };
   1.165 +
   1.166 +  static Arena *arena() { return Compile::current()->indexSet_arena(); }
   1.167 +
   1.168 +  static void populate_free_list();
   1.169 +
   1.170 + public:
   1.171 +
   1.172 +  // Invalidate the current free BitBlock list and begin allocation
   1.173 +  // from a new arena.  It is essential that this method is called whenever
   1.174 +  // the Arena being used for BitBlock allocation is reset.
   1.175 +  static void reset_memory(Compile* compile, Arena *arena) {
   1.176 +    compile->set_indexSet_free_block_list(NULL);
   1.177 +    compile->set_indexSet_arena(arena);
   1.178 +
   1.179 +   // This should probably be done in a static initializer
   1.180 +   _empty_block.clear();
   1.181 +  }
   1.182 +
   1.183 + private:
   1.184 +  friend class BitBlock;
   1.185 +  // A distinguished BitBlock which always remains empty.  When a new IndexSet is
   1.186 +  // created, all of its top level BitBlock pointers are initialized to point to
   1.187 +  // this.
   1.188 +  static BitBlock _empty_block;
   1.189 +
   1.190 +  //-------------------------- Members ------------------------------------------
   1.191 +
   1.192 +  // The number of elements in the set
   1.193 +  uint      _count;
   1.194 +
   1.195 +  // Our top level array of bitvector segments
   1.196 +  BitBlock **_blocks;
   1.197 +
   1.198 +  BitBlock  *_preallocated_block_list[preallocated_block_list_size];
   1.199 +
   1.200 +  // The number of top level array entries in use
   1.201 +  uint       _max_blocks;
   1.202 +
   1.203 +  // Our assertions need to know the maximum number allowed in the set
   1.204 +#ifdef ASSERT
   1.205 +  uint       _max_elements;
   1.206 +#endif
   1.207 +
   1.208 +  // The next IndexSet on the free list (not used at same time as count)
   1.209 +  IndexSet *_next;
   1.210 +
   1.211 + public:
   1.212 +  //-------------------------- Free list operations ------------------------------
   1.213 +  // Individual IndexSets can be placed on a free list.  This is done in PhaseLive.
   1.214 +
   1.215 +  IndexSet *next() {
   1.216 +#ifdef ASSERT
   1.217 +    if( VerifyOpto ) {
   1.218 +      check_watch("removed from free list?", ((_next == NULL) ? 0 : _next->_serial_number));
   1.219 +    }
   1.220 +#endif
   1.221 +    return _next;
   1.222 +  }
   1.223 +
   1.224 +  void set_next(IndexSet *next) {
   1.225 +#ifdef ASSERT
   1.226 +    if( VerifyOpto ) {
   1.227 +      check_watch("put on free list?", ((next == NULL) ? 0 : next->_serial_number));
   1.228 +    }
   1.229 +#endif
   1.230 +    _next = next;
   1.231 +  }
   1.232 +
   1.233 + private:
   1.234 +  //-------------------------- Utility methods -----------------------------------
   1.235 +
   1.236 +  // Get the block which holds element
   1.237 +  BitBlock *get_block_containing(uint element) const {
   1.238 +    assert(element < _max_elements, "element out of bounds");
   1.239 +    return _blocks[get_block_index(element)];
   1.240 +  }
   1.241 +
   1.242 +  // Set a block in the top level array
   1.243 +  void set_block(uint index, BitBlock *block) {
   1.244 +#ifdef ASSERT
   1.245 +    if( VerifyOpto )
   1.246 +      check_watch("set block", index);
   1.247 +#endif
   1.248 +    _blocks[index] = block;
   1.249 +  }
   1.250 +
   1.251 +  // Get a BitBlock from the free list
   1.252 +  BitBlock *alloc_block();
   1.253 +
   1.254 +  // Get a BitBlock from the free list and place it in the top level array
   1.255 +  BitBlock *alloc_block_containing(uint element);
   1.256 +
   1.257 +  // Free a block from the top level array, placing it on the free BitBlock list
   1.258 +  void free_block(uint i);
   1.259 +
   1.260 + public:
   1.261 +  //-------------------------- Primitive set operations --------------------------
   1.262 +
   1.263 +  void clear() {
   1.264 +#ifdef ASSERT
   1.265 +    if( VerifyOpto )
   1.266 +      check_watch("clear");
   1.267 +#endif
   1.268 +    _count = 0;
   1.269 +    for (uint i = 0; i < _max_blocks; i++) {
   1.270 +      BitBlock *block = _blocks[i];
   1.271 +      if (block != &_empty_block) {
   1.272 +        free_block(i);
   1.273 +      }
   1.274 +    }
   1.275 +  }
   1.276 +
   1.277 +  uint count() const { return _count; }
   1.278 +
   1.279 +  bool is_empty() const { return _count == 0; }
   1.280 +
   1.281 +  bool member(uint element) const {
   1.282 +    return get_block_containing(element)->member(element);
   1.283 +  }
   1.284 +
   1.285 +  bool insert(uint element) {
   1.286 +#ifdef ASSERT
   1.287 +    if( VerifyOpto )
   1.288 +      check_watch("insert", element);
   1.289 +#endif
   1.290 +    if (element == 0) {
   1.291 +      return 0;
   1.292 +    }
   1.293 +    BitBlock *block = get_block_containing(element);
   1.294 +    if (block == &_empty_block) {
   1.295 +      block = alloc_block_containing(element);
   1.296 +    }
   1.297 +    bool present = block->insert(element);
   1.298 +    if (!present) {
   1.299 +      _count++;
   1.300 +    }
   1.301 +    return !present;
   1.302 +  }
   1.303 +
   1.304 +  bool remove(uint element) {
   1.305 +#ifdef ASSERT
   1.306 +    if( VerifyOpto )
   1.307 +      check_watch("remove", element);
   1.308 +#endif
   1.309 +
   1.310 +    BitBlock *block = get_block_containing(element);
   1.311 +    bool present = block->remove(element);
   1.312 +    if (present) {
   1.313 +      _count--;
   1.314 +    }
   1.315 +    return present;
   1.316 +  }
   1.317 +
   1.318 +  //-------------------------- Compound set operations ------------------------
   1.319 +  // Compute the union of all elements of one and two which interfere
   1.320 +  // with the RegMask mask.  If the degree of the union becomes
   1.321 +  // exceeds fail_degree, the union bails out.  The underlying set is
   1.322 +  // cleared before the union is performed.
   1.323 +  uint lrg_union(uint lr1, uint lr2,
   1.324 +                 const uint fail_degree,
   1.325 +                 const class PhaseIFG *ifg,
   1.326 +                 const RegMask &mask);
   1.327 +
   1.328 +
   1.329 +  //------------------------- Construction, initialization -----------------------
   1.330 +
   1.331 +  IndexSet() {}
   1.332 +
   1.333 +  // This constructor is used for making a deep copy of a IndexSet.
   1.334 +  IndexSet(IndexSet *set);
   1.335 +
   1.336 +  // Perform initialization on a IndexSet
   1.337 +  void initialize(uint max_element);
   1.338 +
   1.339 +  // Initialize a IndexSet.  If the top level BitBlock array needs to be
   1.340 +  // allocated, do it from the proffered arena.  BitBlocks are still allocated
   1.341 +  // from the static Arena member.
   1.342 +  void initialize(uint max_element, Arena *arena);
   1.343 +
   1.344 +  // Exchange two sets
   1.345 +  void swap(IndexSet *set);
   1.346 +
   1.347 +  //-------------------------- Debugging and statistics --------------------------
   1.348 +
   1.349 +#ifndef PRODUCT
   1.350 +  // Output a IndexSet for debugging
   1.351 +  void dump() const;
   1.352 +#endif
   1.353 +
   1.354 +#ifdef ASSERT
   1.355 +  void tally_iteration_statistics() const;
   1.356 +
   1.357 +  // BitBlock allocation statistics
   1.358 +  static julong _alloc_new;
   1.359 +  static julong _alloc_total;
   1.360 +
   1.361 +  // Block density statistics
   1.362 +  static julong _total_bits;
   1.363 +  static julong _total_used_blocks;
   1.364 +  static julong _total_unused_blocks;
   1.365 +
   1.366 +  // Sanity tests
   1.367 +  void verify() const;
   1.368 +
   1.369 +  static int _serial_count;
   1.370 +  int        _serial_number;
   1.371 +
   1.372 +  // Check to see if the serial number of the current set is the one we're tracing.
   1.373 +  // If it is, print a message.
   1.374 +  void check_watch(const char *operation, uint operand) const {
   1.375 +    if (IndexSetWatch != 0) {
   1.376 +      if (IndexSetWatch == -1 || _serial_number == IndexSetWatch) {
   1.377 +        tty->print_cr("IndexSet %d : %s ( %d )", _serial_number, operation, operand);
   1.378 +      }
   1.379 +    }
   1.380 +  }
   1.381 +  void check_watch(const char *operation) const {
   1.382 +    if (IndexSetWatch != 0) {
   1.383 +      if (IndexSetWatch == -1 || _serial_number == IndexSetWatch) {
   1.384 +        tty->print_cr("IndexSet %d : %s", _serial_number, operation);
   1.385 +      }
   1.386 +    }
   1.387 +  }
   1.388 +
   1.389 + public:
   1.390 +  static void print_statistics();
   1.391 +
   1.392 +#endif
   1.393 +};
   1.394 +
   1.395 +
   1.396 +//-------------------------------- class IndexSetIterator --------------------
   1.397 +// An iterator for IndexSets.
   1.398 +
   1.399 +class IndexSetIterator VALUE_OBJ_CLASS_SPEC {
   1.400 + friend class IndexSet;
   1.401 +
   1.402 + public:
   1.403 +
   1.404 +  // We walk over the bits in a word in chunks of size window_size.
   1.405 +  enum { window_size = 5,
   1.406 +         window_mask = right_n_bits(window_size),
   1.407 +         table_size  = (1 << window_size) };
   1.408 +
   1.409 +  // For an integer of length window_size, what is the first set bit?
   1.410 +  static const byte _first_bit[table_size];
   1.411 +
   1.412 +  // For an integer of length window_size, what is the second set bit?
   1.413 +  static const byte _second_bit[table_size];
   1.414 +
   1.415 + private:
   1.416 +  // The current word we are inspecting
   1.417 +  uint32                _current;
   1.418 +
   1.419 +  // What element number are we currently on?
   1.420 +  uint                  _value;
   1.421 +
   1.422 +  // The index of the next word we will inspect
   1.423 +  uint                  _next_word;
   1.424 +
   1.425 +  // A pointer to the contents of the current block
   1.426 +  uint32               *_words;
   1.427 +
   1.428 +  // The index of the next block we will inspect
   1.429 +  uint                  _next_block;
   1.430 +
   1.431 +  // A pointer to the blocks in our set
   1.432 +  IndexSet::BitBlock **_blocks;
   1.433 +
   1.434 +  // The number of blocks in the set
   1.435 +  uint                  _max_blocks;
   1.436 +
   1.437 +  // If the iterator was created from a non-const set, we replace
   1.438 +  // non-canonical empty blocks with the _empty_block pointer.  If
   1.439 +  // _set is NULL, we do no replacement.
   1.440 +  IndexSet            *_set;
   1.441 +
   1.442 +  // Advance to the next non-empty word and return the next
   1.443 +  // element in the set.
   1.444 +  uint advance_and_next();
   1.445 +
   1.446 +
   1.447 + public:
   1.448 +
   1.449 +  // If an iterator is built from a constant set then empty blocks
   1.450 +  // are not canonicalized.
   1.451 +  IndexSetIterator(IndexSet *set);
   1.452 +  IndexSetIterator(const IndexSet *set);
   1.453 +
   1.454 +  // Return the next element of the set.  Return 0 when done.
   1.455 +  uint next() {
   1.456 +    uint current = _current;
   1.457 +    if (current != 0) {
   1.458 +      uint value = _value;
   1.459 +      while (mask_bits(current,window_mask) == 0) {
   1.460 +        current >>= window_size;
   1.461 +        value += window_size;
   1.462 +      }
   1.463 +
   1.464 +      uint advance = _second_bit[mask_bits(current,window_mask)];
   1.465 +      _current = current >> advance;
   1.466 +      _value = value + advance;
   1.467 +      return value + _first_bit[mask_bits(current,window_mask)];
   1.468 +    } else {
   1.469 +      return advance_and_next();
   1.470 +    }
   1.471 +  }
   1.472 +};
   1.473 +
   1.474 +#endif // SHARE_VM_OPTO_INDEXSET_HPP

mercurial