< 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 >