1187 lines
43 KiB
Diff
1187 lines
43 KiB
Diff
diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp
|
|
index ec318c515..b3b9eb39a 100644
|
|
--- a/hotspot/src/share/vm/opto/chaitin.cpp
|
|
+++ b/hotspot/src/share/vm/opto/chaitin.cpp
|
|
@@ -1038,11 +1038,13 @@ void PhaseChaitin::set_was_low() {
|
|
// low-degree neighbors when determining if this guy colors.
|
|
int briggs_degree = 0;
|
|
IndexSet *s = _ifg->neighbors(i);
|
|
- IndexSetIterator elements(s);
|
|
- uint lidx;
|
|
- while((lidx = elements.next()) != 0) {
|
|
- if( !lrgs(lidx).lo_degree() )
|
|
- briggs_degree += MAX2(size,lrgs(lidx).num_regs());
|
|
+ if (!s->is_empty()) {
|
|
+ IndexSetIterator elements(s);
|
|
+ uint lidx;
|
|
+ while((lidx = elements.next()) != 0) {
|
|
+ if( !lrgs(lidx).lo_degree() )
|
|
+ briggs_degree += MAX2(size,lrgs(lidx).num_regs());
|
|
+ }
|
|
}
|
|
if( briggs_degree < lrgs(i).degrees_of_freedom() )
|
|
lrgs(i)._was_lo = 1; // Low degree via the briggs assertion
|
|
@@ -1118,18 +1120,20 @@ void PhaseChaitin::Pre_Simplify( ) {
|
|
// list. Note that 'degree' can only fall and 'numregs' is
|
|
// unchanged by this action. Thus the two are equal at most once,
|
|
// so LRGs hit the lo-degree worklists at most once.
|
|
- IndexSetIterator elements(adj);
|
|
- uint neighbor;
|
|
- while ((neighbor = elements.next()) != 0) {
|
|
- LRG *n = &lrgs(neighbor);
|
|
- assert( _ifg->effective_degree(neighbor) == n->degree(), "" );
|
|
-
|
|
- // Check for just becoming of-low-degree
|
|
- if( n->just_lo_degree() && !n->_has_copy ) {
|
|
- assert(!(*_ifg->_yanked)[neighbor],"Cannot move to lo degree twice");
|
|
- // Put on lo-degree list
|
|
- n->_next = lo_no_copy;
|
|
- lo_no_copy = neighbor;
|
|
+ if (!adj->is_empty()) {
|
|
+ IndexSetIterator elements(adj);
|
|
+ uint neighbor;
|
|
+ while ((neighbor = elements.next()) != 0) {
|
|
+ LRG *n = &lrgs(neighbor);
|
|
+ assert(_ifg->effective_degree(neighbor) == n->degree(), "");
|
|
+
|
|
+ // Check for just becoming of-low-degree
|
|
+ if (n->just_lo_degree() && !n->_has_copy) {
|
|
+ assert(!(*_ifg->_yanked)[neighbor], "Cannot move to lo degree twice");
|
|
+ // Put on lo-degree list
|
|
+ n->_next = lo_no_copy;
|
|
+ lo_no_copy = neighbor;
|
|
+ }
|
|
}
|
|
}
|
|
} // End of while lo-degree no_copy worklist not empty
|
|
@@ -1159,7 +1163,7 @@ void PhaseChaitin::Simplify( ) {
|
|
lrgs(lo)._next = _simplified;
|
|
_simplified = lo;
|
|
// If this guy is "at risk" then mark his current neighbors
|
|
- if( lrgs(lo)._at_risk ) {
|
|
+ if (lrgs(lo)._at_risk && !_ifg->neighbors(lo)->is_empty()) {
|
|
IndexSetIterator elements(_ifg->neighbors(lo));
|
|
uint datum;
|
|
while ((datum = elements.next()) != 0) {
|
|
@@ -1168,7 +1172,10 @@ void PhaseChaitin::Simplify( ) {
|
|
}
|
|
|
|
// Yank this guy from the IFG.
|
|
- IndexSet *adj = _ifg->remove_node( lo );
|
|
+ IndexSet *adj = _ifg->remove_node(lo);
|
|
+ if (adj->is_empty()) {
|
|
+ continue;
|
|
+ }
|
|
|
|
// If any neighbors' degrees fall below their number of
|
|
// allowed registers, then put that neighbor on the low degree
|
|
@@ -1187,13 +1194,16 @@ void PhaseChaitin::Simplify( ) {
|
|
|
|
// Check for just becoming of-low-degree just counting registers.
|
|
// _must_spill live ranges are already on the low degree list.
|
|
- if( n->just_lo_degree() && !n->_must_spill ) {
|
|
- assert(!(*_ifg->_yanked)[neighbor],"Cannot move to lo degree twice");
|
|
+ if (n->just_lo_degree() && !n->_must_spill) {
|
|
+ assert(!(*_ifg->_yanked)[neighbor], "Cannot move to lo degree twice");
|
|
// Pull from hi-degree list
|
|
uint prev = n->_prev;
|
|
uint next = n->_next;
|
|
- if( prev ) lrgs(prev)._next = next;
|
|
- else _hi_degree = next;
|
|
+ if (prev) {
|
|
+ lrgs(prev)._next = next;
|
|
+ } else {
|
|
+ _hi_degree = next;
|
|
+ }
|
|
lrgs(next)._prev = prev;
|
|
n->_next = _lo_degree;
|
|
_lo_degree = neighbor;
|
|
@@ -1304,7 +1314,7 @@ OptoReg::Name PhaseChaitin::bias_color( LRG &lrg, int chunk ) {
|
|
|
|
// Check for "at_risk" LRG's
|
|
uint risk_lrg = _lrg_map.find(lrg._risk_bias);
|
|
- if( risk_lrg != 0 ) {
|
|
+ if( risk_lrg != 0 && !_ifg->neighbors(risk_lrg)->is_empty()) {
|
|
// Walk the colored neighbors of the "at_risk" candidate
|
|
// Choose a color which is both legal and already taken by a neighbor
|
|
// of the "at_risk" candidate in order to improve the chances of the
|
|
@@ -1320,9 +1330,9 @@ OptoReg::Name PhaseChaitin::bias_color( LRG &lrg, int chunk ) {
|
|
}
|
|
|
|
uint copy_lrg = _lrg_map.find(lrg._copy_bias);
|
|
- if( copy_lrg != 0 ) {
|
|
+ if (copy_lrg != 0) {
|
|
// If he has a color,
|
|
- if( !(*(_ifg->_yanked))[copy_lrg] ) {
|
|
+ if (!(*(_ifg->_yanked))[copy_lrg]) {
|
|
OptoReg::Name reg = lrgs(copy_lrg).reg();
|
|
// And it is legal for you,
|
|
if (is_legal_reg(lrg, reg, chunk))
|
|
@@ -1420,41 +1430,43 @@ uint PhaseChaitin::Select( ) {
|
|
|
|
// Remove neighbor colors
|
|
IndexSet *s = _ifg->neighbors(lidx);
|
|
-
|
|
debug_only(RegMask orig_mask = lrg->mask();)
|
|
- IndexSetIterator elements(s);
|
|
- uint neighbor;
|
|
- while ((neighbor = elements.next()) != 0) {
|
|
- // Note that neighbor might be a spill_reg. In this case, exclusion
|
|
- // of its color will be a no-op, since the spill_reg chunk is in outer
|
|
- // space. Also, if neighbor is in a different chunk, this exclusion
|
|
- // will be a no-op. (Later on, if lrg runs out of possible colors in
|
|
- // its chunk, a new chunk of color may be tried, in which case
|
|
- // examination of neighbors is started again, at retry_next_chunk.)
|
|
- LRG &nlrg = lrgs(neighbor);
|
|
- OptoReg::Name nreg = nlrg.reg();
|
|
- // Only subtract masks in the same chunk
|
|
- if( nreg >= chunk && nreg < chunk + RegMask::CHUNK_SIZE ) {
|
|
+
|
|
+ if (!s->is_empty()) {
|
|
+ IndexSetIterator elements(s);
|
|
+ uint neighbor;
|
|
+ while ((neighbor = elements.next()) != 0) {
|
|
+ // Note that neighbor might be a spill_reg. In this case, exclusion
|
|
+ // of its color will be a no-op, since the spill_reg chunk is in outer
|
|
+ // space. Also, if neighbor is in a different chunk, this exclusion
|
|
+ // will be a no-op. (Later on, if lrg runs out of possible colors in
|
|
+ // its chunk, a new chunk of color may be tried, in which case
|
|
+ // examination of neighbors is started again, at retry_next_chunk.)
|
|
+ LRG &nlrg = lrgs(neighbor);
|
|
+ OptoReg::Name nreg = nlrg.reg();
|
|
+ // Only subtract masks in the same chunk
|
|
+ if( nreg >= chunk && nreg < chunk + RegMask::CHUNK_SIZE ) {
|
|
#ifndef PRODUCT
|
|
- uint size = lrg->mask().Size();
|
|
- RegMask rm = lrg->mask();
|
|
+ uint size = lrg->mask().Size();
|
|
+ RegMask rm = lrg->mask();
|
|
#endif
|
|
- lrg->SUBTRACT(nlrg.mask());
|
|
+ lrg->SUBTRACT(nlrg.mask());
|
|
#ifndef PRODUCT
|
|
- if (trace_spilling() && lrg->mask().Size() != size) {
|
|
- ttyLocker ttyl;
|
|
- tty->print("L%d ", lidx);
|
|
- rm.dump();
|
|
- tty->print(" intersected L%d ", neighbor);
|
|
- nlrg.mask().dump();
|
|
- tty->print(" removed ");
|
|
- rm.SUBTRACT(lrg->mask());
|
|
- rm.dump();
|
|
- tty->print(" leaving ");
|
|
- lrg->mask().dump();
|
|
- tty->cr();
|
|
- }
|
|
+ if (trace_spilling() && lrg->mask().Size() != size) {
|
|
+ ttyLocker ttyl;
|
|
+ tty->print("L%d ", lidx);
|
|
+ rm.dump();
|
|
+ tty->print(" intersected L%d ", neighbor);
|
|
+ nlrg.mask().dump();
|
|
+ tty->print(" removed ");
|
|
+ rm.SUBTRACT(lrg->mask());
|
|
+ rm.dump();
|
|
+ tty->print(" leaving ");
|
|
+ lrg->mask().dump();
|
|
+ tty->cr();
|
|
+ }
|
|
#endif
|
|
+ }
|
|
}
|
|
}
|
|
//assert(is_allstack == lrg->mask().is_AllStack(), "nbrs must not change AllStackedness");
|
|
@@ -1827,7 +1839,7 @@ bool PhaseChaitin::stretch_base_pointer_live_ranges(ResourceArea *a) {
|
|
|
|
// Found a safepoint?
|
|
JVMState *jvms = n->jvms();
|
|
- if( jvms ) {
|
|
+ if (jvms && !liveout.is_empty()) {
|
|
// Now scan for a live derived pointer
|
|
IndexSetIterator elements(&liveout);
|
|
uint neighbor;
|
|
@@ -1983,12 +1995,14 @@ void PhaseChaitin::dump(const Block *b) const {
|
|
// Print live-out info at end of block
|
|
if( _live ) {
|
|
tty->print("Liveout: ");
|
|
- IndexSet *live = _live->live(b);
|
|
- IndexSetIterator elements(live);
|
|
tty->print("{");
|
|
- uint i;
|
|
- while ((i = elements.next()) != 0) {
|
|
- tty->print("L%d ", _lrg_map.find_const(i));
|
|
+ IndexSet *live = _live->live(b);
|
|
+ if (!live->is_empty()) {
|
|
+ IndexSetIterator elements(live);
|
|
+ uint i;
|
|
+ while ((i = elements.next()) != 0) {
|
|
+ tty->print("L%d ", _lrg_map.find_const(i));
|
|
+ }
|
|
}
|
|
tty->print_cr("}");
|
|
}
|
|
diff --git a/hotspot/src/share/vm/opto/coalesce.cpp b/hotspot/src/share/vm/opto/coalesce.cpp
|
|
index c675445bf..988a45ec2 100644
|
|
--- a/hotspot/src/share/vm/opto/coalesce.cpp
|
|
+++ b/hotspot/src/share/vm/opto/coalesce.cpp
|
|
@@ -602,29 +602,40 @@ void PhaseConservativeCoalesce::update_ifg(uint lr1, uint lr2, IndexSet *n_lr1,
|
|
// Some original neighbors of lr1 might have gone away
|
|
// because the constrained register mask prevented them.
|
|
// Remove lr1 from such neighbors.
|
|
- IndexSetIterator one(n_lr1);
|
|
- uint neighbor;
|
|
+ uint neighbor = 0;
|
|
LRG &lrg1 = lrgs(lr1);
|
|
- while ((neighbor = one.next()) != 0)
|
|
- if( !_ulr.member(neighbor) )
|
|
- if( _phc._ifg->neighbors(neighbor)->remove(lr1) )
|
|
- lrgs(neighbor).inc_degree( -lrg1.compute_degree(lrgs(neighbor)) );
|
|
+
|
|
+ if (!n_lr1->is_empty()) {
|
|
+ IndexSetIterator one(n_lr1);
|
|
+ while ((neighbor = one.next()) != 0)
|
|
+ if (!_ulr.member(neighbor))
|
|
+ if (_phc._ifg->neighbors(neighbor)->remove(lr1))
|
|
+ lrgs(neighbor).inc_degree(-lrg1.compute_degree(lrgs(neighbor)));
|
|
+ }
|
|
|
|
|
|
// lr2 is now called (coalesced into) lr1.
|
|
// Remove lr2 from the IFG.
|
|
- IndexSetIterator two(n_lr2);
|
|
LRG &lrg2 = lrgs(lr2);
|
|
- while ((neighbor = two.next()) != 0)
|
|
- if( _phc._ifg->neighbors(neighbor)->remove(lr2) )
|
|
- lrgs(neighbor).inc_degree( -lrg2.compute_degree(lrgs(neighbor)) );
|
|
+ if (!n_lr2->is_empty()) {
|
|
+ IndexSetIterator two(n_lr2);
|
|
+ while ((neighbor = two.next()) != 0) {
|
|
+ if (_phc._ifg->neighbors(neighbor)->remove(lr2)) {
|
|
+ lrgs(neighbor).inc_degree(-lrg2.compute_degree(lrgs(neighbor)));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
|
|
// Some neighbors of intermediate copies now interfere with the
|
|
// combined live range.
|
|
- IndexSetIterator three(&_ulr);
|
|
- while ((neighbor = three.next()) != 0)
|
|
- if( _phc._ifg->neighbors(neighbor)->insert(lr1) )
|
|
- lrgs(neighbor).inc_degree( lrg1.compute_degree(lrgs(neighbor)) );
|
|
+ if (!_ulr.is_empty()) {
|
|
+ IndexSetIterator three(&_ulr);
|
|
+ while ((neighbor = three.next()) != 0) {
|
|
+ if (_phc._ifg->neighbors(neighbor)->insert(lr1)) {
|
|
+ lrgs(neighbor).inc_degree(lrg1.compute_degree(lrgs(neighbor)));
|
|
+ }
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
static void record_bias( const PhaseIFG *ifg, int lr1, int lr2 ) {
|
|
diff --git a/hotspot/src/share/vm/opto/ifg.cpp b/hotspot/src/share/vm/opto/ifg.cpp
|
|
index 3b33aa7a9..39c0e0155 100644
|
|
--- a/hotspot/src/share/vm/opto/ifg.cpp
|
|
+++ b/hotspot/src/share/vm/opto/ifg.cpp
|
|
@@ -94,11 +94,13 @@ void PhaseIFG::SquareUp() {
|
|
assert( !_is_square, "only on triangular" );
|
|
|
|
// Simple transpose
|
|
- for( uint i = 0; i < _maxlrg; i++ ) {
|
|
- IndexSetIterator elements(&_adjs[i]);
|
|
- uint datum;
|
|
- while ((datum = elements.next()) != 0) {
|
|
- _adjs[datum].insert( i );
|
|
+ for (uint i = 0; i < _maxlrg; i++) {
|
|
+ if (!_adjs[i].is_empty()) {
|
|
+ IndexSetIterator elements(&_adjs[i]);
|
|
+ uint datum;
|
|
+ while ((datum = elements.next()) != 0) {
|
|
+ _adjs[datum].insert(i);
|
|
+ }
|
|
}
|
|
}
|
|
_is_square = true;
|
|
@@ -122,44 +124,52 @@ int PhaseIFG::test_edge_sq( uint a, uint b ) const {
|
|
}
|
|
|
|
// Union edges of B into A
|
|
-void PhaseIFG::Union( uint a, uint b ) {
|
|
+void PhaseIFG::Union(uint a, uint b) {
|
|
assert( _is_square, "only on square" );
|
|
IndexSet *A = &_adjs[a];
|
|
- IndexSetIterator b_elements(&_adjs[b]);
|
|
- uint datum;
|
|
- while ((datum = b_elements.next()) != 0) {
|
|
- if(A->insert(datum)) {
|
|
- _adjs[datum].insert(a);
|
|
- lrgs(a).invalid_degree();
|
|
- lrgs(datum).invalid_degree();
|
|
+ if (!_adjs[b].is_empty()) {
|
|
+ IndexSetIterator b_elements(&_adjs[b]);
|
|
+ uint datum;
|
|
+ while ((datum = b_elements.next()) != 0) {
|
|
+ if (A->insert(datum)) {
|
|
+ _adjs[datum].insert(a);
|
|
+ lrgs(a).invalid_degree();
|
|
+ lrgs(datum).invalid_degree();
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
|
|
// Yank a Node and all connected edges from the IFG. Return a
|
|
// list of neighbors (edges) yanked.
|
|
-IndexSet *PhaseIFG::remove_node( uint a ) {
|
|
+IndexSet *PhaseIFG::remove_node(uint a) {
|
|
assert( _is_square, "only on square" );
|
|
assert( !_yanked->test(a), "" );
|
|
_yanked->set(a);
|
|
|
|
// I remove the LRG from all neighbors.
|
|
- IndexSetIterator elements(&_adjs[a]);
|
|
LRG &lrg_a = lrgs(a);
|
|
- uint datum;
|
|
- while ((datum = elements.next()) != 0) {
|
|
- _adjs[datum].remove(a);
|
|
- lrgs(datum).inc_degree( -lrg_a.compute_degree(lrgs(datum)) );
|
|
+ if (!_adjs[a].is_empty()) {
|
|
+ IndexSetIterator elements(&_adjs[a]);
|
|
+ uint datum;
|
|
+ while ((datum = elements.next()) != 0) {
|
|
+ _adjs[datum].remove(a);
|
|
+ lrgs(datum).inc_degree(-lrg_a.compute_degree(lrgs(datum)));
|
|
+ }
|
|
}
|
|
return neighbors(a);
|
|
}
|
|
|
|
// Re-insert a yanked Node.
|
|
-void PhaseIFG::re_insert( uint a ) {
|
|
+void PhaseIFG::re_insert(uint a) {
|
|
assert( _is_square, "only on square" );
|
|
assert( _yanked->test(a), "" );
|
|
(*_yanked) >>= a;
|
|
|
|
+ if (_adjs[a].is_empty()) {
|
|
+ return;
|
|
+ }
|
|
+
|
|
IndexSetIterator elements(&_adjs[a]);
|
|
uint datum;
|
|
while ((datum = elements.next()) != 0) {
|
|
@@ -173,7 +183,7 @@ void PhaseIFG::re_insert( uint a ) {
|
|
// mis-aligned (or for Fat-Projections, not-adjacent) then we have to
|
|
// MULTIPLY the sizes. Inspect Brigg's thesis on register pairs to see why
|
|
// this is so.
|
|
-int LRG::compute_degree( LRG &l ) const {
|
|
+int LRG::compute_degree(LRG &l) const {
|
|
int tmp;
|
|
int num_regs = _num_regs;
|
|
int nregs = l.num_regs();
|
|
@@ -188,14 +198,18 @@ int LRG::compute_degree( LRG &l ) const {
|
|
// mis-aligned (or for Fat-Projections, not-adjacent) then we have to
|
|
// MULTIPLY the sizes. Inspect Brigg's thesis on register pairs to see why
|
|
// this is so.
|
|
-int PhaseIFG::effective_degree( uint lidx ) const {
|
|
+int PhaseIFG::effective_degree(uint lidx) const {
|
|
+ IndexSet *s = neighbors(lidx);
|
|
+ if (s->is_empty()) {
|
|
+ return 0;
|
|
+ }
|
|
+
|
|
int eff = 0;
|
|
int num_regs = lrgs(lidx).num_regs();
|
|
int fat_proj = lrgs(lidx)._fat_proj;
|
|
- IndexSet *s = neighbors(lidx);
|
|
IndexSetIterator elements(s);
|
|
uint nidx;
|
|
- while((nidx = elements.next()) != 0) {
|
|
+ while ((nidx = elements.next()) != 0) {
|
|
LRG &lrgn = lrgs(nidx);
|
|
int nregs = lrgn.num_regs();
|
|
eff += (fat_proj || lrgn._fat_proj) // either is a fat-proj?
|
|
@@ -210,14 +224,16 @@ int PhaseIFG::effective_degree( uint lidx ) const {
|
|
void PhaseIFG::dump() const {
|
|
tty->print_cr("-- Interference Graph --%s--",
|
|
_is_square ? "square" : "triangular" );
|
|
- if( _is_square ) {
|
|
- for( uint i = 0; i < _maxlrg; i++ ) {
|
|
+ if (_is_square) {
|
|
+ for (uint i = 0; i < _maxlrg; i++) {
|
|
tty->print( (*_yanked)[i] ? "XX " : " ");
|
|
tty->print("L%d: { ",i);
|
|
- IndexSetIterator elements(&_adjs[i]);
|
|
- uint datum;
|
|
- while ((datum = elements.next()) != 0) {
|
|
- tty->print("L%d ", datum);
|
|
+ if (!_adjs[i].is_empty()) {
|
|
+ IndexSetIterator elements(&_adjs[i]);
|
|
+ uint datum;
|
|
+ while ((datum = elements.next()) != 0) {
|
|
+ tty->print("L%d ", datum);
|
|
+ }
|
|
}
|
|
tty->print_cr("}");
|
|
|
|
@@ -235,10 +251,12 @@ void PhaseIFG::dump() const {
|
|
tty->print("L%d ",j - 1);
|
|
}
|
|
tty->print("| ");
|
|
- IndexSetIterator elements(&_adjs[i]);
|
|
- uint datum;
|
|
- while ((datum = elements.next()) != 0) {
|
|
- tty->print("L%d ", datum);
|
|
+ if (!_adjs[i].is_empty()) {
|
|
+ IndexSetIterator elements(&_adjs[i]);
|
|
+ uint datum;
|
|
+ while ((datum = elements.next()) != 0) {
|
|
+ tty->print("L%d ", datum);
|
|
+ }
|
|
}
|
|
tty->print("}\n");
|
|
}
|
|
@@ -265,16 +283,18 @@ void PhaseIFG::verify( const PhaseChaitin *pc ) const {
|
|
for( uint i = 0; i < _maxlrg; i++ ) {
|
|
assert(!((*_yanked)[i]) || !neighbor_cnt(i), "Is removed completely" );
|
|
IndexSet *set = &_adjs[i];
|
|
- IndexSetIterator elements(set);
|
|
- uint idx;
|
|
- uint last = 0;
|
|
- while ((idx = elements.next()) != 0) {
|
|
- assert(idx != i, "Must have empty diagonal");
|
|
- assert(pc->_lrg_map.find_const(idx) == idx, "Must not need Find");
|
|
- assert(_adjs[idx].member(i), "IFG not square");
|
|
- assert(!(*_yanked)[idx], "No yanked neighbors");
|
|
- assert(last < idx, "not sorted increasing");
|
|
- last = idx;
|
|
+ if (!set->is_empty()) {
|
|
+ IndexSetIterator elements(set);
|
|
+ uint idx;
|
|
+ uint last = 0;
|
|
+ while ((idx = elements.next()) != 0) {
|
|
+ assert(idx != i, "Must have empty diagonal");
|
|
+ assert(pc->_lrg_map.find_const(idx) == idx, "Must not need Find");
|
|
+ assert(_adjs[idx].member(i), "IFG not square");
|
|
+ assert(!(*_yanked)[idx], "No yanked neighbors");
|
|
+ assert(last < idx, "not sorted increasing");
|
|
+ last = idx;
|
|
+ }
|
|
}
|
|
assert(!lrgs(i)._degree_valid || effective_degree(i) == lrgs(i).degree(), "degree is valid but wrong");
|
|
}
|
|
@@ -284,17 +304,21 @@ void PhaseIFG::verify( const PhaseChaitin *pc ) const {
|
|
// Interfere this register with everything currently live. Use the RegMasks
|
|
// to trim the set of possible interferences. Return a count of register-only
|
|
// interferences as an estimate of register pressure.
|
|
-void PhaseChaitin::interfere_with_live( uint r, IndexSet *liveout ) {
|
|
- uint retval = 0;
|
|
- // Interfere with everything live.
|
|
- const RegMask &rm = lrgs(r).mask();
|
|
- // Check for interference by checking overlap of regmasks.
|
|
- // Only interfere if acceptable register masks overlap.
|
|
- IndexSetIterator elements(liveout);
|
|
- uint l;
|
|
- while( (l = elements.next()) != 0 )
|
|
- if( rm.overlap( lrgs(l).mask() ) )
|
|
- _ifg->add_edge( r, l );
|
|
+void PhaseChaitin::interfere_with_live(uint r, IndexSet *liveout) {
|
|
+ if (!liveout->is_empty()) {
|
|
+ uint retval = 0;
|
|
+ // Interfere with everything live.
|
|
+ const RegMask &rm = lrgs(r).mask();
|
|
+ // Check for interference by checking overlap of regmasks.
|
|
+ // Only interfere if acceptable register masks overlap.
|
|
+ IndexSetIterator elements(liveout);
|
|
+ uint l;
|
|
+ while ((l = elements.next()) != 0) {
|
|
+ if (rm.overlap(lrgs(l).mask())) {
|
|
+ _ifg->add_edge(r, l);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
// Actually build the interference graph. Uses virtual registers only, no
|
|
@@ -390,6 +414,9 @@ void PhaseChaitin::build_ifg_virtual( ) {
|
|
}
|
|
|
|
uint PhaseChaitin::count_int_pressure( IndexSet *liveout ) {
|
|
+ if (liveout->is_empty()) {
|
|
+ return 0;
|
|
+ }
|
|
IndexSetIterator elements(liveout);
|
|
uint lidx;
|
|
uint cnt = 0;
|
|
@@ -405,6 +432,9 @@ uint PhaseChaitin::count_int_pressure( IndexSet *liveout ) {
|
|
}
|
|
|
|
uint PhaseChaitin::count_float_pressure( IndexSet *liveout ) {
|
|
+ if (liveout->is_empty()) {
|
|
+ return 0;
|
|
+ }
|
|
IndexSetIterator elements(liveout);
|
|
uint lidx;
|
|
uint cnt = 0;
|
|
@@ -489,23 +519,25 @@ uint PhaseChaitin::build_ifg_physical( ResourceArea *a ) {
|
|
int inst_count = last_inst - first_inst;
|
|
double cost = (inst_count <= 0) ? 0.0 : block->_freq * double(inst_count);
|
|
assert(!(cost < 0.0), "negative spill cost" );
|
|
- IndexSetIterator elements(&liveout);
|
|
- uint lidx;
|
|
- while ((lidx = elements.next()) != 0) {
|
|
- LRG &lrg = lrgs(lidx);
|
|
- lrg._area += cost;
|
|
- // Compute initial register pressure
|
|
- if (lrg.mask().is_UP() && lrg.mask_size()) {
|
|
- if (lrg._is_float || lrg._is_vector) { // Count float pressure
|
|
- pressure[1] += lrg.reg_pressure();
|
|
- if (pressure[1] > block->_freg_pressure) {
|
|
- block->_freg_pressure = pressure[1];
|
|
- }
|
|
- // Count int pressure, but do not count the SP, flags
|
|
- } else if(lrgs(lidx).mask().overlap(*Matcher::idealreg2regmask[Op_RegI])) {
|
|
- pressure[0] += lrg.reg_pressure();
|
|
- if (pressure[0] > block->_reg_pressure) {
|
|
- block->_reg_pressure = pressure[0];
|
|
+ if (!liveout.is_empty()) {
|
|
+ IndexSetIterator elements(&liveout);
|
|
+ uint lidx;
|
|
+ while ((lidx = elements.next()) != 0) {
|
|
+ LRG &lrg = lrgs(lidx);
|
|
+ lrg._area += cost;
|
|
+ // Compute initial register pressure
|
|
+ if (lrg.mask().is_UP() && lrg.mask_size()) {
|
|
+ if (lrg._is_float || lrg._is_vector) { // Count float pressure
|
|
+ pressure[1] += lrg.reg_pressure();
|
|
+ if (pressure[1] > block->_freg_pressure) {
|
|
+ block->_freg_pressure = pressure[1];
|
|
+ }
|
|
+ // Count int pressure, but do not count the SP, flags
|
|
+ } else if (lrgs(lidx).mask().overlap(*Matcher::idealreg2regmask[Op_RegI])) {
|
|
+ pressure[0] += lrg.reg_pressure();
|
|
+ if (pressure[0] > block->_reg_pressure) {
|
|
+ block->_reg_pressure = pressure[0];
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
diff --git a/hotspot/src/share/vm/opto/indexSet.cpp b/hotspot/src/share/vm/opto/indexSet.cpp
|
|
index 4ba99e727..958901007 100644
|
|
--- a/hotspot/src/share/vm/opto/indexSet.cpp
|
|
+++ b/hotspot/src/share/vm/opto/indexSet.cpp
|
|
@@ -177,6 +177,9 @@ IndexSet::BitBlock *IndexSet::alloc_block() {
|
|
IndexSet::BitBlock *IndexSet::alloc_block_containing(uint element) {
|
|
BitBlock *block = alloc_block();
|
|
uint bi = get_block_index(element);
|
|
+ if (bi >= _current_block_limit) {
|
|
+ _current_block_limit = bi + 1;
|
|
+ }
|
|
_blocks[bi] = block;
|
|
return block;
|
|
}
|
|
@@ -191,7 +194,7 @@ void IndexSet::free_block(uint i) {
|
|
assert(block != &_empty_block, "cannot free the empty block");
|
|
block->set_next((IndexSet::BitBlock*)Compile::current()->indexSet_free_block_list());
|
|
Compile::current()->set_indexSet_free_block_list(block);
|
|
- set_block(i,&_empty_block);
|
|
+ set_block(i, &_empty_block);
|
|
}
|
|
|
|
//------------------------------lrg_union--------------------------------------
|
|
@@ -234,38 +237,42 @@ uint IndexSet::lrg_union(uint lr1, uint lr2,
|
|
// other color. (A variant of the Briggs assertion)
|
|
uint reg_degree = 0;
|
|
|
|
- uint element;
|
|
+ uint element = 0;
|
|
// Load up the combined interference set with the neighbors of one
|
|
- IndexSetIterator elements(one);
|
|
- while ((element = elements.next()) != 0) {
|
|
- LRG &lrg = ifg->lrgs(element);
|
|
- if (mask.overlap(lrg.mask())) {
|
|
- insert(element);
|
|
- if( !lrg.mask().is_AllStack() ) {
|
|
- reg_degree += lrg1.compute_degree(lrg);
|
|
- if( reg_degree >= fail_degree ) return reg_degree;
|
|
- } else {
|
|
- // !!!!! Danger! No update to reg_degree despite having a neighbor.
|
|
- // A variant of the Briggs assertion.
|
|
- // Not needed if I simplify during coalesce, ala George/Appel.
|
|
- assert( lrg.lo_degree(), "" );
|
|
- }
|
|
- }
|
|
- }
|
|
- // Add neighbors of two as well
|
|
- IndexSetIterator elements2(two);
|
|
- while ((element = elements2.next()) != 0) {
|
|
- LRG &lrg = ifg->lrgs(element);
|
|
- if (mask.overlap(lrg.mask())) {
|
|
- if (insert(element)) {
|
|
- if( !lrg.mask().is_AllStack() ) {
|
|
- reg_degree += lrg2.compute_degree(lrg);
|
|
- if( reg_degree >= fail_degree ) return reg_degree;
|
|
+ if (!one->is_empty()) {
|
|
+ IndexSetIterator elements(one);
|
|
+ while ((element = elements.next()) != 0) {
|
|
+ LRG &lrg = ifg->lrgs(element);
|
|
+ if (mask.overlap(lrg.mask())) {
|
|
+ insert(element);
|
|
+ if (!lrg.mask().is_AllStack()) {
|
|
+ reg_degree += lrg1.compute_degree(lrg);
|
|
+ if (reg_degree >= fail_degree) return reg_degree;
|
|
} else {
|
|
// !!!!! Danger! No update to reg_degree despite having a neighbor.
|
|
// A variant of the Briggs assertion.
|
|
// Not needed if I simplify during coalesce, ala George/Appel.
|
|
- assert( lrg.lo_degree(), "" );
|
|
+ assert(lrg.lo_degree(), "");
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ // Add neighbors of two as well
|
|
+ if (!two->is_empty()) {
|
|
+ IndexSetIterator elements2(two);
|
|
+ while ((element = elements2.next()) != 0) {
|
|
+ LRG &lrg = ifg->lrgs(element);
|
|
+ if (mask.overlap(lrg.mask())) {
|
|
+ if (insert(element)) {
|
|
+ if (!lrg.mask().is_AllStack()) {
|
|
+ reg_degree += lrg2.compute_degree(lrg);
|
|
+ if (reg_degree >= fail_degree) return reg_degree;
|
|
+ } else {
|
|
+ // !!!!! Danger! No update to reg_degree despite having a neighbor.
|
|
+ // A variant of the Briggs assertion.
|
|
+ // Not needed if I simplify during coalesce, ala George/Appel.
|
|
+ assert(lrg.lo_degree(), "");
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
@@ -285,6 +292,7 @@ IndexSet::IndexSet (IndexSet *set) {
|
|
_max_elements = set->_max_elements;
|
|
#endif
|
|
_count = set->_count;
|
|
+ _current_block_limit = set->_current_block_limit;
|
|
_max_blocks = set->_max_blocks;
|
|
if (_max_blocks <= preallocated_block_list_size) {
|
|
_blocks = _preallocated_block_list;
|
|
@@ -314,6 +322,7 @@ void IndexSet::initialize(uint max_elements) {
|
|
_max_elements = max_elements;
|
|
#endif
|
|
_count = 0;
|
|
+ _current_block_limit = 0;
|
|
_max_blocks = (max_elements + bits_per_block - 1) / bits_per_block;
|
|
|
|
if (_max_blocks <= preallocated_block_list_size) {
|
|
@@ -338,6 +347,7 @@ void IndexSet::initialize(uint max_elements, Arena *arena) {
|
|
_max_elements = max_elements;
|
|
#endif // ASSERT
|
|
_count = 0;
|
|
+ _current_block_limit = 0;
|
|
_max_blocks = (max_elements + bits_per_block - 1) / bits_per_block;
|
|
|
|
if (_max_blocks <= preallocated_block_list_size) {
|
|
@@ -360,7 +370,8 @@ void IndexSet::swap(IndexSet *set) {
|
|
set->check_watch("swap", _serial_number);
|
|
#endif
|
|
|
|
- for (uint i = 0; i < _max_blocks; i++) {
|
|
+ uint max = MAX2(_current_block_limit, set->_current_block_limit);
|
|
+ for (uint i = 0; i < max; i++) {
|
|
BitBlock *temp = _blocks[i];
|
|
set_block(i, set->_blocks[i]);
|
|
set->set_block(i, temp);
|
|
@@ -368,6 +379,10 @@ void IndexSet::swap(IndexSet *set) {
|
|
uint temp = _count;
|
|
_count = set->_count;
|
|
set->_count = temp;
|
|
+
|
|
+ temp = _current_block_limit;
|
|
+ _current_block_limit = set->_current_block_limit;
|
|
+ set->_current_block_limit = temp;
|
|
}
|
|
|
|
//---------------------------- IndexSet::dump() -----------------------------
|
|
@@ -375,12 +390,13 @@ void IndexSet::swap(IndexSet *set) {
|
|
|
|
#ifndef PRODUCT
|
|
void IndexSet::dump() const {
|
|
- IndexSetIterator elements(this);
|
|
-
|
|
tty->print("{");
|
|
- uint i;
|
|
- while ((i = elements.next()) != 0) {
|
|
- tty->print("L%d ", i);
|
|
+ if (!this->is_empty()) {
|
|
+ IndexSetIterator elements(this);
|
|
+ uint i;
|
|
+ while ((i = elements.next()) != 0) {
|
|
+ tty->print("L%d ", i);
|
|
+ }
|
|
}
|
|
tty->print_cr("}");
|
|
}
|
|
@@ -435,12 +451,14 @@ void IndexSet::verify() const {
|
|
}
|
|
}
|
|
|
|
- IndexSetIterator elements(this);
|
|
- count = 0;
|
|
- while ((i = elements.next()) != 0) {
|
|
- count++;
|
|
- assert(member(i), "returned a non member");
|
|
- assert(count <= _count, "iterator returned wrong number of elements");
|
|
+ if (!this->is_empty()) {
|
|
+ IndexSetIterator elements(this);
|
|
+ count = 0;
|
|
+ while ((i = elements.next()) != 0) {
|
|
+ count++;
|
|
+ assert(member(i), "returned a non member");
|
|
+ assert(count <= _count, "iterator returned wrong number of elements");
|
|
+ }
|
|
}
|
|
}
|
|
#endif
|
|
@@ -449,44 +467,35 @@ void IndexSet::verify() const {
|
|
// Create an iterator for a set. If empty blocks are detected when iterating
|
|
// over the set, these blocks are replaced.
|
|
|
|
-IndexSetIterator::IndexSetIterator(IndexSet *set) {
|
|
+IndexSetIterator::IndexSetIterator(IndexSet *set) :
|
|
+ _current(0),
|
|
+ _value(0),
|
|
+ _next_word(IndexSet::words_per_block),
|
|
+ _next_block(set->is_empty() ? 1 : 0),
|
|
+ _max_blocks(set->is_empty() ? 1 : set->_current_block_limit),
|
|
+ _words(NULL),
|
|
+ _blocks(set->_blocks),
|
|
+ _set(set) {
|
|
#ifdef ASSERT
|
|
if (CollectIndexSetStatistics) {
|
|
set->tally_iteration_statistics();
|
|
}
|
|
set->check_watch("traversed", set->count());
|
|
#endif
|
|
- if (set->is_empty()) {
|
|
- _current = 0;
|
|
- _next_word = IndexSet::words_per_block;
|
|
- _next_block = 1;
|
|
- _max_blocks = 1;
|
|
-
|
|
- // We don't need the following values when we iterate over an empty set.
|
|
- // The commented out code is left here to document that the omission
|
|
- // is intentional.
|
|
- //
|
|
- //_value = 0;
|
|
- //_words = NULL;
|
|
- //_blocks = NULL;
|
|
- //_set = NULL;
|
|
- } else {
|
|
- _current = 0;
|
|
- _value = 0;
|
|
- _next_block = 0;
|
|
- _next_word = IndexSet::words_per_block;
|
|
-
|
|
- _max_blocks = set->_max_blocks;
|
|
- _words = NULL;
|
|
- _blocks = set->_blocks;
|
|
- _set = set;
|
|
- }
|
|
}
|
|
|
|
//---------------------------- IndexSetIterator(const) -----------------------------
|
|
// Iterate over a constant IndexSet.
|
|
|
|
-IndexSetIterator::IndexSetIterator(const IndexSet *set) {
|
|
+IndexSetIterator::IndexSetIterator(const IndexSet *set) :
|
|
+ _current(0),
|
|
+ _value(0),
|
|
+ _next_word(IndexSet::words_per_block),
|
|
+ _next_block(set->is_empty() ? 1 : 0),
|
|
+ _max_blocks(set->is_empty() ? 1 : set->_current_block_limit),
|
|
+ _words(NULL),
|
|
+ _blocks(set->_blocks),
|
|
+ _set(NULL) {
|
|
#ifdef ASSERT
|
|
if (CollectIndexSetStatistics) {
|
|
set->tally_iteration_statistics();
|
|
@@ -494,31 +503,6 @@ IndexSetIterator::IndexSetIterator(const IndexSet *set) {
|
|
// We don't call check_watch from here to avoid bad recursion.
|
|
// set->check_watch("traversed const", set->count());
|
|
#endif
|
|
- if (set->is_empty()) {
|
|
- _current = 0;
|
|
- _next_word = IndexSet::words_per_block;
|
|
- _next_block = 1;
|
|
- _max_blocks = 1;
|
|
-
|
|
- // We don't need the following values when we iterate over an empty set.
|
|
- // The commented out code is left here to document that the omission
|
|
- // is intentional.
|
|
- //
|
|
- //_value = 0;
|
|
- //_words = NULL;
|
|
- //_blocks = NULL;
|
|
- //_set = NULL;
|
|
- } else {
|
|
- _current = 0;
|
|
- _value = 0;
|
|
- _next_block = 0;
|
|
- _next_word = IndexSet::words_per_block;
|
|
-
|
|
- _max_blocks = set->_max_blocks;
|
|
- _words = NULL;
|
|
- _blocks = set->_blocks;
|
|
- _set = NULL;
|
|
- }
|
|
}
|
|
|
|
//---------------------------- List16Iterator::advance_and_next() -----------------------------
|
|
@@ -536,7 +520,7 @@ uint IndexSetIterator::advance_and_next() {
|
|
|
|
_next_word = wi+1;
|
|
|
|
- return next();
|
|
+ return next_value();
|
|
}
|
|
}
|
|
|
|
@@ -555,7 +539,7 @@ uint IndexSetIterator::advance_and_next() {
|
|
_next_block = bi+1;
|
|
_next_word = wi+1;
|
|
|
|
- return next();
|
|
+ return next_value();
|
|
}
|
|
}
|
|
|
|
diff --git a/hotspot/src/share/vm/opto/indexSet.hpp b/hotspot/src/share/vm/opto/indexSet.hpp
|
|
index ef5aed18b..6a15fa02d 100644
|
|
--- a/hotspot/src/share/vm/opto/indexSet.hpp
|
|
+++ b/hotspot/src/share/vm/opto/indexSet.hpp
|
|
@@ -189,14 +189,17 @@ class IndexSet : public ResourceObj {
|
|
// The number of elements in the set
|
|
uint _count;
|
|
|
|
+ // The current upper limit of blocks that has been allocated and might be in use
|
|
+ uint _current_block_limit;
|
|
+
|
|
+ // The number of top level array entries in use
|
|
+ uint _max_blocks;
|
|
+
|
|
// Our top level array of bitvector segments
|
|
BitBlock **_blocks;
|
|
|
|
BitBlock *_preallocated_block_list[preallocated_block_list_size];
|
|
|
|
- // The number of top level array entries in use
|
|
- uint _max_blocks;
|
|
-
|
|
// Our assertions need to know the maximum number allowed in the set
|
|
#ifdef ASSERT
|
|
uint _max_elements;
|
|
@@ -263,12 +266,13 @@ class IndexSet : public ResourceObj {
|
|
check_watch("clear");
|
|
#endif
|
|
_count = 0;
|
|
- for (uint i = 0; i < _max_blocks; i++) {
|
|
+ for (uint i = 0; i < _current_block_limit; i++) {
|
|
BitBlock *block = _blocks[i];
|
|
if (block != &_empty_block) {
|
|
free_block(i);
|
|
}
|
|
}
|
|
+ _current_block_limit = 0;
|
|
}
|
|
|
|
uint count() const { return _count; }
|
|
@@ -419,18 +423,18 @@ class IndexSetIterator VALUE_OBJ_CLASS_SPEC {
|
|
// The index of the next word we will inspect
|
|
uint _next_word;
|
|
|
|
+ // The index of the next block we will inspect
|
|
+ uint _next_block;
|
|
+
|
|
+ // The number of blocks in the set
|
|
+ uint _max_blocks;
|
|
+
|
|
// A pointer to the contents of the current block
|
|
uint32 *_words;
|
|
|
|
- // The index of the next block we will inspect
|
|
- uint _next_block;
|
|
-
|
|
// A pointer to the blocks in our set
|
|
IndexSet::BitBlock **_blocks;
|
|
|
|
- // The number of blocks in the set
|
|
- uint _max_blocks;
|
|
-
|
|
// If the iterator was created from a non-const set, we replace
|
|
// non-canonical empty blocks with the _empty_block pointer. If
|
|
// _set is NULL, we do no replacement.
|
|
@@ -448,20 +452,26 @@ class IndexSetIterator VALUE_OBJ_CLASS_SPEC {
|
|
IndexSetIterator(IndexSet *set);
|
|
IndexSetIterator(const IndexSet *set);
|
|
|
|
+ // Return the next element of the set.
|
|
+ uint next_value() {
|
|
+ uint current = _current;
|
|
+ uint value = _value;
|
|
+ while (mask_bits(current,window_mask) == 0) {
|
|
+ current >>= window_size;
|
|
+ value += window_size;
|
|
+ }
|
|
+
|
|
+ uint advance = _second_bit[mask_bits(current,window_mask)];
|
|
+ _current = current >> advance;
|
|
+ _value = value + advance;
|
|
+ return value + _first_bit[mask_bits(current,window_mask)];
|
|
+ }
|
|
+
|
|
// Return the next element of the set. Return 0 when done.
|
|
uint next() {
|
|
uint current = _current;
|
|
if (current != 0) {
|
|
- uint value = _value;
|
|
- while (mask_bits(current,window_mask) == 0) {
|
|
- current >>= window_size;
|
|
- value += window_size;
|
|
- }
|
|
-
|
|
- uint advance = _second_bit[mask_bits(current,window_mask)];
|
|
- _current = current >> advance;
|
|
- _value = value + advance;
|
|
- return value + _first_bit[mask_bits(current,window_mask)];
|
|
+ return next_value();
|
|
} else {
|
|
return advance_and_next();
|
|
}
|
|
diff --git a/hotspot/src/share/vm/opto/live.cpp b/hotspot/src/share/vm/opto/live.cpp
|
|
index 787f5ab88..53599162e 100644
|
|
--- a/hotspot/src/share/vm/opto/live.cpp
|
|
+++ b/hotspot/src/share/vm/opto/live.cpp
|
|
@@ -69,7 +69,7 @@ void PhaseLive::compute(uint maxlrg) {
|
|
|
|
// Array of delta-set pointers, indexed by block pre_order-1.
|
|
_deltas = NEW_RESOURCE_ARRAY(IndexSet*,_cfg.number_of_blocks());
|
|
- memset( _deltas, 0, sizeof(IndexSet*)* _cfg.number_of_blocks());
|
|
+ memset(_deltas, 0, sizeof(IndexSet*)* _cfg.number_of_blocks());
|
|
|
|
_free_IndexSet = NULL;
|
|
|
|
@@ -93,8 +93,8 @@ void PhaseLive::compute(uint maxlrg) {
|
|
|
|
uint r = _names.at(n->_idx);
|
|
assert(!def_outside->member(r), "Use of external LRG overlaps the same LRG defined in this block");
|
|
- def->insert( r );
|
|
- use->remove( r );
|
|
+ def->insert(r);
|
|
+ use->remove(r);
|
|
uint cnt = n->req();
|
|
for (uint k = 1; k < cnt; k++) {
|
|
Node *nk = n->in(k);
|
|
@@ -134,7 +134,7 @@ void PhaseLive::compute(uint maxlrg) {
|
|
while (_worklist->size()) {
|
|
Block* block = _worklist->pop();
|
|
IndexSet *delta = getset(block);
|
|
- assert( delta->count(), "missing delta set" );
|
|
+ assert(delta->count(), "missing delta set");
|
|
|
|
// Add new-live-in to predecessors live-out sets
|
|
for (uint l = 1; l < block->num_preds(); l++) {
|
|
@@ -173,34 +173,32 @@ void PhaseLive::stats(uint iters) const {
|
|
|
|
// Get an IndexSet for a block. Return existing one, if any. Make a new
|
|
// empty one if a prior one does not exist.
|
|
-IndexSet *PhaseLive::getset( Block *p ) {
|
|
+IndexSet *PhaseLive::getset(Block *p) {
|
|
IndexSet *delta = _deltas[p->_pre_order-1];
|
|
- if( !delta ) // Not on worklist?
|
|
+ if( !delta ) { // Not on worklist?
|
|
// Get a free set; flag as being on worklist
|
|
- delta = _deltas[p->_pre_order-1] = getfreeset();
|
|
+ delta = _deltas[p->_pre_order - 1] = getfreeset();
|
|
+ }
|
|
return delta; // Return set of new live-out items
|
|
}
|
|
|
|
// Pull from free list, or allocate. Internal allocation on the returned set
|
|
// is always from thread local storage.
|
|
-IndexSet *PhaseLive::getfreeset( ) {
|
|
+IndexSet *PhaseLive::getfreeset() {
|
|
IndexSet *f = _free_IndexSet;
|
|
- if( !f ) {
|
|
+ if (!f) {
|
|
f = new IndexSet;
|
|
-// f->set_arena(Thread::current()->resource_area());
|
|
f->initialize(_maxlrg, Thread::current()->resource_area());
|
|
} else {
|
|
// Pull from free list
|
|
_free_IndexSet = f->next();
|
|
- //f->_cnt = 0; // Reset to empty
|
|
-// f->set_arena(Thread::current()->resource_area());
|
|
f->initialize(_maxlrg, Thread::current()->resource_area());
|
|
}
|
|
return f;
|
|
}
|
|
|
|
// Free an IndexSet from a block.
|
|
-void PhaseLive::freeset( const Block *p ) {
|
|
+void PhaseLive::freeset(const Block *p) {
|
|
IndexSet *f = _deltas[p->_pre_order-1];
|
|
f->set_next(_free_IndexSet);
|
|
_free_IndexSet = f; // Drop onto free list
|
|
@@ -209,53 +207,58 @@ void PhaseLive::freeset( const Block *p ) {
|
|
|
|
// Add a live-out value to a given blocks live-out set. If it is new, then
|
|
// also add it to the delta set and stick the block on the worklist.
|
|
-void PhaseLive::add_liveout( Block *p, uint r, VectorSet &first_pass ) {
|
|
+void PhaseLive::add_liveout(Block *p, uint r, VectorSet &first_pass) {
|
|
IndexSet *live = &_live[p->_pre_order-1];
|
|
if( live->insert(r) ) { // If actually inserted...
|
|
// We extended the live-out set. See if the value is generated locally.
|
|
// If it is not, then we must extend the live-in set.
|
|
if( !_defs[p->_pre_order-1].member( r ) ) {
|
|
if( !_deltas[p->_pre_order-1] && // Not on worklist?
|
|
- first_pass.test(p->_pre_order) )
|
|
+ first_pass.test(p->_pre_order)) {
|
|
_worklist->push(p); // Actually go on worklist if already 1st pass
|
|
+ }
|
|
getset(p)->insert(r);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add a vector of live-out values to a given blocks live-out set.
|
|
-void PhaseLive::add_liveout( Block *p, IndexSet *lo, VectorSet &first_pass ) {
|
|
+void PhaseLive::add_liveout(Block *p, IndexSet *lo, VectorSet &first_pass) {
|
|
IndexSet *live = &_live[p->_pre_order-1];
|
|
IndexSet *defs = &_defs[p->_pre_order-1];
|
|
IndexSet *on_worklist = _deltas[p->_pre_order-1];
|
|
IndexSet *delta = on_worklist ? on_worklist : getfreeset();
|
|
|
|
- IndexSetIterator elements(lo);
|
|
- uint r;
|
|
- while ((r = elements.next()) != 0) {
|
|
- if( live->insert(r) && // If actually inserted...
|
|
- !defs->member( r ) ) // and not defined locally
|
|
- delta->insert(r); // Then add to live-in set
|
|
+ if (!lo->is_empty()) {
|
|
+ IndexSetIterator elements(lo);
|
|
+ uint r;
|
|
+ while ((r = elements.next()) != 0) {
|
|
+ if (live->insert(r) && // If actually inserted...
|
|
+ !defs->member(r)) { // and not defined locally
|
|
+ delta->insert(r); // Then add to live-in set
|
|
+ }
|
|
+ }
|
|
}
|
|
|
|
- if( delta->count() ) { // If actually added things
|
|
+ if (delta->count()) { // If actually added things
|
|
_deltas[p->_pre_order-1] = delta; // Flag as on worklist now
|
|
- if( !on_worklist && // Not on worklist?
|
|
- first_pass.test(p->_pre_order) )
|
|
- _worklist->push(p); // Actually go on worklist if already 1st pass
|
|
- } else { // Nothing there; just free it
|
|
+ if (!on_worklist && // Not on worklist?
|
|
+ first_pass.test(p->_pre_order)) {
|
|
+ _worklist->push(p); // Actually go on worklist if already 1st pass
|
|
+ }
|
|
+ } else { // Nothing there; just free it
|
|
delta->set_next(_free_IndexSet);
|
|
- _free_IndexSet = delta; // Drop onto free list
|
|
+ _free_IndexSet = delta; // Drop onto free list
|
|
}
|
|
}
|
|
|
|
#ifndef PRODUCT
|
|
// Dump the live-out set for a block
|
|
-void PhaseLive::dump( const Block *b ) const {
|
|
+void PhaseLive::dump(const Block *b) const {
|
|
tty->print("Block %d: ",b->_pre_order);
|
|
tty->print("LiveOut: "); _live[b->_pre_order-1].dump();
|
|
uint cnt = b->number_of_nodes();
|
|
- for( uint i=0; i<cnt; i++ ) {
|
|
+ for (uint i=0; i < cnt; i++) {
|
|
tty->print("L%d/", _names.at(b->get_node(i)->_idx));
|
|
b->get_node(i)->dump();
|
|
}
|
|
@@ -263,7 +266,7 @@ void PhaseLive::dump( const Block *b ) const {
|
|
}
|
|
|
|
// Verify that base pointers and derived pointers are still sane.
|
|
-void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
|
|
+void PhaseChaitin::verify_base_ptrs(ResourceArea *a) const {
|
|
#ifdef ASSERT
|
|
Unique_Node_List worklist(a);
|
|
for (uint i = 0; i < _cfg.number_of_blocks(); i++) {
|
|
@@ -288,17 +291,18 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
|
|
worklist.clear();
|
|
worklist.push(check);
|
|
uint k = 0;
|
|
- while( k < worklist.size() ) {
|
|
+ while (k < worklist.size()) {
|
|
check = worklist.at(k);
|
|
assert(check,"Bad base or derived pointer");
|
|
// See PhaseChaitin::find_base_for_derived() for all cases.
|
|
int isc = check->is_Copy();
|
|
- if( isc ) {
|
|
+ if (isc) {
|
|
worklist.push(check->in(isc));
|
|
- } else if( check->is_Phi() ) {
|
|
- for (uint m = 1; m < check->req(); m++)
|
|
+ } else if (check->is_Phi()) {
|
|
+ for (uint m = 1; m < check->req(); m++) {
|
|
worklist.push(check->in(m));
|
|
- } else if( check->is_Con() ) {
|
|
+ }
|
|
+ } else if (check->is_Con()) {
|
|
if (is_derived) {
|
|
// Derived is NULL+offset
|
|
assert(!is_derived || check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad derived pointer");
|
|
@@ -312,8 +316,8 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
|
|
check->bottom_type()->is_ptr()->ptr() == TypePtr::Null,"Bad base pointer");
|
|
}
|
|
}
|
|
- } else if( check->bottom_type()->is_ptr()->_offset == 0 ) {
|
|
- if(check->is_Proj() || check->is_Mach() &&
|
|
+ } else if (check->bottom_type()->is_ptr()->_offset == 0) {
|
|
+ if (check->is_Proj() || check->is_Mach() &&
|
|
(check->as_Mach()->ideal_Opcode() == Op_CreateEx ||
|
|
check->as_Mach()->ideal_Opcode() == Op_ThreadLocal ||
|
|
check->as_Mach()->ideal_Opcode() == Op_CMoveP ||
|
|
@@ -347,7 +351,7 @@ void PhaseChaitin::verify_base_ptrs( ResourceArea *a ) const {
|
|
}
|
|
|
|
// Verify that graphs and base pointers are still sane.
|
|
-void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const {
|
|
+void PhaseChaitin::verify(ResourceArea *a, bool verify_ifg) const {
|
|
#ifdef ASSERT
|
|
if( VerifyOpto || VerifyRegisterAllocator ) {
|
|
_cfg.verify();
|
|
diff --git a/hotspot/src/share/vm/opto/reg_split.cpp b/hotspot/src/share/vm/opto/reg_split.cpp
|
|
index a132f1f9f..de0c9fc7f 100644
|
|
--- a/hotspot/src/share/vm/opto/reg_split.cpp
|
|
+++ b/hotspot/src/share/vm/opto/reg_split.cpp
|
|
@@ -1250,10 +1250,12 @@ uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
|
|
// it contains no members which compress to defidx. Finding such an
|
|
// instance may be a case to add liveout adjustment in compress_uf_map().
|
|
// See 5063219.
|
|
- uint member;
|
|
- IndexSetIterator isi(liveout);
|
|
- while ((member = isi.next()) != 0) {
|
|
- assert(defidx != _lrg_map.find_const(member), "Live out member has not been compressed");
|
|
+ if (!liveout->is_empty()) {
|
|
+ uint member;
|
|
+ IndexSetIterator isi(liveout);
|
|
+ while ((member = isi.next()) != 0) {
|
|
+ assert(defidx != _lrg_map.find_const(member), "Live out member has not been compressed");
|
|
+ }
|
|
}
|
|
#endif
|
|
Reachblock[slidx] = NULL;
|