changeset 566:91263420e1c6

6791852: assert(b->_nodes[insidx] == n,"got insidx set incorrectly") Summary: Move the CreateEx up before each round of IFG construction Reviewed-by: never, phh
author kvn
date Fri, 06 Feb 2009 13:31:03 -0800
parents 7fe62bb75bf4
children bbef4344adb2
files src/share/vm/opto/block.cpp src/share/vm/opto/chaitin.cpp src/share/vm/opto/chaitin.hpp src/share/vm/opto/ifg.cpp src/share/vm/opto/live.cpp src/share/vm/opto/reg_split.cpp
diffstat 6 files changed, 70 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/block.cpp	Thu Feb 05 14:43:58 2009 -0800
+++ b/src/share/vm/opto/block.cpp	Fri Feb 06 13:31:03 2009 -0800
@@ -880,6 +880,7 @@
 }
 
 void PhaseCFG::verify( ) const {
+#ifdef ASSERT
   // Verify sane CFG
   for( uint i = 0; i < _num_blocks; i++ ) {
     Block *b = _blocks[i];
@@ -894,10 +895,20 @@
                 "CreateEx must be first instruction in block" );
       }
       for( uint k = 0; k < n->req(); k++ ) {
-        Node *use = n->in(k);
-        if( use && use != n ) {
-          assert( _bbs[use->_idx] || use->is_Con(),
+        Node *def = n->in(k);
+        if( def && def != n ) {
+          assert( _bbs[def->_idx] || def->is_Con(),
                   "must have block; constants for debug info ok" );
+          // Verify that instructions in the block is in correct order.
+          // Uses must follow their definition if they are at the same block.
+          // Mostly done to check that MachSpillCopy nodes are placed correctly
+          // when CreateEx node is moved in build_ifg_physical().
+          if( _bbs[def->_idx] == b &&
+              !(b->head()->is_Loop() && n->is_Phi()) &&
+              // See (+++) comment in reg_split.cpp
+              !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) {
+            assert( b->find_node(def) < j, "uses must follow definitions" );
+          }
         }
       }
     }
@@ -914,6 +925,7 @@
       assert( b->_num_succs == 2, "Conditional branch must have two targets");
     }
   }
+#endif
 }
 #endif
 
--- a/src/share/vm/opto/chaitin.cpp	Thu Feb 05 14:43:58 2009 -0800
+++ b/src/share/vm/opto/chaitin.cpp	Fri Feb 06 13:31:03 2009 -0800
@@ -228,6 +228,11 @@
   // them for real.
   de_ssa();
 
+#ifdef ASSERT
+  // Veify the graph before RA.
+  verify(&live_arena);
+#endif
+
   {
     NOT_PRODUCT( Compile::TracePhase t3("computeLive", &_t_computeLive, TimeCompiler); )
     _live = NULL;                 // Mark live as being not available
@@ -306,12 +311,6 @@
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
     if (C->failing())  return;
 
-#ifdef ASSERT
-    if( VerifyOpto || VerifyRegisterAllocator ) {
-      _cfg.verify();
-      verify_base_ptrs(&live_arena);
-    }
-#endif
     NOT_PRODUCT( C->verify_graph_edges(); )
 
     compact();                  // Compact LRGs; return new lower max lrg
@@ -340,7 +339,7 @@
     compress_uf_map_for_nodes();
 
 #ifdef ASSERT
-    if( VerifyOpto || VerifyRegisterAllocator ) _ifg->verify(this);
+    verify(&live_arena, true);
 #endif
   } else {
     ifg.SquareUp();
@@ -376,12 +375,6 @@
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
     if (C->failing())  return;
-#ifdef ASSERT
-    if( VerifyOpto || VerifyRegisterAllocator ) {
-      _cfg.verify();
-      verify_base_ptrs(&live_arena);
-    }
-#endif
 
     compact();                  // Compact LRGs; return new lower max lrg
 
@@ -412,7 +405,7 @@
     }
     compress_uf_map_for_nodes();
 #ifdef ASSERT
-    if( VerifyOpto || VerifyRegisterAllocator ) _ifg->verify(this);
+    verify(&live_arena, true);
 #endif
     cache_lrg_info();           // Count degree of LRGs
 
@@ -432,6 +425,11 @@
   // Peephole remove copies
   post_allocate_copy_removal();
 
+#ifdef ASSERT
+  // Veify the graph after RA.
+  verify(&live_arena);
+#endif
+
   // max_reg is past the largest *register* used.
   // Convert that to a frame_slot number.
   if( _max_reg <= _matcher._new_SP )
--- a/src/share/vm/opto/chaitin.hpp	Thu Feb 05 14:43:58 2009 -0800
+++ b/src/share/vm/opto/chaitin.hpp	Fri Feb 06 13:31:03 2009 -0800
@@ -491,6 +491,8 @@
   // Verify that base pointers and derived pointers are still sane
   void verify_base_ptrs( ResourceArea *a ) const;
 
+  void verify( ResourceArea *a, bool verify_ifg = false ) const;
+
   void dump_for_spill_split_recycle() const;
 
 public:
--- a/src/share/vm/opto/ifg.cpp	Thu Feb 05 14:43:58 2009 -0800
+++ b/src/share/vm/opto/ifg.cpp	Fri Feb 06 13:31:03 2009 -0800
@@ -471,12 +471,28 @@
     // for the "collect_gc_info" phase later.
     IndexSet liveout(_live->live(b));
     uint last_inst = b->end_idx();
-    // Compute last phi index
-    uint last_phi;
-    for( last_phi = 1; last_phi < last_inst; last_phi++ )
-      if( !b->_nodes[last_phi]->is_Phi() )
+    // Compute first nonphi node index
+    uint first_inst;
+    for( first_inst = 1; first_inst < last_inst; first_inst++ )
+      if( !b->_nodes[first_inst]->is_Phi() )
         break;
 
+    // Spills could be inserted before CreateEx node which should be
+    // first instruction in block after Phis. Move CreateEx up.
+    for( uint insidx = first_inst; insidx < last_inst; insidx++ ) {
+      Node *ex = b->_nodes[insidx];
+      if( ex->is_SpillCopy() ) continue;
+      if( insidx > first_inst && ex->is_Mach() &&
+          ex->as_Mach()->ideal_Opcode() == Op_CreateEx ) {
+        // If the CreateEx isn't above all the MachSpillCopies
+        // then move it to the top.
+        b->_nodes.remove(insidx);
+        b->_nodes.insert(first_inst, ex);
+      }
+      // Stop once a CreateEx or any other node is found
+      break;
+    }
+
     // Reset block's register pressure values for each ifg construction
     uint pressure[2], hrp_index[2];
     pressure[0] = pressure[1] = 0;
@@ -485,7 +501,7 @@
     // Liveout things are presumed live for the whole block.  We accumulate
     // 'area' accordingly.  If they get killed in the block, we'll subtract
     // the unused part of the block from the area.
-    int inst_count = last_inst - last_phi;
+    int inst_count = last_inst - first_inst;
     double cost = (inst_count <= 0) ? 0.0 : b->_freq * double(inst_count);
     assert(!(cost < 0.0), "negative spill cost" );
     IndexSetIterator elements(&liveout);
--- a/src/share/vm/opto/live.cpp	Thu Feb 05 14:43:58 2009 -0800
+++ b/src/share/vm/opto/live.cpp	Fri Feb 06 13:31:03 2009 -0800
@@ -329,8 +329,12 @@
                       UseCompressedOops && check->as_Mach()->ideal_Opcode() == Op_DecodeN ||
 #endif
                       check->as_Mach()->ideal_Opcode() == Op_LoadP ||
-                      check->as_Mach()->ideal_Opcode() == Op_LoadKlass))
+                      check->as_Mach()->ideal_Opcode() == Op_LoadKlass)) {
+                    // Valid nodes
+                  } else {
+                    check->dump();
                     assert(false,"Bad base or derived pointer");
+                  }
                 } else {
                   assert(is_derived,"Bad base pointer");
                   assert(check->is_Mach() && check->as_Mach()->ideal_Opcode() == Op_AddP,"Bad derived pointer");
@@ -346,4 +350,18 @@
   } // End of forall blocks
 #endif
 }
+
+//------------------------------verify-------------------------------------
+// Verify that graphs and base pointers are still sane.
+void PhaseChaitin::verify( ResourceArea *a, bool verify_ifg ) const {
+#ifdef ASSERT
+  if( VerifyOpto || VerifyRegisterAllocator ) {
+    _cfg.verify();
+    verify_base_ptrs(a);
+    if(verify_ifg)
+      _ifg->verify(this);
+  }
 #endif
+}
+
+#endif
--- a/src/share/vm/opto/reg_split.cpp	Thu Feb 05 14:43:58 2009 -0800
+++ b/src/share/vm/opto/reg_split.cpp	Fri Feb 06 13:31:03 2009 -0800
@@ -96,9 +96,7 @@
   // its definer.
   while( i < b->_nodes.size() &&
          (b->_nodes[i]->is_Proj() ||
-          b->_nodes[i]->is_Phi()  ||
-          (b->_nodes[i]->is_Mach() &&
-           b->_nodes[i]->as_Mach()->ideal_Opcode() == Op_CreateEx)) )
+          b->_nodes[i]->is_Phi() ) )
     i++;
 
   // Do not insert between a call and his Catch