src/share/vm/opto/coalesce.cpp
Print this page
@@ -605,10 +605,90 @@
ifg->lrgs(lr1)._copy_bias = lr2;
if( !ifg->lrgs(lr2)._copy_bias )
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 PhaseConservativeCoalesce::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.
bool PhaseConservativeCoalesce::copy_copy(Node *dst_copy, Node *src_copy, Block *b, uint bindex) {
@@ -688,11 +768,11 @@
b2 = _phc._cfg.get_block_for_node(b2->pred(1));
}
}
// 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 );
return false;
}
@@ -734,16 +814,15 @@
// n_lr2->dump();
// tty->print_cr("resulting set is");
// _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);
- _ulr.clear();
+ // Replace n_lr1 with the new combined live range.
+ // _ulr should be clean on the next iteration.
+ n_lr1->set_from(&_ulr);
n_lr2->clear();
+ _ulr.clear();
lrgs(lr1).set_degree( _phc._ifg->effective_degree(lr1) );
lrgs(lr2).set_degree( 0 );
// Join live ranges. Merge larger into smaller. Union lr2 into lr1 in the