--- old/src/share/vm/opto/coalesce.cpp 2014-11-06 00:05:08.646893827 +0300 +++ new/src/share/vm/opto/coalesce.cpp 2014-11-06 00:05:08.594893826 +0300 @@ -607,6 +607,86 @@ ifg->lrgs(lr2)._copy_bias = lr1; } +//------------------------------lrg_union-------------------------------------- +// Compute the union of all elements of one and two which interfere with +// the RegMask mask. If the degree of the union becomes exceeds +// fail_degree, the union bails out. The destination set is cleared before +// the union is performed. + +uint lrg_union(IndexSet& dst, uint lr1, uint lr2, + const uint fail_degree, + const PhaseIFG *ifg, + const RegMask &mask ) { + IndexSet *one = ifg->neighbors(lr1); + IndexSet *two = ifg->neighbors(lr2); + LRG &lrg1 = ifg->lrgs(lr1); + LRG &lrg2 = ifg->lrgs(lr2); +#ifdef ASSERT +// assert(_max_elements == one->_max_elements, "max element mismatch"); +// check_watch("union destination"); +// one->check_watch("union source"); +// two->check_watch("union source"); +#endif + + // Compute the degree of the combined live-range. The combined + // live-range has the union of the original live-ranges' neighbors set as + // well as the neighbors of all intermediate copies, minus those neighbors + // that can not use the intersected allowed-register-set. + + // Copy the larger set. Insert the smaller set into the larger. + if (two->count() > one->count()) { + IndexSet *temp = one; + one = two; + two = temp; + } + + dst.clear(); + + // Used to compute degree of register-only interferences. Infinite-stack + // neighbors do not alter colorability, as they can always color to some + // other color. (A variant of the Briggs assertion) + uint reg_degree = 0; + + uint element; + // 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())) { + dst.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 (dst.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(), "" ); + } + } + } + } + + return reg_degree; +} + // See if I can coalesce a series of multiple copies together. I need the // final dest copy and the original src copy. They can be the same Node. // Compute the compatible register masks. @@ -690,7 +770,7 @@ } // Union the two interference sets together into '_ulr' - uint reg_degree = _ulr.lrg_union( lr1, lr2, rm_size, _phc._ifg, rm ); + uint reg_degree = lrg_union( _ulr, lr1, lr2, rm_size, _phc._ifg, rm ); if( reg_degree >= rm_size ) { record_bias( _phc._ifg, lr1, lr2 ); @@ -736,11 +816,14 @@ // _ulr.dump(); //} - // Replace n_lr1 with the new combined live range. _ulr will use - // n_lr1's old memory on the next iteration. n_lr2 is cleared to - // send its internal memory to the free list. - _ulr.swap(n_lr1); + // Replace n_lr1 with the new combined live range. + // _ulr should be clean on the next iteration. + n_lr1->set_from(&_ulr); _ulr.clear(); + + // TODO: Do we need to clear n_lr2 here? Previous + // IndexSet implementation freed the underlying blocks, + // but now we only clear the bitmap, is this redundant? n_lr2->clear(); lrgs(lr1).set_degree( _phc._ifg->effective_degree(lr1) );