< 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 >