6809798: SafePointScalarObject node placed into incorrect block during GCM
authorkvn
Thu, 26 Feb 2009 14:26:02 -0800
changeset 2127 268ea58ed775
parent 2126 f6f30d1677a8
child 2128 c08c265de2f5
6809798: SafePointScalarObject node placed into incorrect block during GCM Summary: Replace the control edge of a pinned node before scheduling. Reviewed-by: never
hotspot/src/share/vm/opto/block.cpp
hotspot/src/share/vm/opto/block.hpp
hotspot/src/share/vm/opto/callnode.cpp
hotspot/src/share/vm/opto/callnode.hpp
hotspot/src/share/vm/opto/gcm.cpp
hotspot/src/share/vm/opto/macro.cpp
--- a/hotspot/src/share/vm/opto/block.cpp	Wed Feb 25 14:36:27 2009 -0800
+++ b/hotspot/src/share/vm/opto/block.cpp	Thu Feb 26 14:26:02 2009 -0800
@@ -909,6 +909,10 @@
               !(n->jvms() != NULL && n->jvms()->is_monitor_use(k)) ) {
             assert( b->find_node(def) < j, "uses must follow definitions" );
           }
+          if( def->is_SafePointScalarObject() ) {
+            assert(_bbs[def->_idx] == b, "SafePointScalarObject Node should be at the same block as its SafePoint node");
+            assert(_bbs[def->_idx] == _bbs[def->in(0)->_idx], "SafePointScalarObject Node should be at the same block as its control edge");
+          }
         }
       }
     }
--- a/hotspot/src/share/vm/opto/block.hpp	Wed Feb 25 14:36:27 2009 -0800
+++ b/hotspot/src/share/vm/opto/block.hpp	Thu Feb 26 14:26:02 2009 -0800
@@ -347,6 +347,8 @@
   // Helper function to insert a node into a block
   void schedule_node_into_block( Node *n, Block *b );
 
+  void PhaseCFG::replace_block_proj_ctrl( Node *n );
+
   // Set the basic block for pinned Nodes
   void schedule_pinned_nodes( VectorSet &visited );
 
--- a/hotspot/src/share/vm/opto/callnode.cpp	Wed Feb 25 14:36:27 2009 -0800
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Thu Feb 26 14:26:02 2009 -0800
@@ -975,6 +975,7 @@
 }
 
 bool SafePointScalarObjectNode::pinned() const { return true; }
+bool SafePointScalarObjectNode::depends_only_on_test() const { return false; }
 
 uint SafePointScalarObjectNode::ideal_reg() const {
   return 0; // No matching to machine instruction
--- a/hotspot/src/share/vm/opto/callnode.hpp	Wed Feb 25 14:36:27 2009 -0800
+++ b/hotspot/src/share/vm/opto/callnode.hpp	Thu Feb 26 14:26:02 2009 -0800
@@ -437,6 +437,10 @@
   // of the SafePoint node for which it was generated.
   virtual bool pinned() const; // { return true; }
 
+  // SafePointScalarObject depends on the SafePoint node
+  // for which it was generated.
+  virtual bool depends_only_on_test() const; // { return false; }
+
   virtual uint size_of() const { return sizeof(*this); }
 
   // Assumes that "this" is an argument to a safepoint node "s", and that
--- a/hotspot/src/share/vm/opto/gcm.cpp	Wed Feb 25 14:36:27 2009 -0800
+++ b/hotspot/src/share/vm/opto/gcm.cpp	Thu Feb 26 14:26:02 2009 -0800
@@ -57,6 +57,37 @@
   }
 }
 
+//----------------------------replace_block_proj_ctrl-------------------------
+// Nodes that have is_block_proj() nodes as their control need to use
+// the appropriate Region for their actual block as their control since
+// the projection will be in a predecessor block.
+void PhaseCFG::replace_block_proj_ctrl( Node *n ) {
+  const Node *in0 = n->in(0);
+  assert(in0 != NULL, "Only control-dependent");
+  const Node *p = in0->is_block_proj();
+  if (p != NULL && p != n) {    // Control from a block projection?
+    assert(!n->pinned() || n->is_SafePointScalarObject(), "only SafePointScalarObject pinned node is expected here");
+    // Find trailing Region
+    Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block
+    uint j = 0;
+    if (pb->_num_succs != 1) {  // More then 1 successor?
+      // Search for successor
+      uint max = pb->_nodes.size();
+      assert( max > 1, "" );
+      uint start = max - pb->_num_succs;
+      // Find which output path belongs to projection
+      for (j = start; j < max; j++) {
+        if( pb->_nodes[j] == in0 )
+          break;
+      }
+      assert( j < max, "must find" );
+      // Change control to match head of successor basic block
+      j -= start;
+    }
+    n->set_req(0, pb->_succs[j]->head());
+  }
+}
+
 
 //------------------------------schedule_pinned_nodes--------------------------
 // Set the basic block for Nodes pinned into blocks
@@ -68,8 +99,10 @@
     Node *n = spstack.pop();
     if( !visited.test_set(n->_idx) ) { // Test node and flag it as visited
       if( n->pinned() && !_bbs.lookup(n->_idx) ) {  // Pinned?  Nail it down!
+        assert( n->in(0), "pinned Node must have Control" );
+        // Before setting block replace block_proj control edge
+        replace_block_proj_ctrl(n);
         Node *input = n->in(0);
-        assert( input, "pinned Node must have Control" );
         while( !input->is_block_start() )
           input = input->in(0);
         Block *b = _bbs[input->_idx];  // Basic block of controlling input
@@ -158,34 +191,12 @@
       uint  i = nstack_top_i;
 
       if (i == 0) {
-        // Special control input processing.
-        // While I am here, go ahead and look for Nodes which are taking control
-        // from a is_block_proj Node.  After I inserted RegionNodes to make proper
-        // blocks, the control at a is_block_proj more properly comes from the
-        // Region being controlled by the block_proj Node.
+        // Fixup some control.  Constants without control get attached
+        // to root and nodes that use is_block_proj() nodes should be attached
+        // to the region that starts their block.
         const Node *in0 = n->in(0);
         if (in0 != NULL) {              // Control-dependent?
-          const Node *p = in0->is_block_proj();
-          if (p != NULL && p != n) {    // Control from a block projection?
-            // Find trailing Region
-            Block *pb = _bbs[in0->_idx]; // Block-projection already has basic block
-            uint j = 0;
-            if (pb->_num_succs != 1) {  // More then 1 successor?
-              // Search for successor
-              uint max = pb->_nodes.size();
-              assert( max > 1, "" );
-              uint start = max - pb->_num_succs;
-              // Find which output path belongs to projection
-              for (j = start; j < max; j++) {
-                if( pb->_nodes[j] == in0 )
-                  break;
-              }
-              assert( j < max, "must find" );
-              // Change control to match head of successor basic block
-              j -= start;
-            }
-            n->set_req(0, pb->_succs[j]->head());
-          }
+          replace_block_proj_ctrl(n);
         } else {               // n->in(0) == NULL
           if (n->req() == 1) { // This guy is a constant with NO inputs?
             n->set_req(0, _root);
@@ -226,6 +237,8 @@
         if (!n->pinned()) {
           // Set earliest legal block.
           _bbs.map(n->_idx, find_deepest_input(n, _bbs));
+        } else {
+          assert(_bbs[n->_idx] == _bbs[n->in(0)->_idx], "Pinned Node should be at the same block as its control edge");
         }
 
         if (nstack.is_empty()) {
--- a/hotspot/src/share/vm/opto/macro.cpp	Wed Feb 25 14:36:27 2009 -0800
+++ b/hotspot/src/share/vm/opto/macro.cpp	Thu Feb 26 14:26:02 2009 -0800
@@ -64,6 +64,7 @@
       uint old_unique = C->unique();
       Node* new_in = old_sosn->clone(jvms_adj, sosn_map);
       if (old_unique != C->unique()) {
+        new_in->set_req(0, newcall->in(0)); // reset control edge
         new_in = transform_later(new_in); // Register new node.
       }
       old_in = new_in;