< prev index next >

src/hotspot/share/opto/gcm.cpp

Print this page
rev 49218 : 8192992: Test8007294.java failed: attempted to spill a non-spillable item
Summary: Fix bugs in schedule_late that forces load to early
Reviewed-by:

@@ -681,10 +681,15 @@
     // earliest legal block for 'load'.  In the latter case,
     // immediately insert an anti-dependence edge.
     Block* store_block = get_block_for_node(store);
     assert(store_block != NULL, "unused killing projections skipped above");
 
+    // if the store block is dominated by the LCA - it can't interfere
+    if (LCA->dominates(store_block)) {
+      continue;
+    }
+
     if (store->is_Phi()) {
       // 'load' uses memory which is one (or more) of the Phi's inputs.
       // It must be scheduled not before the Phi, but rather before
       // each of the relevant Phi inputs.
       //

@@ -696,10 +701,19 @@
       // PhiNode may be at start of block 'early' with backedge to 'early'
       DEBUG_ONLY(bool found_match = false);
       for (uint j = PhiNode::Input, jmax = store->req(); j < jmax; j++) {
         if (store->in(j) == mem) {   // Found matching input?
           DEBUG_ONLY(found_match = true);
+          // Only stores can force load to be scheduled earlier, conservative test here.
+          if (mem == load->in(MemNode::Memory)) {
+            // if the phis input is the same as the memory our load consumes, we don't need to schedule before it
+            continue;
+          } else if (mem->isa_MergeMem()) {
+            // if the phis input is a mergemem - it will be visited by the normal downward search
+            continue;
+          }
+
           Block* pred_block = get_block_for_node(store_block->pred(j));
           if (pred_block != early) {
             // If any predecessor of the Phi matches the load's "early block",
             // we do not need a precedence edge between the Phi and 'load'
             // since the load will be forced into a block preceding the Phi.

@@ -1467,10 +1481,20 @@
       return;
     }
   }
   _regalloc = NULL;
 
+#ifndef PRODUCT
+  if (trace_opto_pipelining()) {
+    tty->print("\n---- Before call catch cleanup ----\n");
+    for (uint i = 0; i < number_of_blocks(); i++) {
+      Block* block = get_block(i);
+      block->dump();
+    }
+  }
+#endif
+
   // If we inserted any instructions between a Call and his CatchNode,
   // clone the instructions on all paths below the Catch.
   for (uint i = 0; i < number_of_blocks(); i++) {
     Block* block = get_block(i);
     call_catch_cleanup(block);
< prev index next >