# HG changeset patch
# User adlertz
# Date 1372187227 25200
# Node ID 0afc7507c3c169236b1be4fac903913f2d7339f8
# Parent  103f9765cbbed89017eea07afa48bca3bf50e5c1
8017243: 8001345 is incomplete
Summary: Replaces unused decodeN at MemBarAcquire with its corresponding loadN if loadN is used at more than one place.
Reviewed-by: kvn, twisti

diff -r 103f9765cbbe -r 0afc7507c3c1 hotspot/src/share/vm/opto/memnode.cpp
--- a/hotspot/src/share/vm/opto/memnode.cpp	Mon Jun 24 18:23:45 2013 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Tue Jun 25 12:07:07 2013 -0700
@@ -2943,11 +2943,19 @@
       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)) {
-        assert(my_mem->unique_out() == this, "sanity");
-        phase->hash_delete(this);
-        del_req(Precedent);
-        phase->is_IterGVN()->_worklist.push(my_mem); // remove dead node later
-        my_mem = NULL;
+        // 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();