< 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,70 +83,73 @@
}
//------------------------------ClearToPairs-----------------------------------
// Clear out partial bits; leave only bit pairs
void RegMask::clear_to_pairs() {
- for( int i = 0; i < RM_SIZE; i++ ) {
+ 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;
}
- verify_pairs();
+ 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.
- for( int i = 0; i < RM_SIZE; i++ ) {
+ assert(valid_watermarks(), "sanity");
+ for (int i = _lwm; i <= _hwm; i++) {
int bits = _A[i];
- while( bits ) { // Check bits for pairing
+ 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;
+ if ((bit & 0x55555555) == 0) return false;
bits -= bit; // Remove bit from mask
// Check for aligned adjacent bit
- if( (bits & (bit<<1)) == 0 ) return false;
+ 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;
+ 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
+ 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
+ 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;
-
+ 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
+ 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] )
+ 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
+ if(bit != _A[i]) return false; // Found many bits, so fail
i++; // Skip iteration forward
- if( i >= RM_SIZE || _A[i] != 1 )
+ 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,16 +161,16 @@
//------------------------------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++) {
+ 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
- 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::Name((i<<_LogWordBits) + find_lowest_bit(_A[i]) + (size - 1));
}
}
return OptoReg::Bad;
}
@@ -175,12 +178,13 @@
// 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 = 0; i < RM_SIZE; i++) {
+ 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,21 +198,22 @@
}
}
}
_A[i] = sets;
}
- verify_sets(size);
+ 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 = 0; i < RM_SIZE; i++) {
+ 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,21 +228,22 @@
}
}
}
_A[i] = sets;
}
- verify_sets(size);
+ 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.
- for (int i = 0; i < RM_SIZE; i++) {
+ 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,14 +260,15 @@
//------------------------------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;
+ 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 = 0; i < RM_SIZE; i++) {
+ 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,11 +284,11 @@
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)
+ 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,24 +297,25 @@
//------------------------------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() )
+ if (is_AllStack())
return false;
// Slower check for any stack bits set (also DOWN)
- if( overlap(Matcher::STACK_ONLY_mask) )
+ 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++) {
+ assert(valid_watermarks(), "sanity");
+ for (int i = _lwm; i <= _hwm; i++) {
sum += population_count(_A[i]);
}
return sum;
}
< prev index next >