comparison 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
comparison
equal deleted inserted replaced
1562:dfe27f03244a 1579:e9ff18c4ace7
30 //------------------------------implicit_null_check---------------------------- 30 //------------------------------implicit_null_check----------------------------
31 // Detect implicit-null-check opportunities. Basically, find NULL checks 31 // Detect implicit-null-check opportunities. Basically, find NULL checks
32 // with suitable memory ops nearby. Use the memory op to do the NULL check. 32 // with suitable memory ops nearby. Use the memory op to do the NULL check.
33 // I can generate a memory op if there is not one nearby. 33 // I can generate a memory op if there is not one nearby.
34 // The proj is the control projection for the not-null case. 34 // The proj is the control projection for the not-null case.
35 // The val is the pointer being checked for nullness. 35 // The val is the pointer being checked for nullness or
36 // decodeHeapOop_not_null node if it did not fold into address.
36 void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) { 37 void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) {
37 // Assume if null check need for 0 offset then always needed 38 // Assume if null check need for 0 offset then always needed
38 // Intel solaris doesn't support any null checks yet and no 39 // Intel solaris doesn't support any null checks yet and no
39 // mechanism exists (yet) to set the switches at an os_cpu level 40 // mechanism exists (yet) to set the switches at an os_cpu level
40 if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return; 41 if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return;
93 if (!found_trap) { 94 if (!found_trap) {
94 // We did not find an uncommon trap. 95 // We did not find an uncommon trap.
95 return; 96 return;
96 } 97 }
97 } 98 }
99
100 // Check for decodeHeapOop_not_null node which did not fold into address
101 bool is_decoden = ((intptr_t)val) & 1;
102 val = (Node*)(((intptr_t)val) & ~1);
103
104 assert(!is_decoden || (val->in(0) == NULL) && val->is_Mach() &&
105 (val->as_Mach()->ideal_Opcode() == Op_DecodeN), "sanity");
98 106
99 // Search the successor block for a load or store who's base value is also 107 // Search the successor block for a load or store who's base value is also
100 // the tested value. There may be several. 108 // the tested value. There may be several.
101 Node_List *out = new Node_List(Thread::current()->resource_area()); 109 Node_List *out = new Node_List(Thread::current()->resource_area());
102 MachNode *best = NULL; // Best found so far 110 MachNode *best = NULL; // Best found so far
146 continue; 154 continue;
147 default: // Also check for embedded loads 155 default: // Also check for embedded loads
148 if( !mach->needs_anti_dependence_check() ) 156 if( !mach->needs_anti_dependence_check() )
149 continue; // Not an memory op; skip it 157 continue; // Not an memory op; skip it
150 { 158 {
151 // Check that value is used in memory address. 159 // Check that value is used in memory address in
160 // instructions with embedded load (CmpP val1,(val2+off)).
152 Node* base; 161 Node* base;
153 Node* index; 162 Node* index;
154 const MachOper* oper = mach->memory_inputs(base, index); 163 const MachOper* oper = mach->memory_inputs(base, index);
155 if (oper == NULL || oper == (MachOper*)-1) { 164 if (oper == NULL || oper == (MachOper*)-1) {
156 continue; // Not an memory op; skip it 165 continue; // Not an memory op; skip it
211 220
212 // Found a memory user; see if it can be hoisted to check-block 221 // Found a memory user; see if it can be hoisted to check-block
213 uint vidx = 0; // Capture index of value into memop 222 uint vidx = 0; // Capture index of value into memop
214 uint j; 223 uint j;
215 for( j = mach->req()-1; j > 0; j-- ) { 224 for( j = mach->req()-1; j > 0; j-- ) {
216 if( mach->in(j) == val ) vidx = j; 225 if( mach->in(j) == val ) {
226 vidx = j;
227 // Ignore DecodeN val which could be hoisted to where needed.
228 if( is_decoden ) continue;
229 }
217 // Block of memory-op input 230 // Block of memory-op input
218 Block *inb = cfg->_bbs[mach->in(j)->_idx]; 231 Block *inb = cfg->_bbs[mach->in(j)->_idx];
219 Block *b = this; // Start from nul check 232 Block *b = this; // Start from nul check
220 while( b != inb && b->_dom_depth > inb->_dom_depth ) 233 while( b != inb && b->_dom_depth > inb->_dom_depth )
221 b = b->_idom; // search upwards for input 234 b = b->_idom; // search upwards for input
268 281
269 // ---- Found an implicit null check 282 // ---- Found an implicit null check
270 extern int implicit_null_checks; 283 extern int implicit_null_checks;
271 implicit_null_checks++; 284 implicit_null_checks++;
272 285
286 if( is_decoden ) {
287 // Check if we need to hoist decodeHeapOop_not_null first.
288 Block *valb = cfg->_bbs[val->_idx];
289 if( this != valb && this->_dom_depth < valb->_dom_depth ) {
290 // Hoist it up to the end of the test block.
291 valb->find_remove(val);
292 this->add_inst(val);
293 cfg->_bbs.map(val->_idx,this);
294 // DecodeN on x86 may kill flags. Check for flag-killing projections
295 // that also need to be hoisted.
296 for (DUIterator_Fast jmax, j = val->fast_outs(jmax); j < jmax; j++) {
297 Node* n = val->fast_out(j);
298 if( n->Opcode() == Op_MachProj ) {
299 cfg->_bbs[n->_idx]->find_remove(n);
300 this->add_inst(n);
301 cfg->_bbs.map(n->_idx,this);
302 }
303 }
304 }
305 }
273 // Hoist the memory candidate up to the end of the test block. 306 // Hoist the memory candidate up to the end of the test block.
274 Block *old_block = cfg->_bbs[best->_idx]; 307 Block *old_block = cfg->_bbs[best->_idx];
275 old_block->find_remove(best); 308 old_block->find_remove(best);
276 add_inst(best); 309 add_inst(best);
277 cfg->_bbs.map(best->_idx,this); 310 cfg->_bbs.map(best->_idx,this);