Skip to content

Commit fa3cfcd

Browse files
committedNov 24, 2020
8256883: C2: Add a RegMask iterator
Reviewed-by: kvn, pliden, eosterlund
1 parent f55ae95 commit fa3cfcd

File tree

6 files changed

+78
-45
lines changed

6 files changed

+78
-45
lines changed
 

‎src/hotspot/cpu/aarch64/gc/z/zBarrierSetAssembler_aarch64.cpp

+3-6
Original file line numberDiff line numberDiff line change
@@ -318,13 +318,10 @@ class ZSaveLiveRegisters {
318318

319319
public:
320320
void initialize(ZLoadBarrierStubC2* stub) {
321-
// Create mask of live registers
322-
RegMask live = stub->live();
323-
324321
// Record registers that needs to be saved/restored
325-
while (live.is_NotEmpty()) {
326-
const OptoReg::Name opto_reg = live.find_first_elem();
327-
live.Remove(opto_reg);
322+
RegMaskIterator rmi(stub->live());
323+
while (rmi.has_next()) {
324+
const OptoReg::Name opto_reg = rmi.next();
328325
if (OptoReg::is_reg(opto_reg)) {
329326
const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
330327
if (vm_reg->is_Register()) {

‎src/hotspot/cpu/x86/gc/z/zBarrierSetAssembler_x86.cpp

+3-4
Original file line numberDiff line numberDiff line change
@@ -480,12 +480,11 @@ class ZSaveLiveRegisters {
480480
int xmm_spill_size = 0;
481481

482482
// Record registers that needs to be saved/restored
483-
while (live.is_NotEmpty()) {
484-
const OptoReg::Name opto_reg = live.find_first_elem();
483+
RegMaskIterator rmi(live);
484+
while (rmi.has_next()) {
485+
const OptoReg::Name opto_reg = rmi.next();
485486
const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
486487

487-
live.Remove(opto_reg);
488-
489488
if (vm_reg->is_Register()) {
490489
if (caller_saved.Member(opto_reg)) {
491490
_gp_registers.append(vm_reg->as_Register());

‎src/hotspot/share/opto/output.cpp

+12-15
Original file line numberDiff line numberDiff line change
@@ -2870,11 +2870,10 @@ void Scheduling::verify_good_schedule( Block *b, const char *msg ) {
28702870
int n_op = n->Opcode();
28712871
if( n_op == Op_MachProj && n->ideal_reg() == MachProjNode::fat_proj ) {
28722872
// Fat-proj kills a slew of registers
2873-
RegMask rm = n->out_RegMask();// Make local copy
2874-
while( rm.is_NotEmpty() ) {
2875-
OptoReg::Name kill = rm.find_first_elem();
2876-
rm.Remove(kill);
2877-
verify_do_def( n, kill, msg );
2873+
RegMaskIterator rmi(n->out_RegMask());
2874+
while (rmi.has_next()) {
2875+
OptoReg::Name kill = rmi.next();
2876+
verify_do_def(n, kill, msg);
28782877
}
28792878
} else if( n_op != Op_Node ) { // Avoid brand new antidependence nodes
28802879
// Get DEF'd registers the normal way
@@ -3061,11 +3060,10 @@ void Scheduling::ComputeRegisterAntidependencies(Block *b) {
30613060
// This can add edges to 'n' and obscure whether or not it was a def,
30623061
// hence the is_def flag.
30633062
fat_proj_seen = true;
3064-
RegMask rm = n->out_RegMask();// Make local copy
3065-
while( rm.is_NotEmpty() ) {
3066-
OptoReg::Name kill = rm.find_first_elem();
3067-
rm.Remove(kill);
3068-
anti_do_def( b, n, kill, is_def );
3063+
RegMaskIterator rmi(n->out_RegMask());
3064+
while (rmi.has_next()) {
3065+
OptoReg::Name kill = rmi.next();
3066+
anti_do_def(b, n, kill, is_def);
30693067
}
30703068
} else {
30713069
// Get DEF'd registers the normal way
@@ -3080,11 +3078,10 @@ void Scheduling::ComputeRegisterAntidependencies(Block *b) {
30803078
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
30813079
Node* use = n->fast_out(i);
30823080
if (use->is_Proj()) {
3083-
RegMask rm = use->out_RegMask();// Make local copy
3084-
while( rm.is_NotEmpty() ) {
3085-
OptoReg::Name kill = rm.find_first_elem();
3086-
rm.Remove(kill);
3087-
anti_do_def( b, n, kill, false );
3081+
RegMaskIterator rmi(use->out_RegMask());
3082+
while (rmi.has_next()) {
3083+
OptoReg::Name kill = rmi.next();
3084+
anti_do_def(b, n, kill, false);
30883085
}
30893086
}
30903087
}

‎src/hotspot/share/opto/postaloc.cpp

+6-9
Original file line numberDiff line numberDiff line change
@@ -784,15 +784,12 @@ void PhaseChaitin::post_allocate_copy_removal() {
784784
}
785785

786786
// Fat projections kill many registers
787-
if( n_ideal_reg == MachProjNode::fat_proj ) {
788-
RegMask rm = n->out_RegMask();
789-
// wow, what an expensive iterator...
790-
nreg = rm.find_first_elem();
791-
while( OptoReg::is_valid(nreg)) {
792-
rm.Remove(nreg);
793-
value.map(nreg,n);
794-
regnd.map(nreg,n);
795-
nreg = rm.find_first_elem();
787+
if (n_ideal_reg == MachProjNode::fat_proj) {
788+
RegMaskIterator rmi(n->out_RegMask());
789+
while (rmi.has_next()) {
790+
nreg = rmi.next();
791+
value.map(nreg, n);
792+
regnd.map(nreg, n);
796793
}
797794
}
798795

‎src/hotspot/share/opto/regmask.cpp

+8-11
Original file line numberDiff line numberDiff line change
@@ -355,24 +355,21 @@ uint RegMask::Size() const {
355355
#ifndef PRODUCT
356356
void RegMask::dump(outputStream *st) const {
357357
st->print("[");
358-
RegMask rm = *this; // Structure copy into local temp
359358

360-
OptoReg::Name start = rm.find_first_elem(); // Get a register
361-
if (OptoReg::is_valid(start)) { // Check for empty mask
362-
rm.Remove(start); // Yank from mask
359+
RegMaskIterator rmi(*this);
360+
if (rmi.has_next()) {
361+
OptoReg::Name start = rmi.next();
362+
363363
OptoReg::dump(start, st); // Print register
364364
OptoReg::Name last = start;
365365

366366
// Now I have printed an initial register.
367367
// Print adjacent registers as "rX-rZ" instead of "rX,rY,rZ".
368368
// Begin looping over the remaining registers.
369-
while (1) { //
370-
OptoReg::Name reg = rm.find_first_elem(); // Get a register
371-
if (!OptoReg::is_valid(reg))
372-
break; // Empty mask, end loop
373-
rm.Remove(reg); // Yank from mask
369+
while (rmi.has_next()) {
370+
OptoReg::Name reg = rmi.next(); // Get a register
374371

375-
if (last+1 == reg) { // See if they are adjacent
372+
if (last + 1 == reg) { // See if they are adjacent
376373
// Adjacent registers just collect into long runs, no printing.
377374
last = reg;
378375
} else { // Ending some kind of run
@@ -398,7 +395,7 @@ void RegMask::dump(outputStream *st) const {
398395
st->print("-");
399396
OptoReg::dump(last, st);
400397
}
401-
if (rm.is_AllStack()) st->print("...");
398+
if (is_AllStack()) st->print("...");
402399
}
403400
st->print("]");
404401
}

‎src/hotspot/share/opto/regmask.hpp

+46
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ static unsigned int find_highest_bit(uintptr_t mask) {
5656

5757
class RegMask {
5858

59+
friend class RegMaskIterator;
60+
5961
enum {
6062
_WordBits = BitsPerWord,
6163
_LogWordBits = LogBitsPerWord,
@@ -362,6 +364,50 @@ class RegMask {
362364
}
363365
};
364366

367+
class RegMaskIterator {
368+
private:
369+
uintptr_t _current_word;
370+
unsigned int _next_index;
371+
OptoReg::Name _reg;
372+
const RegMask& _rm;
373+
public:
374+
RegMaskIterator(const RegMask& rm) : _current_word(0), _next_index(rm._lwm), _reg(OptoReg::Special), _rm(rm) {
375+
// Calculate the first element
376+
next();
377+
}
378+
379+
bool has_next() {
380+
return _reg != OptoReg::Bad;
381+
}
382+
383+
// Get the current element and calculate the next
384+
OptoReg::Name next() {
385+
OptoReg::Name r = _reg;
386+
if (_current_word != 0) {
387+
unsigned int next_bit = find_lowest_bit(_current_word);
388+
assert(next_bit > 0, "must be");
389+
assert(((_current_word >> next_bit) & 0x1) == 1, "sanity");
390+
_current_word = (_current_word >> next_bit) - 1;
391+
_reg = OptoReg::add(_reg, next_bit);
392+
return r;
393+
}
394+
395+
while (_next_index <= _rm._hwm) {
396+
_current_word = _rm._RM_UP[_next_index++];
397+
if (_current_word != 0) {
398+
unsigned int next_bit = find_lowest_bit(_current_word);
399+
assert(((_current_word >> next_bit) & 0x1) == 1, "sanity");
400+
_current_word = (_current_word >> next_bit) - 1;
401+
_reg = OptoReg::Name(((_next_index - 1) << RegMask::_LogWordBits) + next_bit);
402+
return r;
403+
}
404+
}
405+
406+
_reg = OptoReg::Name(OptoReg::Bad);
407+
return r;
408+
}
409+
};
410+
365411
// Do not use this constant directly in client code!
366412
#undef RM_SIZE
367413

0 commit comments

Comments
 (0)
Please sign in to comment.