8256883: C2: Add a RegMask iterator
Reviewed-by: kvn, pliden, eosterlund
This commit is contained in:
parent
f55ae9595e
commit
fa3cfcd0cd
@ -318,13 +318,10 @@ private:
|
||||
|
||||
public:
|
||||
void initialize(ZLoadBarrierStubC2* stub) {
|
||||
// Create mask of live registers
|
||||
RegMask live = stub->live();
|
||||
|
||||
// Record registers that needs to be saved/restored
|
||||
while (live.is_NotEmpty()) {
|
||||
const OptoReg::Name opto_reg = live.find_first_elem();
|
||||
live.Remove(opto_reg);
|
||||
RegMaskIterator rmi(stub->live());
|
||||
while (rmi.has_next()) {
|
||||
const OptoReg::Name opto_reg = rmi.next();
|
||||
if (OptoReg::is_reg(opto_reg)) {
|
||||
const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
|
||||
if (vm_reg->is_Register()) {
|
||||
|
@ -480,12 +480,11 @@ private:
|
||||
int xmm_spill_size = 0;
|
||||
|
||||
// Record registers that needs to be saved/restored
|
||||
while (live.is_NotEmpty()) {
|
||||
const OptoReg::Name opto_reg = live.find_first_elem();
|
||||
RegMaskIterator rmi(live);
|
||||
while (rmi.has_next()) {
|
||||
const OptoReg::Name opto_reg = rmi.next();
|
||||
const VMReg vm_reg = OptoReg::as_VMReg(opto_reg);
|
||||
|
||||
live.Remove(opto_reg);
|
||||
|
||||
if (vm_reg->is_Register()) {
|
||||
if (caller_saved.Member(opto_reg)) {
|
||||
_gp_registers.append(vm_reg->as_Register());
|
||||
|
@ -2870,11 +2870,10 @@ void Scheduling::verify_good_schedule( Block *b, const char *msg ) {
|
||||
int n_op = n->Opcode();
|
||||
if( n_op == Op_MachProj && n->ideal_reg() == MachProjNode::fat_proj ) {
|
||||
// Fat-proj kills a slew of registers
|
||||
RegMask rm = n->out_RegMask();// Make local copy
|
||||
while( rm.is_NotEmpty() ) {
|
||||
OptoReg::Name kill = rm.find_first_elem();
|
||||
rm.Remove(kill);
|
||||
verify_do_def( n, kill, msg );
|
||||
RegMaskIterator rmi(n->out_RegMask());
|
||||
while (rmi.has_next()) {
|
||||
OptoReg::Name kill = rmi.next();
|
||||
verify_do_def(n, kill, msg);
|
||||
}
|
||||
} else if( n_op != Op_Node ) { // Avoid brand new antidependence nodes
|
||||
// Get DEF'd registers the normal way
|
||||
@ -3061,11 +3060,10 @@ void Scheduling::ComputeRegisterAntidependencies(Block *b) {
|
||||
// This can add edges to 'n' and obscure whether or not it was a def,
|
||||
// hence the is_def flag.
|
||||
fat_proj_seen = true;
|
||||
RegMask rm = n->out_RegMask();// Make local copy
|
||||
while( rm.is_NotEmpty() ) {
|
||||
OptoReg::Name kill = rm.find_first_elem();
|
||||
rm.Remove(kill);
|
||||
anti_do_def( b, n, kill, is_def );
|
||||
RegMaskIterator rmi(n->out_RegMask());
|
||||
while (rmi.has_next()) {
|
||||
OptoReg::Name kill = rmi.next();
|
||||
anti_do_def(b, n, kill, is_def);
|
||||
}
|
||||
} else {
|
||||
// Get DEF'd registers the normal way
|
||||
@ -3080,11 +3078,10 @@ void Scheduling::ComputeRegisterAntidependencies(Block *b) {
|
||||
for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
|
||||
Node* use = n->fast_out(i);
|
||||
if (use->is_Proj()) {
|
||||
RegMask rm = use->out_RegMask();// Make local copy
|
||||
while( rm.is_NotEmpty() ) {
|
||||
OptoReg::Name kill = rm.find_first_elem();
|
||||
rm.Remove(kill);
|
||||
anti_do_def( b, n, kill, false );
|
||||
RegMaskIterator rmi(use->out_RegMask());
|
||||
while (rmi.has_next()) {
|
||||
OptoReg::Name kill = rmi.next();
|
||||
anti_do_def(b, n, kill, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -784,15 +784,12 @@ void PhaseChaitin::post_allocate_copy_removal() {
|
||||
}
|
||||
|
||||
// Fat projections kill many registers
|
||||
if( n_ideal_reg == MachProjNode::fat_proj ) {
|
||||
RegMask rm = n->out_RegMask();
|
||||
// wow, what an expensive iterator...
|
||||
nreg = rm.find_first_elem();
|
||||
while( OptoReg::is_valid(nreg)) {
|
||||
rm.Remove(nreg);
|
||||
value.map(nreg,n);
|
||||
regnd.map(nreg,n);
|
||||
nreg = rm.find_first_elem();
|
||||
if (n_ideal_reg == MachProjNode::fat_proj) {
|
||||
RegMaskIterator rmi(n->out_RegMask());
|
||||
while (rmi.has_next()) {
|
||||
nreg = rmi.next();
|
||||
value.map(nreg, n);
|
||||
regnd.map(nreg, n);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -355,24 +355,21 @@ uint RegMask::Size() const {
|
||||
#ifndef PRODUCT
|
||||
void RegMask::dump(outputStream *st) const {
|
||||
st->print("[");
|
||||
RegMask rm = *this; // Structure copy into local temp
|
||||
|
||||
OptoReg::Name start = rm.find_first_elem(); // Get a register
|
||||
if (OptoReg::is_valid(start)) { // Check for empty mask
|
||||
rm.Remove(start); // Yank from mask
|
||||
RegMaskIterator rmi(*this);
|
||||
if (rmi.has_next()) {
|
||||
OptoReg::Name start = rmi.next();
|
||||
|
||||
OptoReg::dump(start, st); // Print register
|
||||
OptoReg::Name last = start;
|
||||
|
||||
// Now I have printed an initial register.
|
||||
// Print adjacent registers as "rX-rZ" instead of "rX,rY,rZ".
|
||||
// Begin looping over the remaining registers.
|
||||
while (1) { //
|
||||
OptoReg::Name reg = rm.find_first_elem(); // Get a register
|
||||
if (!OptoReg::is_valid(reg))
|
||||
break; // Empty mask, end loop
|
||||
rm.Remove(reg); // Yank from mask
|
||||
while (rmi.has_next()) {
|
||||
OptoReg::Name reg = rmi.next(); // Get a register
|
||||
|
||||
if (last+1 == reg) { // See if they are adjacent
|
||||
if (last + 1 == reg) { // See if they are adjacent
|
||||
// Adjacent registers just collect into long runs, no printing.
|
||||
last = reg;
|
||||
} else { // Ending some kind of run
|
||||
@ -398,7 +395,7 @@ void RegMask::dump(outputStream *st) const {
|
||||
st->print("-");
|
||||
OptoReg::dump(last, st);
|
||||
}
|
||||
if (rm.is_AllStack()) st->print("...");
|
||||
if (is_AllStack()) st->print("...");
|
||||
}
|
||||
st->print("]");
|
||||
}
|
||||
|
@ -56,6 +56,8 @@ static unsigned int find_highest_bit(uintptr_t mask) {
|
||||
|
||||
class RegMask {
|
||||
|
||||
friend class RegMaskIterator;
|
||||
|
||||
enum {
|
||||
_WordBits = BitsPerWord,
|
||||
_LogWordBits = LogBitsPerWord,
|
||||
@ -362,6 +364,50 @@ class RegMask {
|
||||
}
|
||||
};
|
||||
|
||||
class RegMaskIterator {
|
||||
private:
|
||||
uintptr_t _current_word;
|
||||
unsigned int _next_index;
|
||||
OptoReg::Name _reg;
|
||||
const RegMask& _rm;
|
||||
public:
|
||||
RegMaskIterator(const RegMask& rm) : _current_word(0), _next_index(rm._lwm), _reg(OptoReg::Special), _rm(rm) {
|
||||
// Calculate the first element
|
||||
next();
|
||||
}
|
||||
|
||||
bool has_next() {
|
||||
return _reg != OptoReg::Bad;
|
||||
}
|
||||
|
||||
// Get the current element and calculate the next
|
||||
OptoReg::Name next() {
|
||||
OptoReg::Name r = _reg;
|
||||
if (_current_word != 0) {
|
||||
unsigned int next_bit = find_lowest_bit(_current_word);
|
||||
assert(next_bit > 0, "must be");
|
||||
assert(((_current_word >> next_bit) & 0x1) == 1, "sanity");
|
||||
_current_word = (_current_word >> next_bit) - 1;
|
||||
_reg = OptoReg::add(_reg, next_bit);
|
||||
return r;
|
||||
}
|
||||
|
||||
while (_next_index <= _rm._hwm) {
|
||||
_current_word = _rm._RM_UP[_next_index++];
|
||||
if (_current_word != 0) {
|
||||
unsigned int next_bit = find_lowest_bit(_current_word);
|
||||
assert(((_current_word >> next_bit) & 0x1) == 1, "sanity");
|
||||
_current_word = (_current_word >> next_bit) - 1;
|
||||
_reg = OptoReg::Name(((_next_index - 1) << RegMask::_LogWordBits) + next_bit);
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
_reg = OptoReg::Name(OptoReg::Bad);
|
||||
return r;
|
||||
}
|
||||
};
|
||||
|
||||
// Do not use this constant directly in client code!
|
||||
#undef RM_SIZE
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user