< prev index next >
src/hotspot/share/opto/lcm.cpp
Print this page
@@ -311,11 +311,15 @@
vidx = j;
// Ignore DecodeN val which could be hoisted to where needed.
if( is_decoden ) continue;
}
// Block of memory-op input
- Block *inb = get_block_for_node(mach->in(j));
+ Block* inb = get_block_for_node(mach->in(j));
+ if (mach->in(j)->is_Con() && inb == get_block_for_node(mach)) {
+ // Ignore constant loads scheduled in the same block (we can simply hoist them as well)
+ continue;
+ }
Block *b = block; // Start from nul check
while( b != inb && b->_dom_depth > inb->_dom_depth )
b = b->_idom; // search upwards for input
// See if input dominates null check
if( b != inb )
@@ -387,11 +391,32 @@
block->add_inst(n);
map_node_to_block(n, block);
}
}
}
+ } else {
+ // Hoist constant load inputs as well.
+ for (uint i = 1; i < best->req(); ++i) {
+ Node* n = best->in(i);
+ if (n->is_Con() && get_block_for_node(n) == get_block_for_node(best)) {
+ get_block_for_node(n)->find_remove(n);
+ block->add_inst(n);
+ map_node_to_block(n, block);
+ // Constant loads may kill flags (for example, when XORing a register).
+ // Check for flag-killing projections that also need to be hoisted.
+ for (DUIterator_Fast jmax, j = n->fast_outs(jmax); j < jmax; j++) {
+ Node* proj = n->fast_out(j);
+ if (proj->is_MachProj()) {
+ get_block_for_node(proj)->find_remove(proj);
+ block->add_inst(proj);
+ map_node_to_block(proj, block);
+ }
+ }
+ }
}
+ }
+
// Hoist the memory candidate up to the end of the test block.
Block *old_block = get_block_for_node(best);
old_block->find_remove(best);
block->add_inst(best);
map_node_to_block(best, block);
< prev index next >