1 Star 0 Fork 74

LeoFang / openjdk-1.8.0

forked from src-openEuler / openjdk-1.8.0 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
8220159-Optimize-various-RegMask-operations-by-introducing-watermarks.patch 19.72 KB
一键复制 编辑 原始数据 按行查看 历史
jdkboy 提交于 2020-08-31 10:08 . Add several enhancement patches
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp
index de6d443cd..abbd4449f 100644
--- a/hotspot/src/share/vm/opto/chaitin.hpp
+++ b/hotspot/src/share/vm/opto/chaitin.hpp
@@ -111,9 +111,9 @@ public:
_msize_valid=1;
if (_is_vector) {
assert(!_fat_proj, "sanity");
- _mask.verify_sets(_num_regs);
+ assert(_mask.is_aligned_sets(_num_regs), "mask is not aligned, adjacent sets");
} else if (_num_regs == 2 && !_fat_proj) {
- _mask.verify_pairs();
+ assert(_mask.is_aligned_pairs(), "mask is not aligned, adjacent pairs");
}
#endif
}
diff --git a/hotspot/src/share/vm/opto/regmask.cpp b/hotspot/src/share/vm/opto/regmask.cpp
index 352ccfb9d..d92f09eb6 100644
--- a/hotspot/src/share/vm/opto/regmask.cpp
+++ b/hotspot/src/share/vm/opto/regmask.cpp
@@ -74,7 +74,8 @@ int find_lowest_bit( uint32 mask ) {
}
// Find highest 1, or return 32 if empty
-int find_hihghest_bit( uint32 mask ) {
+int find_highest_bit( uint32 mask ) {
+ assert(mask != 0, "precondition");
int n = 0;
if( mask > 0xffff ) {
mask >>= 16;
@@ -167,13 +168,14 @@ OptoReg::Name RegMask::find_first_pair() const {
//------------------------------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");
}
//------------------------------SmearToPairs-----------------------------------
@@ -188,10 +190,14 @@ void RegMask::smear_to_pairs() {
verify_pairs();
}
-//------------------------------is_aligned_pairs-------------------------------
+bool RegMask::is_misaligned_pair() const {
+ return Size() == 2 && !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
int bit = bits & -bits; // Extract low bit
@@ -206,39 +212,28 @@ bool RegMask::is_aligned_pairs() const {
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;
+bool RegMask::is_bound1() const {
+ if (is_AllStack()) return false;
+ return Size() == 1;
}
//------------------------------is_bound2--------------------------------------
// Return TRUE if the mask contains an adjacent pair of bits and no other bits.
-int RegMask::is_bound_pair() const {
+bool RegMask::is_bound_pair() const {
if( is_AllStack() ) return false;
-
+ assert(valid_watermarks(), "sanity");
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?
+ 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
+ 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 )
+ i++; // Skip iteration forward
+ if( i > _hwm || _A[i] != 1 )
return false; // Require 1 lo bit in next word
}
}
@@ -247,31 +242,44 @@ int RegMask::is_bound_pair() const {
return true;
}
+// Test for a single adjacent set of ideal register's size.
+bool RegMask::is_bound(uint ireg) const {
+ if (is_vector(ireg)) {
+ if (is_bound_set(num_registers(ireg)))
+ return true;
+ } else if (is_bound1() || is_bound_pair()) {
+ return true;
+ }
+ return false;
+}
+
+
+
static int low_bits[3] = { 0x55555555, 0x11111111, 0x01010101 };
-//------------------------------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;
}
-//------------------------------clear_to_sets----------------------------------
// 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 <= 8, "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++) {
@@ -286,17 +294,17 @@ void RegMask::clear_to_sets(const int size) {
}
_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 <= 8, "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++) {
@@ -312,17 +320,17 @@ void RegMask::smear_to_sets(const int size) {
}
_A[i] = sets;
}
- verify_sets(size);
+ assert(is_aligned_sets(size), "mask is not aligned, adjacent sets");
}
-//------------------------------is_aligned_set--------------------------------
+// Assert that the register mask contains only bit sets.
bool RegMask::is_aligned_sets(const int size) const {
if (size == 1) return true;
assert(2 <= size && size <= 8, "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
@@ -339,14 +347,14 @@ bool RegMask::is_aligned_sets(const int size) const {
return true;
}
-//------------------------------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 <= 8, "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
@@ -364,7 +372,7 @@ int RegMask::is_bound_set(const int size) const {
int set = bit>>24;
set = set & -set; // Remove sign extension.
set = (((set << size) - 1) >> 8);
- if (i >= RM_SIZE || _A[i] != set)
+ if (i > _hwm || _A[i] != set)
return false; // Require expected low bits in next word
}
}
@@ -373,7 +381,6 @@ int RegMask::is_bound_set(const int size) const {
return true;
}
-//------------------------------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)
@@ -386,22 +393,22 @@ bool RegMask::is_UP() const {
return true;
}
-//------------------------------Size-------------------------------------------
// Compute size of register mask in bits
uint RegMask::Size() const {
extern uint8 bitsInByte[256];
uint sum = 0;
- for( int i = 0; i < RM_SIZE; i++ )
+ assert(valid_watermarks(), "sanity");
+ for( int i = _lwm; i <= _hwm; i++ ) {
sum +=
bitsInByte[(_A[i]>>24) & 0xff] +
bitsInByte[(_A[i]>>16) & 0xff] +
bitsInByte[(_A[i]>> 8) & 0xff] +
bitsInByte[ _A[i] & 0xff];
+ }
return sum;
}
#ifndef PRODUCT
-//------------------------------print------------------------------------------
void RegMask::dump(outputStream *st) const {
st->print("[");
RegMask rm = *this; // Structure copy into local temp
diff --git a/hotspot/src/share/vm/opto/regmask.hpp b/hotspot/src/share/vm/opto/regmask.hpp
index 5ceebb3fb..6cef16ad7 100644
--- a/hotspot/src/share/vm/opto/regmask.hpp
+++ b/hotspot/src/share/vm/opto/regmask.hpp
@@ -44,27 +44,12 @@
# include "adfiles/adGlobals_ppc_64.hpp"
#endif
-// Some fun naming (textual) substitutions:
-//
-// RegMask::get_low_elem() ==> RegMask::find_first_elem()
-// RegMask::Special ==> RegMask::Empty
-// RegMask::_flags ==> RegMask::is_AllStack()
-// RegMask::operator<<=() ==> RegMask::Insert()
-// RegMask::operator>>=() ==> RegMask::Remove()
-// RegMask::Union() ==> RegMask::OR
-// RegMask::Inter() ==> RegMask::AND
-//
-// OptoRegister::RegName ==> OptoReg::Name
-//
-// OptoReg::stack0() ==> _last_Mach_Reg or ZERO in core version
-//
-// numregs in chaitin ==> proper degree in chaitin
//-------------Non-zero bit search methods used by RegMask---------------------
// Find lowest 1, or return 32 if empty
int find_lowest_bit( uint32 mask );
// Find highest 1, or return 32 if empty
-int find_hihghest_bit( uint32 mask );
+int find_highest_bit( uint32 mask );
//------------------------------RegMask----------------------------------------
// The ADL file describes how to print the machine-specific registers, as well
@@ -97,6 +82,12 @@ class RegMask VALUE_OBJ_CLASS_SPEC {
public:
enum { CHUNK_SIZE = RM_SIZE*_WordBits };
+ // The low and high water marks represents the lowest and highest word
+ // that might contain set register mask bits, respectively. We guarantee
+ // that there are no bits in words outside this range, but any word at
+ // and between the two marks can still be 0.
+ int _lwm;
+ int _hwm;
// SlotsPerLong is 2, since slots are 32 bits and longs are 64 bits.
// Also, consider the maximum alignment size for a normally allocated
@@ -126,13 +117,21 @@ public:
# define BODY(I) _A[I] = a##I;
FORALL_BODY
# undef BODY
+ _lwm = 0;
+ _hwm = RM_SIZE - 1;
+ while (_hwm > 0 && _A[_hwm] == 0) _hwm--;
+ while ((_lwm < _hwm) && _A[_lwm] == 0) _lwm++;
+ assert(valid_watermarks(), "post-condition");
}
// Handy copying constructor
RegMask( RegMask *rm ) {
-# define BODY(I) _A[I] = rm->_A[I];
- FORALL_BODY
-# undef BODY
+ _hwm = rm->_hwm;
+ _lwm = rm->_lwm;
+ for (int i = 0; i < RM_SIZE; i++) {
+ _A[i] = rm->_A[i];
+ }
+ assert(valid_watermarks(), "post-condition");
}
// Construct an empty mask
@@ -162,30 +161,36 @@ public:
// Test for being a not-empty mask.
int is_NotEmpty( ) const {
+ assert(valid_watermarks(), "sanity");
int tmp = 0;
-# define BODY(I) tmp |= _A[I];
- FORALL_BODY
-# undef BODY
+ for (int i = _lwm; i <= _hwm; i++) {
+ tmp |= _A[i];
+ }
return tmp;
}
// Find lowest-numbered register from mask, or BAD if mask is empty.
OptoReg::Name find_first_elem() const {
- int base, bits;
-# define BODY(I) if( (bits = _A[I]) != 0 ) base = I<<_LogWordBits; else
- FORALL_BODY
-# undef BODY
- { base = OptoReg::Bad; bits = 1<<0; }
- return OptoReg::Name(base + find_lowest_bit(bits));
+ assert(valid_watermarks(), "sanity");
+ for (int i = _lwm; i <= _hwm; i++) {
+ int bits = _A[i];
+ if (bits) {
+ return OptoReg::Name((i<<_LogWordBits) + find_lowest_bit(bits));
+ }
+ }
+ return OptoReg::Name(OptoReg::Bad);
}
+
// Get highest-numbered register from mask, or BAD if mask is empty.
OptoReg::Name find_last_elem() const {
- int base, bits;
-# define BODY(I) if( (bits = _A[RM_SIZE-1-I]) != 0 ) base = (RM_SIZE-1-I)<<_LogWordBits; else
- FORALL_BODY
-# undef BODY
- { base = OptoReg::Bad; bits = 1<<0; }
- return OptoReg::Name(base + find_hihghest_bit(bits));
+ assert(valid_watermarks(), "sanity");
+ for (int i = _hwm; i >= _lwm; i--) {
+ int bits = _A[i];
+ if (bits) {
+ return OptoReg::Name((i<<_LogWordBits) + find_highest_bit(bits));
+ }
+ }
+ return OptoReg::Name(OptoReg::Bad);
}
// Find the lowest-numbered register pair in the mask. Return the
@@ -199,25 +204,34 @@ public:
void smear_to_pairs();
// Verify that the mask contains only aligned adjacent bit pairs
void verify_pairs() const { assert( is_aligned_pairs(), "mask is not aligned, adjacent pairs" ); }
+
+#ifdef ASSERT
+ // Verify watermarks are sane, i.e., within bounds and that no
+ // register words below or above the watermarks have bits set.
+ bool valid_watermarks() const {
+ assert(_hwm >= 0 && _hwm < RM_SIZE, err_msg("_hwm out of range: %d", _hwm));
+ assert(_lwm >= 0 && _lwm < RM_SIZE, err_msg("_lwm out of range: %d", _lwm));
+ for (int i = 0; i < _lwm; i++) {
+ assert(_A[i] == 0, err_msg("_lwm too high: %d regs at: %d", _lwm, i));
+ }
+ for (int i = _hwm + 1; i < RM_SIZE; i++) {
+ assert(_A[i] == 0, err_msg("_hwm too low: %d regs at: %d", _hwm, i));
+ }
+ return true;
+ }
+#endif // !ASSERT
+
// Test that the mask contains only aligned adjacent bit pairs
bool is_aligned_pairs() const;
// mask is a pair of misaligned registers
- bool is_misaligned_pair() const { return Size()==2 && !is_aligned_pairs(); }
+ bool is_misaligned_pair() const;
// Test for single register
- int is_bound1() const;
+ bool is_bound1() const;
// Test for a single adjacent pair
- int is_bound_pair() const;
+ bool is_bound_pair() const;
// Test for a single adjacent set of ideal register's size.
- int is_bound(uint ireg) const {
- if (is_vector(ireg)) {
- if (is_bound_set(num_registers(ireg)))
- return true;
- } else if (is_bound1() || is_bound_pair()) {
- return true;
- }
- return false;
- }
+ bool is_bound(uint ireg) const;
// Find the lowest-numbered register set in the mask. Return the
// HIGHEST register number in the set, or BAD if no sets.
@@ -228,8 +242,6 @@ public:
void clear_to_sets(const int size);
// Smear out partial bits to aligned adjacent bit sets.
void smear_to_sets(const int size);
- // Verify that the mask contains only aligned adjacent bit sets
- void verify_sets(int size) const { assert(is_aligned_sets(size), "mask is not aligned, adjacent sets"); }
// Test that the mask contains only aligned adjacent bit sets
bool is_aligned_sets(const int size) const;
@@ -244,11 +256,14 @@ public:
// Fast overlap test. Non-zero if any registers in common.
int overlap( const RegMask &rm ) const {
- return
-# define BODY(I) (_A[I] & rm._A[I]) |
- FORALL_BODY
-# undef BODY
- 0 ;
+ assert(valid_watermarks() && rm.valid_watermarks(), "sanity");
+ int hwm = MIN2(_hwm, rm._hwm);
+ int lwm = MAX2(_lwm, rm._lwm);
+ int result = 0;
+ for (int i = lwm; i <= hwm; i++) {
+ result |= _A[i] & rm._A[i];
+ }
+ return result;
}
// Special test for register pressure based splitting
@@ -257,22 +272,29 @@ public:
// Clear a register mask
void Clear( ) {
-# define BODY(I) _A[I] = 0;
- FORALL_BODY
-# undef BODY
+ _lwm = RM_SIZE - 1;
+ _hwm = 0;
+ memset(_A, 0, sizeof(int)*RM_SIZE);
+ assert(valid_watermarks(), "sanity");
}
// Fill a register mask with 1's
void Set_All( ) {
-# define BODY(I) _A[I] = -1;
- FORALL_BODY
-# undef BODY
+ _lwm = 0;
+ _hwm = RM_SIZE - 1;
+ memset(_A, 0xFF, sizeof(int)*RM_SIZE);
+ assert(valid_watermarks(), "sanity");
}
// Insert register into mask
void Insert( OptoReg::Name reg ) {
- assert( reg < CHUNK_SIZE, "" );
- _A[reg>>_LogWordBits] |= (1<<(reg&(_WordBits-1)));
+ assert(reg < CHUNK_SIZE, "sanity");
+ assert(valid_watermarks(), "pre-condition");
+ int index = reg>>_LogWordBits;
+ if (index > _hwm) _hwm = index;
+ if (index < _lwm) _lwm = index;
+ _A[index] |= (1<<(reg&(_WordBits-1)));
+ assert(valid_watermarks(), "post-condition");
}
// Remove register from mask
@@ -283,23 +305,38 @@ public:
// OR 'rm' into 'this'
void OR( const RegMask &rm ) {
-# define BODY(I) this->_A[I] |= rm._A[I];
- FORALL_BODY
-# undef BODY
+ assert(valid_watermarks() && rm.valid_watermarks(), "sanity");
+ // OR widens the live range
+ if (_lwm > rm._lwm) _lwm = rm._lwm;
+ if (_hwm < rm._hwm) _hwm = rm._hwm;
+ for (int i = _lwm; i <= _hwm; i++) {
+ _A[i] |= rm._A[i];
+ }
+ assert(valid_watermarks(), "sanity");
}
// AND 'rm' into 'this'
void AND( const RegMask &rm ) {
-# define BODY(I) this->_A[I] &= rm._A[I];
- FORALL_BODY
-# undef BODY
+ assert(valid_watermarks() && rm.valid_watermarks(), "sanity");
+ // Do not evaluate words outside the current watermark range, as they are
+ // already zero and an &= would not change that
+ for (int i = _lwm; i <= _hwm; i++) {
+ _A[i] &= rm._A[i];
+ }
+ // Narrow the watermarks if &rm spans a narrower range.
+ // Update after to ensure non-overlapping words are zeroed out.
+ if (_lwm < rm._lwm) _lwm = rm._lwm;
+ if (_hwm > rm._hwm) _hwm = rm._hwm;
}
// Subtract 'rm' from 'this'
void SUBTRACT( const RegMask &rm ) {
-# define BODY(I) _A[I] &= ~rm._A[I];
- FORALL_BODY
-# undef BODY
+ assert(valid_watermarks() && rm.valid_watermarks(), "sanity");
+ int hwm = MIN2(_hwm, rm._hwm);
+ int lwm = MAX2(_lwm, rm._lwm);
+ for (int i = lwm; i <= hwm; i++) {
+ _A[i] &= ~rm._A[i];
+ }
}
// Compute size of register mask: number of bits
1
https://gitee.com/leofang94/openjdk-1.8.0.git
git@gitee.com:leofang94/openjdk-1.8.0.git
leofang94
openjdk-1.8.0
openjdk-1.8.0
master

搜索帮助