< prev index next > src/hotspot/share/opto/lcm.cpp
Print this page
case Op_StoreC:
case Op_StoreD:
case Op_StoreF:
case Op_StoreI:
case Op_StoreL:
+ case Op_StoreLSpecial:
case Op_StoreP:
case Op_StoreN:
case Op_StoreNKlass:
was_store = true; // Memory op is a store op
// Stores will have their address in slot 2 (memory in slot 1).
} else {
// only regular oops are expected here
tptr = base->bottom_type()->is_ptr();
}
// Give up if offset is not a compile-time constant.
! if (offset == Type::OffsetBot || tptr->_offset == Type::OffsetBot)
continue;
! offset += tptr->_offset; // correct if base is offsetted
// Give up if reference is beyond page size.
if (MacroAssembler::needs_explicit_null_check(offset))
continue;
// Give up if base is a decode node and the heap base is not protected.
if (base->is_Mach() && base->as_Mach()->ideal_Opcode() == Op_DecodeN &&
} else {
// only regular oops are expected here
tptr = base->bottom_type()->is_ptr();
}
// Give up if offset is not a compile-time constant.
! if (offset == Type::OffsetBot || tptr->offset() == Type::OffsetBot)
continue;
! offset += tptr->offset(); // correct if base is offsetted
// Give up if reference is beyond page size.
if (MacroAssembler::needs_explicit_null_check(offset))
continue;
// Give up if base is a decode node and the heap base is not protected.
if (base->is_Mach() && base->as_Mach()->ideal_Opcode() == Op_DecodeN &&
// a scratch register for the implementation of the node (e.g. in
// late-expanded GC barriers).
continue;
}
// Block of memory-op input
! Block *inb = get_block_for_node(mach->in(j));
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 )
// a scratch register for the implementation of the node (e.g. in
// late-expanded GC barriers).
continue;
}
// Block of memory-op input
! Block* inb = get_block_for_node(mach->in(j));
+ if (mach->in(j)->is_Con() && mach->in(j)->req() == 1 && 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 )
}
move_node_and_its_projections_to_block(val, block);
}
}
+ // 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);
+ }
+ }
+ }
+ }
+
+
// Move any MachTemp inputs to the end of the test block.
for (uint i = 0; i < best->req(); i++) {
Node* n = best->in(i);
if (n == nullptr || !n->is_MachTemp()) {
continue;
case Op_StoreC:
case Op_StoreD:
case Op_StoreF:
case Op_StoreI:
case Op_StoreL:
+ case Op_StoreLSpecial:
case Op_StoreP:
case Op_StoreN:
case Op_StoreVector:
case Op_StoreVectorMasked:
case Op_StoreVectorScatter:
// Act as if the call defines the Frame Pointer.
// Certainly the FP is alive and well after the call.
regs.Insert(_matcher.c_frame_pointer());
// Set all registers killed and not already defined by the call.
! uint r_cnt = mcall->tf()->range()->cnt();
int op = mcall->ideal_Opcode();
MachProjNode *proj = new MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
map_node_to_block(proj, block);
block->insert_node(proj, node_cnt++);
// Act as if the call defines the Frame Pointer.
// Certainly the FP is alive and well after the call.
regs.Insert(_matcher.c_frame_pointer());
// Set all registers killed and not already defined by the call.
! uint r_cnt = mcall->tf()->range_cc()->cnt();
int op = mcall->ideal_Opcode();
MachProjNode *proj = new MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
map_node_to_block(proj, block);
block->insert_node(proj, node_cnt++);
< prev index next >