8162496: missing precedence edge for anti_dependence
authorkvn
Thu, 18 Aug 2016 14:31:02 -0700
changeset 40862 3f9cd7a4bfa7
parent 40651 998e35976abf
child 40863 f5fec6a2dc9e
8162496: missing precedence edge for anti_dependence Summary: fix Implicit Null Check optimization code. Reviewed-by: roland, aph
hotspot/src/share/vm/opto/block.cpp
hotspot/src/share/vm/opto/block.hpp
hotspot/src/share/vm/opto/lcm.cpp
--- a/hotspot/src/share/vm/opto/block.cpp	Thu Aug 18 11:26:35 2016 +0300
+++ b/hotspot/src/share/vm/opto/block.cpp	Thu Aug 18 14:31:02 2016 -0700
@@ -1212,6 +1212,9 @@
       if (j >= 1 && n->is_Mach() && n->as_Mach()->ideal_Opcode() == Op_CreateEx) {
         assert(j == 1 || block->get_node(j-1)->is_Phi(), "CreateEx must be first instruction in block");
       }
+      if (n->needs_anti_dependence_check()) {
+        verify_anti_dependences(block, n);
+      }
       for (uint k = 0; k < n->req(); k++) {
         Node *def = n->in(k);
         if (def && def != n) {
--- a/hotspot/src/share/vm/opto/block.hpp	Thu Aug 18 11:26:35 2016 +0300
+++ b/hotspot/src/share/vm/opto/block.hpp	Thu Aug 18 14:31:02 2016 -0700
@@ -186,14 +186,13 @@
   Block* lone_fall_through();   // Return lone fall-through Block or null
 
   Block* dom_lca(Block* that);  // Compute LCA in dominator tree.
-#ifdef ASSERT
+
   bool dominates(Block* that) {
     int dom_diff = this->_dom_depth - that->_dom_depth;
     if (dom_diff > 0)  return false;
     for (; dom_diff < 0; dom_diff++)  that = that->_idom;
     return this == that;
   }
-#endif
 
   // Report the alignment required by this block.  Must be a power of 2.
   // The previous block will insert nops to get this alignment.
@@ -481,9 +480,9 @@
   MachNode* _goto;
 
   Block* insert_anti_dependences(Block* LCA, Node* load, bool verify = false);
-  void verify_anti_dependences(Block* LCA, Node* load) {
+  void verify_anti_dependences(Block* LCA, Node* load) const {
     assert(LCA == get_block_for_node(load), "should already be scheduled");
-    insert_anti_dependences(LCA, load, true);
+    const_cast<PhaseCFG*>(this)->insert_anti_dependences(LCA, load, true);
   }
 
   bool move_to_next(Block* bx, uint b_index);
--- a/hotspot/src/share/vm/opto/lcm.cpp	Thu Aug 18 11:26:35 2016 +0300
+++ b/hotspot/src/share/vm/opto/lcm.cpp	Thu Aug 18 14:31:02 2016 -0700
@@ -240,6 +240,14 @@
       continue;
     }
 
+    // Check that node's control edge is not-null block's head or dominates it,
+    // otherwise we can't hoist it because there are other control dependencies.
+    Node* ctrl = mach->in(0);
+    if (ctrl != NULL && !(ctrl == not_null_block->head() ||
+        get_block_for_node(ctrl)->dominates(not_null_block))) {
+      continue;
+    }
+
     // check if the offset is not too high for implicit exception
     {
       intptr_t offset = 0;
@@ -379,9 +387,12 @@
   block->add_inst(best);
   map_node_to_block(best, block);
 
-  // Move the control dependence
-  if (best->in(0) && best->in(0) == old_block->head())
-    best->set_req(0, block->head());
+  // Move the control dependence if it is pinned to not-null block.
+  // Don't change it in other cases: NULL or dominating control.
+  if (best->in(0) == not_null_block->head()) {
+    // Set it to control edge of null check.
+    best->set_req(0, proj->in(0)->in(0));
+  }
 
   // Check for flag-killing projections that also need to be hoisted
   // Should be DU safe because no edge updates.
@@ -437,6 +448,18 @@
 
   latency_from_uses(nul_chk);
   latency_from_uses(best);
+
+  // insert anti-dependences to defs in this block
+  if (! best->needs_anti_dependence_check()) {
+    for (uint k = 1; k < block->number_of_nodes(); k++) {
+      Node *n = block->get_node(k);
+      if (n->needs_anti_dependence_check() &&
+          n->in(LoadNode::Memory) == best->in(StoreNode::Memory)) {
+        // Found anti-dependent load
+        insert_anti_dependences(block, n);
+      }
+    }
+  }
 }