src/share/vm/opto/lcm.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File
*** old/src/share/vm/opto/lcm.cpp	Thu May 20 16:56:57 2010
--- new/src/share/vm/opto/lcm.cpp	Thu May 20 16:56:57 2010

*** 30,40 **** --- 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. ! // 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 **** --- 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. ! // 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 **** --- 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; ! 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