changeset 9764:09c6aa9c4a33

Implemented additional optimizations for read barriers.
author rkennke
date Tue, 06 Oct 2015 15:05:10 +0200
parents 29693376eaec
children edd77b2146e0
files src/share/vm/opto/shenandoahSupport.cpp src/share/vm/opto/shenandoahSupport.hpp
diffstat 2 files changed, 83 insertions(+), 21 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/shenandoahSupport.cpp	Tue Oct 06 15:04:50 2015 +0200
+++ b/src/share/vm/opto/shenandoahSupport.cpp	Tue Oct 06 15:05:10 2015 +0200
@@ -93,6 +93,72 @@
   return true;
 }
 
+bool ShenandoahReadBarrierNode::dominates_memory_rb_impl(PhaseTransform* phase,
+							 Node* b1,
+							 Node* b2,
+							 Node* current,
+							 Unique_Node_List &visited) {
+  if (current == NULL) {
+    return false; // Incomplete phi. Try again later.
+  } else if (visited.member(current)) {
+    // We have already seen it.
+    return true;
+  }
+  visited.push(current);
+
+  if (current == b1) {
+    return true;
+  } else if (current == phase->C->immutable_memory()) {
+    return false;
+  } else if (current->isa_Phi()) {
+    bool dominates = true;
+    for (uint i = 1; i < current->req() && dominates == true; i++) {
+      Node* in = current->in(i);
+      dominates = dominates && dominates_memory_rb_impl(phase, b1, b2, in, visited);
+    }
+    return dominates;
+  } else if (current->Opcode() == Op_ShenandoahWriteBarrier) {
+    const Type* in_type = current->bottom_type();
+    const Type* this_type = b2->bottom_type();
+    if (is_independent(in_type, this_type)) {
+      Node* in = current->in(Memory);
+      return dominates_memory_rb_impl(phase, b1, b2, in, visited);
+    } else {
+      return false;
+    }
+  } else if (current->Opcode() == Op_ShenandoahWBMemProj) {
+    Node* in = current->in(0);
+    return dominates_memory_rb_impl(phase, b1, b2, in, visited);
+  } else if (current->is_top()) {
+    return true; // Dead path
+  } else if (current->is_Proj()) {
+    return dominates_memory_rb_impl(phase, b1, b2, current->in(0), visited);
+  } else if (current->is_Call()) {
+    return false; // TODO: Maybe improve by looking at the call's memory effects?
+  } else if (current->is_MemBar()) {
+    return false; // TODO: Do we need to stop at *any* membar?
+  } else if (current->is_MergeMem()) {
+    // if (true) return false;
+    // tty->print_cr("current == mergemem: "); current->dump();
+    const TypePtr* adr_type = phase->type(b2)->is_ptr()->add_offset(-8);
+    uint alias_idx = phase->C->get_alias_index(adr_type);
+    Node* mem_in = current->as_MergeMem()->memory_at(alias_idx);
+    return dominates_memory_rb_impl(phase, b1, b2, current->in(TypeFunc::Memory), visited);
+  } else {
+    // tty->print_cr("what else can we see here:");
+#ifdef ASSERT
+    current->dump();
+#endif
+    ShouldNotReachHere();
+    return false;
+  }
+}
+
+bool ShenandoahReadBarrierNode::dominates_memory_rb(PhaseTransform* phase, Node* b1, Node* b2) {
+  Unique_Node_List visited;
+  return dominates_memory_rb_impl(phase, b1->in(Memory), b2, b2->in(Memory), visited);
+}
+
 bool ShenandoahReadBarrierNode::is_independent(const Type* in_type, const Type* this_type) const {
   assert(in_type->isa_oopptr(), "expect oop ptr");
   assert(this_type->isa_oopptr(), "expect oop ptr");
@@ -132,8 +198,6 @@
     return NULL;
   }
 
-  // if (true) return NULL;
-
   if (in(Memory) == phase->C->immutable_memory()) return NULL;
 
   // If memory input is a MergeMem, take the appropriate slice out of it.
@@ -308,7 +372,7 @@
     Node* in = current->in(0);
     return dominates_memory_impl(phase, b1, b2, in, visited);
   } else if (current->is_top()) {
-    return false; // Dead path
+    return true; // Dead path
   } else if (current->is_Proj()) {
     // tty->print_cr("current == proj: "); current->dump();
     return dominates_memory_impl(phase, b1, b2, current->in(0), visited);
@@ -424,30 +488,27 @@
   // tty->print("optimizing rb: "); dump();
   Node* id = ShenandoahBarrierNode::Identity(phase);
 
-  if (true) return id;
-
-  if (id == this) {
+  if (id == this && phase->is_IterGVN()) {
     Node* n = in(ValueIn);
     // No success in super call. Try to combine identical read barriers.
     for (DUIterator i = n->outs(); n->has_out(i); i++) {
       Node* sibling = n->out(i);
-      if (sibling == this) {
+      if (sibling == this || sibling->Opcode() != Op_ShenandoahReadBarrier) {
   	continue;
       }
-      if (sibling->outcnt() == 0) {
-	continue;
-      }
-      if (sibling->Opcode() == Op_ShenandoahReadBarrier &&
-  	  sibling->in(Control) == in(Control) &&
-  	  sibling->in(Memory)  == in(Memory) &&
-  	  sibling->in(ValueIn)  == in(ValueIn)) {
-	// assert(sibling->hash() == hash(), "ident node needs same hash");
-	// assert(cmp(sibling) == 1, "ident node needs equals");
-	//if (sibling->_hash_lock == 0) {
-	  // tty->print_cr("skipped sibling not in hash: "); sibling->dump();
-	//} else {
+      assert(sibling->in(ValueIn)  == in(ValueIn), "sanity");
+      if (phase->is_IterGVN()->hash_find(sibling) &&
+	  sibling->bottom_type() == bottom_type() &&
+	  sibling->in(Control) == in(Control) &&
+  	  dominates_memory_rb(phase, sibling, this)) {
+	/*
+	if (in(Memory) != sibling->in(Memory)) {
+	  tty->print_cr("interesting rb-fold");
+	  dump();
+	  sibling->dump();
+	}
+	*/
 	return sibling;
-	//}
       }
     }
   }
--- a/src/share/vm/opto/shenandoahSupport.hpp	Tue Oct 06 15:04:50 2015 +0200
+++ b/src/share/vm/opto/shenandoahSupport.hpp	Tue Oct 06 15:05:10 2015 +0200
@@ -82,7 +82,8 @@
 
 private:
   bool is_independent(const Type* in_type, const Type* this_type) const;
-
+  bool dominates_memory_rb(PhaseTransform* phase, Node* b1, Node* b2);
+  bool dominates_memory_rb_impl(PhaseTransform* phase, Node* b1, Node* b2, Node* current, Unique_Node_List &visited);
 };
 
 class ShenandoahWriteBarrierNode : public ShenandoahBarrierNode {