Mercurial > hg > truffle
diff src/share/vm/opto/lcm.cpp @ 1579:e9ff18c4ace7
Merge
author | jrose |
---|---|
date | Wed, 02 Jun 2010 22:45:42 -0700 |
parents | c18cbe5936b8 3657cb01ffc5 |
children | 0e35fa8ebccd |
line wrap: on
line diff
--- a/src/share/vm/opto/lcm.cpp Tue Jun 01 11:48:33 2010 -0700 +++ b/src/share/vm/opto/lcm.cpp Wed Jun 02 22:45:42 2010 -0700 @@ -32,7 +32,8 @@ // 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 @@ -96,6 +97,13 @@ } } + // Check for decodeHeapOop_not_null node which did not fold into address + bool is_decoden = ((intptr_t)val) & 1; + val = (Node*)(((intptr_t)val) & ~1); + + assert(!is_decoden || (val->in(0) == NULL) && val->is_Mach() && + (val->as_Mach()->ideal_Opcode() == Op_DecodeN), "sanity"); + // 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()); @@ -148,7 +156,8 @@ 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); @@ -213,7 +222,11 @@ 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 which 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 @@ -270,6 +283,26 @@ extern int implicit_null_checks; implicit_null_checks++; + if( is_decoden ) { + // Check if we need to hoist decodeHeapOop_not_null first. + Block *valb = cfg->_bbs[val->_idx]; + if( this != valb && this->_dom_depth < valb->_dom_depth ) { + // Hoist it up to the end of the test block. + valb->find_remove(val); + this->add_inst(val); + cfg->_bbs.map(val->_idx,this); + // DecodeN on x86 may kill flags. Check for flag-killing projections + // that also need to be hoisted. + for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) { + Node* n = val->fast_out(j); + if( n->Opcode() == Op_MachProj ) { + cfg->_bbs[n->_idx]->find_remove(n); + this->add_inst(n); + cfg->_bbs.map(n->_idx,this); + } + } + } + } // Hoist the memory candidate up to the end of the test block. Block *old_block = cfg->_bbs[best->_idx]; old_block->find_remove(best);