6862863: C2 compiler fails in elide_copy()
authornever
Fri, 14 Aug 2009 15:53:46 -0700
changeset 3678 d797d97552e4
parent 3604 30fbd94d4963
child 3679 8bdd9efb2a5f
6862863: C2 compiler fails in elide_copy() Reviewed-by: kvn
hotspot/src/share/vm/opto/chaitin.hpp
hotspot/src/share/vm/opto/postaloc.cpp
--- a/hotspot/src/share/vm/opto/chaitin.hpp	Thu Aug 06 12:24:41 2009 -0700
+++ b/hotspot/src/share/vm/opto/chaitin.hpp	Fri Aug 14 15:53:46 2009 -0700
@@ -458,6 +458,16 @@
   // Post-Allocation peephole copy removal
   void post_allocate_copy_removal();
   Node *skip_copies( Node *c );
+  // Replace the old node with the current live version of that value
+  // and yank the old value if it's dead.
+  int replace_and_yank_if_dead( Node *old, OptoReg::Name nreg,
+                                Block *current_block, Node_List& value, Node_List& regnd ) {
+    Node* v = regnd[nreg];
+    assert(v->outcnt() != 0, "no dead values");
+    old->replace_by(v);
+    return yank_if_dead(old, current_block, &value, &regnd);
+  }
+
   int yank_if_dead( Node *old, Block *current_block, Node_List *value, Node_List *regnd );
   int elide_copy( Node *n, int k, Block *current_block, Node_List &value, Node_List &regnd, bool can_change_regs );
   int use_prior_register( Node *copy, uint idx, Node *def, Block *current_block, Node_List &value, Node_List &regnd );
--- a/hotspot/src/share/vm/opto/postaloc.cpp	Thu Aug 06 12:24:41 2009 -0700
+++ b/hotspot/src/share/vm/opto/postaloc.cpp	Fri Aug 14 15:53:46 2009 -0700
@@ -88,6 +88,7 @@
       value->map(old_reg,NULL);  // Yank from value/regnd maps
       regnd->map(old_reg,NULL);  // This register's value is now unknown
     }
+    assert(old->req() <= 2, "can't handle more inputs");
     Node *tmp = old->req() > 1 ? old->in(1) : NULL;
     old->disconnect_inputs(NULL);
     if( !tmp ) break;
@@ -530,6 +531,16 @@
       // Do not change from int to pointer
       Node *val = skip_copies(n);
 
+      // Clear out a dead definition before starting so that the
+      // elimination code doesn't have to guard against it.  The
+      // definition could in fact be a kill projection with a count of
+      // 0 which is safe but since those are uninteresting for copy
+      // elimination just delete them as well.
+      if (regnd[nreg] != NULL && regnd[nreg]->outcnt() == 0) {
+        regnd.map(nreg, NULL);
+        value.map(nreg, NULL);
+      }
+
       uint n_ideal_reg = n->ideal_reg();
       if( is_single_register(n_ideal_reg) ) {
         // If Node 'n' does not change the value mapped by the register,
@@ -537,8 +548,7 @@
         // mapping so 'n' will go dead.
         if( value[nreg] != val ) {
           if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, OptoReg::Bad)) {
-            n->replace_by(regnd[nreg]);
-            j -= yank_if_dead(n,b,&value,&regnd);
+            j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
           } else {
             // Update the mapping: record new Node defined by the register
             regnd.map(nreg,n);
@@ -546,10 +556,9 @@
             // Node after skipping all copies.
             value.map(nreg,val);
           }
-        } else if( !may_be_copy_of_callee(n) && regnd[nreg]->outcnt() != 0 ) {
+        } else if( !may_be_copy_of_callee(n) ) {
           assert( n->is_Copy(), "" );
-          n->replace_by(regnd[nreg]);
-          j -= yank_if_dead(n,b,&value,&regnd);
+          j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
         }
       } else {
         // If the value occupies a register pair, record same info
@@ -565,18 +574,16 @@
         }
         if( value[nreg] != val || value[nreg_lo] != val ) {
           if (eliminate_copy_of_constant(val, n, b, value, regnd, nreg, nreg_lo)) {
-            n->replace_by(regnd[nreg]);
-            j -= yank_if_dead(n,b,&value,&regnd);
+            j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
           } else {
             regnd.map(nreg   , n );
             regnd.map(nreg_lo, n );
             value.map(nreg   ,val);
             value.map(nreg_lo,val);
           }
-        } else if( !may_be_copy_of_callee(n) && regnd[nreg]->outcnt() != 0 ) {
+        } else if( !may_be_copy_of_callee(n) ) {
           assert( n->is_Copy(), "" );
-          n->replace_by(regnd[nreg]);
-          j -= yank_if_dead(n,b,&value,&regnd);
+          j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
         }
       }