Mercurial > hg > truffle
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); |