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