< prev index next >

src/hotspot/share/opto/regmask.cpp

Print this page
rev 53991 : 8220159: Optimize various RegMask operations by introducing watermarks
Reviewed-by: neliasso

*** 83,152 **** } //------------------------------ClearToPairs----------------------------------- // Clear out partial bits; leave only bit pairs void RegMask::clear_to_pairs() { ! for( int i = 0; i < RM_SIZE; i++ ) { int bits = _A[i]; bits &= ((bits & 0x55555555)<<1); // 1 hi-bit set for each pair bits |= (bits>>1); // Smear 1 hi-bit into a pair _A[i] = bits; } ! verify_pairs(); } //------------------------------is_aligned_pairs------------------------------- bool RegMask::is_aligned_pairs() const { // Assert that the register mask contains only bit pairs. ! for( int i = 0; i < RM_SIZE; i++ ) { int bits = _A[i]; ! while( bits ) { // Check bits for pairing int bit = bits & -bits; // Extract low bit // Low bit is not odd means its mis-aligned. ! if( (bit & 0x55555555) == 0 ) return false; bits -= bit; // Remove bit from mask // Check for aligned adjacent bit ! if( (bits & (bit<<1)) == 0 ) return false; bits -= (bit<<1); // Remove other halve of pair } } return true; } //------------------------------is_bound1-------------------------------------- // Return TRUE if the mask contains a single bit int RegMask::is_bound1() const { ! if( is_AllStack() ) return false; int bit = -1; // Set to hold the one bit allowed ! for( int i = 0; i < RM_SIZE; i++ ) { ! if( _A[i] ) { // Found some bits ! if( bit != -1 ) return false; // Already had bits, so fail bit = _A[i] & -_A[i]; // Extract 1 bit from mask ! if( bit != _A[i] ) return false; // Found many bits, so fail } } // True for both the empty mask and for a single bit return true; } //------------------------------is_bound2-------------------------------------- // Return TRUE if the mask contains an adjacent pair of bits and no other bits. int RegMask::is_bound_pair() const { ! if( is_AllStack() ) return false; ! int bit = -1; // Set to hold the one bit allowed ! for( int i = 0; i < RM_SIZE; i++ ) { ! if( _A[i] ) { // Found some bits ! if( bit != -1 ) return false; // Already had bits, so fail bit = _A[i] & -(_A[i]); // Extract 1 bit from mask ! if( (bit << 1) != 0 ) { // Bit pair stays in same word? ! if( (bit | (bit<<1)) != _A[i] ) return false; // Require adjacent bit pair and no more bits } else { // Else its a split-pair case ! if( bit != _A[i] ) return false; // Found many bits, so fail i++; // Skip iteration forward ! if( i >= RM_SIZE || _A[i] != 1 ) return false; // Require 1 lo bit in next word } } } // True for both the empty mask and for a bit pair --- 83,155 ---- } //------------------------------ClearToPairs----------------------------------- // Clear out partial bits; leave only bit pairs void RegMask::clear_to_pairs() { ! assert(valid_watermarks(), "sanity"); ! for (int i = _lwm; i <= _hwm; i++) { int bits = _A[i]; bits &= ((bits & 0x55555555)<<1); // 1 hi-bit set for each pair bits |= (bits>>1); // Smear 1 hi-bit into a pair _A[i] = bits; } ! assert(is_aligned_pairs(), "mask is not aligned, adjacent pairs"); } //------------------------------is_aligned_pairs------------------------------- bool RegMask::is_aligned_pairs() const { // Assert that the register mask contains only bit pairs. ! assert(valid_watermarks(), "sanity"); ! for (int i = _lwm; i <= _hwm; i++) { int bits = _A[i]; ! while (bits) { // Check bits for pairing int bit = bits & -bits; // Extract low bit // Low bit is not odd means its mis-aligned. ! if ((bit & 0x55555555) == 0) return false; bits -= bit; // Remove bit from mask // Check for aligned adjacent bit ! if ((bits & (bit<<1)) == 0) return false; bits -= (bit<<1); // Remove other halve of pair } } return true; } //------------------------------is_bound1-------------------------------------- // Return TRUE if the mask contains a single bit int RegMask::is_bound1() const { ! if (is_AllStack()) return false; int bit = -1; // Set to hold the one bit allowed ! assert(valid_watermarks(), "sanity"); ! for (int i = _lwm; i <= _hwm; i++) { ! if (_A[i]) { // Found some bits ! if (bit != -1) return false; // Already had bits, so fail bit = _A[i] & -_A[i]; // Extract 1 bit from mask ! if (bit != _A[i]) return false; // Found many bits, so fail } } // True for both the empty mask and for a single bit return true; } //------------------------------is_bound2-------------------------------------- // Return TRUE if the mask contains an adjacent pair of bits and no other bits. int RegMask::is_bound_pair() const { ! if (is_AllStack()) return false; int bit = -1; // Set to hold the one bit allowed ! assert(valid_watermarks(), "sanity"); ! for (int i = _lwm; i <= _hwm; i++) { ! if (_A[i]) { // Found some bits ! if (bit != -1) return false; // Already had bits, so fail bit = _A[i] & -(_A[i]); // Extract 1 bit from mask ! if ((bit << 1) != 0) { // Bit pair stays in same word? ! if ((bit | (bit<<1)) != _A[i]) return false; // Require adjacent bit pair and no more bits } else { // Else its a split-pair case ! if(bit != _A[i]) return false; // Found many bits, so fail i++; // Skip iteration forward ! if (i > _hwm || _A[i] != 1) return false; // Require 1 lo bit in next word } } } // True for both the empty mask and for a bit pair
*** 158,173 **** //------------------------------find_first_set--------------------------------- // Find the lowest-numbered register set in the mask. Return the // HIGHEST register number in the set, or BAD if no sets. // Works also for size 1. OptoReg::Name RegMask::find_first_set(const int size) const { ! verify_sets(size); ! for (int i = 0; i < RM_SIZE; i++) { if (_A[i]) { // Found some bits - int bit = _A[i] & -_A[i]; // Extract low bit // Convert to bit number, return hi bit in pair ! return OptoReg::Name((i<<_LogWordBits)+find_lowest_bit(bit)+(size-1)); } } return OptoReg::Bad; } --- 161,176 ---- //------------------------------find_first_set--------------------------------- // Find the lowest-numbered register set in the mask. Return the // HIGHEST register number in the set, or BAD if no sets. // Works also for size 1. OptoReg::Name RegMask::find_first_set(const int size) const { ! assert(is_aligned_sets(size), "mask is not aligned, adjacent sets"); ! assert(valid_watermarks(), "sanity"); ! for (int i = _lwm; i <= _hwm; i++) { if (_A[i]) { // Found some bits // Convert to bit number, return hi bit in pair ! return OptoReg::Name((i<<_LogWordBits) + find_lowest_bit(_A[i]) + (size - 1)); } } return OptoReg::Bad; }
*** 175,186 **** // Clear out partial bits; leave only aligned adjacent bit pairs void RegMask::clear_to_sets(const int size) { if (size == 1) return; assert(2 <= size && size <= 16, "update low bits table"); assert(is_power_of_2(size), "sanity"); int low_bits_mask = low_bits[size>>2]; ! for (int i = 0; i < RM_SIZE; i++) { int bits = _A[i]; int sets = (bits & low_bits_mask); for (int j = 1; j < size; j++) { sets = (bits & (sets<<1)); // filter bits which produce whole sets } --- 178,190 ---- // Clear out partial bits; leave only aligned adjacent bit pairs void RegMask::clear_to_sets(const int size) { if (size == 1) return; assert(2 <= size && size <= 16, "update low bits table"); assert(is_power_of_2(size), "sanity"); + assert(valid_watermarks(), "sanity"); int low_bits_mask = low_bits[size>>2]; ! for (int i = _lwm; i <= _hwm; i++) { int bits = _A[i]; int sets = (bits & low_bits_mask); for (int j = 1; j < size; j++) { sets = (bits & (sets<<1)); // filter bits which produce whole sets }
*** 194,214 **** } } } _A[i] = sets; } ! verify_sets(size); } //------------------------------smear_to_sets---------------------------------- // Smear out partial bits to aligned adjacent bit sets void RegMask::smear_to_sets(const int size) { if (size == 1) return; assert(2 <= size && size <= 16, "update low bits table"); assert(is_power_of_2(size), "sanity"); int low_bits_mask = low_bits[size>>2]; ! for (int i = 0; i < RM_SIZE; i++) { int bits = _A[i]; int sets = 0; for (int j = 0; j < size; j++) { sets |= (bits & low_bits_mask); // collect partial bits bits = bits>>1; --- 198,219 ---- } } } _A[i] = sets; } ! assert(is_aligned_sets(size), "mask is not aligned, adjacent sets"); } //------------------------------smear_to_sets---------------------------------- // Smear out partial bits to aligned adjacent bit sets void RegMask::smear_to_sets(const int size) { if (size == 1) return; assert(2 <= size && size <= 16, "update low bits table"); assert(is_power_of_2(size), "sanity"); + assert(valid_watermarks(), "sanity"); int low_bits_mask = low_bits[size>>2]; ! for (int i = _lwm; i <= _hwm; i++) { int bits = _A[i]; int sets = 0; for (int j = 0; j < size; j++) { sets |= (bits & low_bits_mask); // collect partial bits bits = bits>>1;
*** 223,243 **** } } } _A[i] = sets; } ! verify_sets(size); } //------------------------------is_aligned_set-------------------------------- bool RegMask::is_aligned_sets(const int size) const { if (size == 1) return true; assert(2 <= size && size <= 16, "update low bits table"); assert(is_power_of_2(size), "sanity"); int low_bits_mask = low_bits[size>>2]; // Assert that the register mask contains only bit sets. ! for (int i = 0; i < RM_SIZE; i++) { int bits = _A[i]; while (bits) { // Check bits for pairing int bit = bits & -bits; // Extract low bit // Low bit is not odd means its mis-aligned. if ((bit & low_bits_mask) == 0) return false; --- 228,249 ---- } } } _A[i] = sets; } ! assert(is_aligned_sets(size), "mask is not aligned, adjacent sets"); } //------------------------------is_aligned_set-------------------------------- bool RegMask::is_aligned_sets(const int size) const { if (size == 1) return true; assert(2 <= size && size <= 16, "update low bits table"); assert(is_power_of_2(size), "sanity"); int low_bits_mask = low_bits[size>>2]; // Assert that the register mask contains only bit sets. ! assert(valid_watermarks(), "sanity"); ! for (int i = _lwm; i <= _hwm; i++) { int bits = _A[i]; while (bits) { // Check bits for pairing int bit = bits & -bits; // Extract low bit // Low bit is not odd means its mis-aligned. if ((bit & low_bits_mask) == 0) return false;
*** 254,267 **** //------------------------------is_bound_set----------------------------------- // Return TRUE if the mask contains one adjacent set of bits and no other bits. // Works also for size 1. int RegMask::is_bound_set(const int size) const { ! if( is_AllStack() ) return false; assert(1 <= size && size <= 16, "update low bits table"); int bit = -1; // Set to hold the one bit allowed ! for (int i = 0; i < RM_SIZE; i++) { if (_A[i] ) { // Found some bits if (bit != -1) return false; // Already had bits, so fail bit = _A[i] & -_A[i]; // Extract low bit from mask int hi_bit = bit << (size-1); // high bit --- 260,274 ---- //------------------------------is_bound_set----------------------------------- // Return TRUE if the mask contains one adjacent set of bits and no other bits. // Works also for size 1. int RegMask::is_bound_set(const int size) const { ! if (is_AllStack()) return false; assert(1 <= size && size <= 16, "update low bits table"); + assert(valid_watermarks(), "sanity"); int bit = -1; // Set to hold the one bit allowed ! for (int i = _lwm; i <= _hwm; i++) { if (_A[i] ) { // Found some bits if (bit != -1) return false; // Already had bits, so fail bit = _A[i] & -_A[i]; // Extract low bit from mask int hi_bit = bit << (size-1); // high bit
*** 277,287 **** int clear_bit_size = 32-size; int shift_back_size = 32-clear_bit_size; int set = bit>>clear_bit_size; set = set & -set; // Remove sign extension. set = (((set << size) - 1) >> shift_back_size); ! if (i >= RM_SIZE || _A[i] != set) return false; // Require expected low bits in next word } } } // True for both the empty mask and for a bit set --- 284,294 ---- int clear_bit_size = 32-size; int shift_back_size = 32-clear_bit_size; int set = bit>>clear_bit_size; set = set & -set; // Remove sign extension. set = (((set << size) - 1) >> shift_back_size); ! if (i > _hwm || _A[i] != set) return false; // Require expected low bits in next word } } } // True for both the empty mask and for a bit set
*** 290,313 **** //------------------------------is_UP------------------------------------------ // UP means register only, Register plus stack, or stack only is DOWN bool RegMask::is_UP() const { // Quick common case check for DOWN (any stack slot is legal) ! if( is_AllStack() ) return false; // Slower check for any stack bits set (also DOWN) ! if( overlap(Matcher::STACK_ONLY_mask) ) return false; // Not DOWN, so must be UP return true; } //------------------------------Size------------------------------------------- // Compute size of register mask in bits uint RegMask::Size() const { uint sum = 0; ! for (int i = 0; i < RM_SIZE; i++) { sum += population_count(_A[i]); } return sum; } --- 297,321 ---- //------------------------------is_UP------------------------------------------ // UP means register only, Register plus stack, or stack only is DOWN bool RegMask::is_UP() const { // Quick common case check for DOWN (any stack slot is legal) ! if (is_AllStack()) return false; // Slower check for any stack bits set (also DOWN) ! if (overlap(Matcher::STACK_ONLY_mask)) return false; // Not DOWN, so must be UP return true; } //------------------------------Size------------------------------------------- // Compute size of register mask in bits uint RegMask::Size() const { uint sum = 0; ! assert(valid_watermarks(), "sanity"); ! for (int i = _lwm; i <= _hwm; i++) { sum += population_count(_A[i]); } return sum; }
< prev index next >