< 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,690 **** --- 681,695 ---- // 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,705 **** --- 701,719 ---- // 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,1476 **** --- 1481,1500 ---- 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 >