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