changeset 4791:c1130faa6248

8001345: VM crashes with assert(n->outcnt() != 0 || C->top() == n || n->is_Proj()) failed: No dead instructions after post-alloc Summary: Remove unnecessary LoadN / DecodeN nodes at MemBarAcquire nodes. Reviewed-by: kvn, roland
author adlertz
date Mon, 24 Jun 2013 07:28:54 +0200
parents 1122b46889b9
children f460d2390c02
files src/share/vm/opto/memnode.cpp
diffstat 1 files changed, 19 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/opto/memnode.cpp	Wed Jun 26 00:40:13 2013 +0200
+++ b/src/share/vm/opto/memnode.cpp	Mon Jun 24 07:28:54 2013 +0200
@@ -2854,10 +2854,27 @@
   if (in(0) && in(0)->is_top())  return NULL;
 
   // Eliminate volatile MemBars for scalar replaced objects.
-  if (can_reshape && req() == (Precedent+1) &&
-      (Opcode() == Op_MemBarAcquire || Opcode() == Op_MemBarVolatile)) {
+  int opc = Opcode();
+  if (can_reshape && req() == (Precedent + 1) &&
+      (opc == Op_MemBarAcquire || opc == Op_MemBarVolatile)) {
     // Volatile field loads and stores.
     Node* my_mem = in(MemBarNode::Precedent);
+    // The MembarAquire may keep an unused LoadNode alive through the Precedent edge
+    if ((my_mem != NULL) && (opc == Op_MemBarAcquire) && (my_mem->outcnt() == 1)) {
+      // if the Precedent is a decodeN and its input (a Load) is used at more than one place,
+      // replace this Precedent (decodeN) with the Load instead.
+      if ((my_mem->Opcode() == Op_DecodeN) && (my_mem->in(1)->outcnt() > 1))  {
+        Node* load_node = my_mem->in(1);
+        set_req(MemBarNode::Precedent, load_node);
+        phase->is_IterGVN()->_worklist.push(my_mem);
+        my_mem = load_node;
+      } else{
+        assert(my_mem->unique_out() == this, "sanity");
+        del_req(Precedent);
+        phase->is_IterGVN()->_worklist.push(my_mem); // remove dead node later
+        my_mem = NULL;
+      }
+    }
     if (my_mem != NULL && my_mem->is_Mem()) {
       const TypeOopPtr* t_oop = my_mem->in(MemNode::Address)->bottom_type()->isa_oopptr();
       // Check for scalar replaced object reference.