src/share/vm/opto/lcm.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
6954029 Cdiff src/share/vm/opto/lcm.cpp
src/share/vm/opto/lcm.cpp
Print this page
*** 30,40 ****
//------------------------------implicit_null_check----------------------------
// Detect implicit-null-check opportunities. Basically, find NULL checks
// with suitable memory ops nearby. Use the memory op to do the NULL check.
// I can generate a memory op if there is not one nearby.
// The proj is the control projection for the not-null case.
! // The val is the pointer being checked for nullness.
void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) {
// Assume if null check need for 0 offset then always needed
// Intel solaris doesn't support any null checks yet and no
// mechanism exists (yet) to set the switches at an os_cpu level
if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return;
--- 30,41 ----
//------------------------------implicit_null_check----------------------------
// Detect implicit-null-check opportunities. Basically, find NULL checks
// with suitable memory ops nearby. Use the memory op to do the NULL check.
// I can generate a memory op if there is not one nearby.
// The proj is the control projection for the not-null case.
! // The val is the pointer being checked for nullness or
! // decodeHeapOop_not_null node if it did not fold into address.
void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) {
// Assume if null check need for 0 offset then always needed
// Intel solaris doesn't support any null checks yet and no
// mechanism exists (yet) to set the switches at an os_cpu level
if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return;
*** 94,103 ****
--- 95,108 ----
// We did not find an uncommon trap.
return;
}
}
+ // Check for decodeHeapOop_not_null node which did not fold into address.
+ bool is_decoden = val->is_Mach() &&
+ (val->as_Mach()->ideal_Opcode() == Op_DecodeN);
+
// Search the successor block for a load or store who's base value is also
// the tested value. There may be several.
Node_List *out = new Node_List(Thread::current()->resource_area());
MachNode *best = NULL; // Best found so far
for (DUIterator i = val->outs(); val->has_out(i); i++) {
*** 146,156 ****
continue;
default: // Also check for embedded loads
if( !mach->needs_anti_dependence_check() )
continue; // Not an memory op; skip it
{
! // Check that value is used in memory address.
Node* base;
Node* index;
const MachOper* oper = mach->memory_inputs(base, index);
if (oper == NULL || oper == (MachOper*)-1) {
continue; // Not an memory op; skip it
--- 151,162 ----
continue;
default: // Also check for embedded loads
if( !mach->needs_anti_dependence_check() )
continue; // Not an memory op; skip it
{
! // Check that value is used in memory address in
! // instructions with embedded load (CmpP val1,(val2+off)).
Node* base;
Node* index;
const MachOper* oper = mach->memory_inputs(base, index);
if (oper == NULL || oper == (MachOper*)-1) {
continue; // Not an memory op; skip it
*** 211,221 ****
// Found a memory user; see if it can be hoisted to check-block
uint vidx = 0; // Capture index of value into memop
uint j;
for( j = mach->req()-1; j > 0; j-- ) {
! if( mach->in(j) == val ) vidx = j;
// Block of memory-op input
Block *inb = cfg->_bbs[mach->in(j)->_idx];
Block *b = this; // Start from nul check
while( b != inb && b->_dom_depth > inb->_dom_depth )
b = b->_idom; // search upwards for input
--- 217,231 ----
// Found a memory user; see if it can be hoisted to check-block
uint vidx = 0; // Capture index of value into memop
uint j;
for( j = mach->req()-1; j > 0; j-- ) {
! if( mach->in(j) == val ) {
! vidx = j;
! // Ignore DecodeN val since it could be hoisted to where needed.
! if( is_decoden ) continue;
! }
// Block of memory-op input
Block *inb = cfg->_bbs[mach->in(j)->_idx];
Block *b = this; // Start from nul check
while( b != inb && b->_dom_depth > inb->_dom_depth )
b = b->_idom; // search upwards for input
*** 269,278 ****
--- 279,297 ----
// ---- Found an implicit null check
extern int implicit_null_checks;
implicit_null_checks++;
// Hoist the memory candidate up to the end of the test block.
+ if( is_decoden ) {
+ // Check if we need to hoist DecodeN val first.
+ Block *valb = cfg->_bbs[val->_idx];
+ if( this != valb && this->_dom_depth < valb->_dom_depth ) {
+ valb->find_remove(val);
+ this->add_inst(val);
+ cfg->_bbs.map(val->_idx,this);
+ }
+ }
Block *old_block = cfg->_bbs[best->_idx];
old_block->find_remove(best);
add_inst(best);
cfg->_bbs.map(best->_idx,this);
src/share/vm/opto/lcm.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File