Projects
home:dingli:branches:openEuler:24.09-openjdk
openjdk-1.8.0
_service:tar_scm:8234003.patch
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:8234003.patch of Package openjdk-1.8.0
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;
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2