< prev index next >

src/hotspot/share/opto/memnode.cpp

Print this page

        

@@ -3172,41 +3172,79 @@
   leading->_pair_idx = leading->_idx;
 #endif
 }
 
 MemBarNode* MemBarNode::trailing_membar() const {
+  ResourceMark rm;
   Node* trailing = (Node*)this;
   VectorSet seen(Thread::current()->resource_area());
-  while (!trailing->is_MemBar() || !trailing->as_MemBar()->trailing()) {
-    if (seen.test_set(trailing->_idx)) {
-      // Dying subgraph?
-      return NULL;
+  Node_Stack multis(0);
+  do {
+    Node* c = trailing;
+    uint i = 0;
+    do {
+      trailing = NULL;
+      for (; i < c->outcnt(); i++) {
+        Node* next = c->raw_out(i);
+        if (next != c && next->is_CFG()) {
+          if (c->is_MultiBranch()) {
+            if (multis.node() == c) {
+              multis.set_index(i+1);
+            } else {
+              multis.push(c, i+1);
+            }
     }
-    for (DUIterator_Fast jmax, j = trailing->fast_outs(jmax); j < jmax; j++) {
-      Node* next = trailing->fast_out(j);
-      if (next != trailing && next->is_CFG()) {
         trailing = next;
         break;
       }
     }
+      if (trailing != NULL && !seen.test_set(trailing->_idx)) {
+        break;
+      }
+      while (multis.size() > 0) {
+        c = multis.node();
+        i = multis.index();
+        if (i < c->req()) {
+          break;
+        }
+        multis.pop();
   }
+    } while (multis.size() > 0);
+  } while (!trailing->is_MemBar() || !trailing->as_MemBar()->trailing());
+
   MemBarNode* mb = trailing->as_MemBar();
   assert((mb->_kind == TrailingStore && _kind == LeadingStore) ||
          (mb->_kind == TrailingLoadStore && _kind == LeadingLoadStore), "bad trailing membar");
   assert(mb->_pair_idx == _pair_idx, "bad trailing membar");
   return mb;
 }
 
 MemBarNode* MemBarNode::leading_membar() const {
+  ResourceMark rm;
   VectorSet seen(Thread::current()->resource_area());
+  Node_Stack regions(0);
   Node* leading = in(0);
   while (leading != NULL && (!leading->is_MemBar() || !leading->as_MemBar()->leading())) {
-    if (seen.test_set(leading->_idx)) {
-      // Dying subgraph?
+    while (leading == NULL || leading->is_top() || seen.test_set(leading->_idx)) {
+      leading = NULL;
+      while (regions.size() > 0) {
+        Node* r = regions.node();
+        uint i = regions.index();
+        if (i < r->req()) {
+          leading = r->in(i);
+          regions.set_index(i+1);
+        } else {
+          regions.pop();
+        }
+      }
+      if (leading == NULL) {
+        assert(regions.size() == 0, "all paths should have been tried");
       return NULL;
     }
+    }
     if (leading->is_Region()) {
+      regions.push(leading, 2);
       leading = leading->in(1);
     } else {
       leading = leading->in(0);
     }
   }
< prev index next >