changeset 295:ea18057223c4

6732194: Data corruption dependent on -server/-client/-Xbatch Summary: rematerializing nodes results in incorrect inputs Reviewed-by: rasbold
author never
date Mon, 18 Aug 2008 23:17:51 -0700
parents 616a07a75c3c
children ce93a51457ae
files src/share/vm/opto/chaitin.cpp src/share/vm/opto/chaitin.hpp src/share/vm/opto/coalesce.cpp src/share/vm/opto/ifg.cpp src/share/vm/opto/reg_split.cpp
diffstat 5 files changed, 21 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/chaitin.cpp	Thu Aug 14 10:15:29 2008 -0700
+++ b/src/share/vm/opto/chaitin.cpp	Mon Aug 18 23:17:51 2008 -0700
@@ -43,7 +43,7 @@
   if( _degree_valid ) tty->print( "%d ", _eff_degree );
   else tty->print("? ");
 
-  if( _def == NodeSentinel ) {
+  if( is_multidef() ) {
     tty->print("MultiDef ");
     if (_defs != NULL) {
       tty->print("(");
@@ -765,7 +765,7 @@
         // if the LRG is an unaligned pair, we will have to spill
         // so clear the LRG's register mask if it is not already spilled
         if ( !n->is_SpillCopy() &&
-               (lrg._def == NULL || lrg._def == NodeSentinel || !lrg._def->is_SpillCopy()) &&
+               (lrg._def == NULL || lrg.is_multidef() || !lrg._def->is_SpillCopy()) &&
                lrgmask.is_misaligned_Pair()) {
           lrg.Clear();
         }
@@ -1282,7 +1282,7 @@
     // Live range is live and no colors available
     else {
       assert( lrg->alive(), "" );
-      assert( !lrg->_fat_proj || lrg->_def == NodeSentinel ||
+      assert( !lrg->_fat_proj || lrg->is_multidef() ||
               lrg->_def->outcnt() > 0, "fat_proj cannot spill");
       assert( !orig_mask.is_AllStack(), "All Stack does not spill" );
 
--- a/src/share/vm/opto/chaitin.hpp	Thu Aug 14 10:15:29 2008 -0700
+++ b/src/share/vm/opto/chaitin.hpp	Mon Aug 18 23:17:51 2008 -0700
@@ -156,6 +156,8 @@
 
   // Alive if non-zero, dead if zero
   bool alive() const { return _def != NULL; }
+  bool is_multidef() const { return _def == NodeSentinel; }
+  bool is_singledef() const { return _def != NodeSentinel; }
 
 #ifndef PRODUCT
   void dump( ) const;
@@ -320,7 +322,8 @@
   uint split_DEF( Node *def, Block *b, int loc, uint max, Node **Reachblock, Node **debug_defs, GrowableArray<uint> splits, int slidx );
   uint split_USE( Node *def, Block *b, Node *use, uint useidx, uint max, bool def_down, bool cisc_sp, GrowableArray<uint> splits, int slidx );
   int clone_projs( Block *b, uint idx, Node *con, Node *copy, uint &maxlrg );
-  Node *split_Rematerialize( Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits, int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru );
+  Node *split_Rematerialize(Node *def, Block *b, uint insidx, uint &maxlrg, GrowableArray<uint> splits,
+                            int slidx, uint *lrg2reach, Node **Reachblock, bool walkThru);
   // True if lidx is used before any real register is def'd in the block
   bool prompt_use( Block *b, uint lidx );
   Node *get_spillcopy_wide( Node *def, Node *use, uint uidx );
--- a/src/share/vm/opto/coalesce.cpp	Thu Aug 14 10:15:29 2008 -0700
+++ b/src/share/vm/opto/coalesce.cpp	Mon Aug 18 23:17:51 2008 -0700
@@ -604,8 +604,8 @@
   // If both are single def, then src_def powers one live range
   // and def_copy powers the other.  After merging, src_def powers
   // the combined live range.
-  lrgs(lr1)._def = (lrgs(lr1)._def == NodeSentinel ||
-                        lrgs(lr2)._def == NodeSentinel )
+  lrgs(lr1)._def = (lrgs(lr1).is_multidef() ||
+                        lrgs(lr2).is_multidef() )
     ? NodeSentinel : src_def;
   lrgs(lr2)._def = NULL;    // No def for lrg 2
   lrgs(lr2).Clear();        // Force empty mask for LRG 2
--- a/src/share/vm/opto/ifg.cpp	Thu Aug 14 10:15:29 2008 -0700
+++ b/src/share/vm/opto/ifg.cpp	Mon Aug 18 23:17:51 2008 -0700
@@ -594,7 +594,7 @@
 
           // Insure high score for immediate-use spill copies so they get a color
           if( n->is_SpillCopy()
-              && lrgs(r)._def != NodeSentinel     // MultiDef live range can still split
+              && lrgs(r).is_singledef()        // MultiDef live range can still split
               && n->outcnt() == 1              // and use must be in this block
               && _cfg._bbs[n->unique_out()->_idx] == b ) {
             // All single-use MachSpillCopy(s) that immediately precede their
--- a/src/share/vm/opto/reg_split.cpp	Thu Aug 14 10:15:29 2008 -0700
+++ b/src/share/vm/opto/reg_split.cpp	Mon Aug 18 23:17:51 2008 -0700
@@ -284,7 +284,7 @@
       // Check for single-def (LRG cannot redefined)
       uint lidx = n2lidx(in);
       if( lidx >= _maxlrg ) continue; // Value is a recent spill-copy
-      if( lrgs(lidx)._def != NodeSentinel ) continue;
+      if (lrgs(lidx).is_singledef()) continue;
 
       Block *b_def = _cfg._bbs[def->_idx];
       int idx_def = b_def->find_node(def);
@@ -311,12 +311,20 @@
       uint lidx = Find_id(in);
 
       // Walk backwards thru spill copy node intermediates
-      if( walkThru )
+      if (walkThru) {
         while ( in->is_SpillCopy() && lidx >= _maxlrg ) {
           in = in->in(1);
           lidx = Find_id(in);
         }
 
+        if (lidx < _maxlrg && lrgs(lidx).is_multidef()) {
+          // walkThru found a multidef LRG, which is unsafe to use, so
+          // just keep the original def used in the clone.
+          in = spill->in(i);
+          lidx = Find_id(in);
+        }
+      }
+
       if( lidx < _maxlrg && lrgs(lidx).reg() >= LRG::SPILL_REG ) {
         Node *rdef = Reachblock[lrg2reach[lidx]];
         if( rdef ) spill->set_req(i,rdef);
@@ -505,7 +513,7 @@
       // Do not bother splitting or putting in Phis for single-def
       // rematerialized live ranges.  This happens alot to constants
       // with long live ranges.
-      if( lrgs(lidx)._def != NodeSentinel &&
+      if( lrgs(lidx).is_singledef() &&
           lrgs(lidx)._def->rematerialize() ) {
         // reset the Reaches & UP entries
         Reachblock[slidx] = lrgs(lidx)._def;