15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25 // Optimization - Graph Style
26
27 #include "incls/_precompiled.incl"
28 #include "incls/_lcm.cpp.incl"
29
30 //------------------------------implicit_null_check----------------------------
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.
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.
35 // The val is the pointer being checked for nullness.
36 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 // 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 if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return;
41
42 // Make sure the ptr-is-null path appears to be uncommon!
43 float f = end()->as_MachIf()->_prob;
44 if( proj->Opcode() == Op_IfTrue ) f = 1.0f - f;
45 if( f > PROB_UNLIKELY_MAG(4) ) return;
46
47 uint bidx = 0; // Capture index of value into memop
48 bool was_store; // Memory op is a store op
49
50 // Get the successor block for if the test ptr is non-null
51 Block* not_null_block; // this one goes with the proj
52 Block* null_block;
53 if (_nodes[_nodes.size()-1] == proj) {
54 null_block = _succs[0];
55 not_null_block = _succs[1];
79 Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(tr_con);
80 Deoptimization::DeoptAction action = Deoptimization::trap_request_action(tr_con);
81 assert((int)reason < (int)BitsPerInt, "recode bit map");
82 if (is_set_nth_bit(allowed_reasons, (int) reason)
83 && action != Deoptimization::Action_none) {
84 // This uncommon trap is sure to recompile, eventually.
85 // When that happens, C->too_many_traps will prevent
86 // this transformation from happening again.
87 found_trap = true;
88 }
89 }
90 break;
91 }
92 }
93 if (!found_trap) {
94 // We did not find an uncommon trap.
95 return;
96 }
97 }
98
99 // Search the successor block for a load or store who's base value is also
100 // the tested value. There may be several.
101 Node_List *out = new Node_List(Thread::current()->resource_area());
102 MachNode *best = NULL; // Best found so far
103 for (DUIterator i = val->outs(); val->has_out(i); i++) {
104 Node *m = val->out(i);
105 if( !m->is_Mach() ) continue;
106 MachNode *mach = m->as_Mach();
107 was_store = false;
108 switch( mach->ideal_Opcode() ) {
109 case Op_LoadB:
110 case Op_LoadUS:
111 case Op_LoadD:
112 case Op_LoadF:
113 case Op_LoadI:
114 case Op_LoadL:
115 case Op_LoadP:
116 case Op_LoadN:
117 case Op_LoadS:
118 case Op_LoadKlass:
131 case Op_StoreL:
132 case Op_StoreP:
133 case Op_StoreN:
134 was_store = true; // Memory op is a store op
135 // Stores will have their address in slot 2 (memory in slot 1).
136 // If the value being nul-checked is in another slot, it means we
137 // are storing the checked value, which does NOT check the value!
138 if( mach->in(2) != val ) continue;
139 break; // Found a memory op?
140 case Op_StrComp:
141 case Op_StrEquals:
142 case Op_StrIndexOf:
143 case Op_AryEq:
144 // Not a legit memory op for implicit null check regardless of
145 // embedded loads
146 continue;
147 default: // Also check for embedded loads
148 if( !mach->needs_anti_dependence_check() )
149 continue; // Not an memory op; skip it
150 {
151 // Check that value is used in memory address.
152 Node* base;
153 Node* index;
154 const MachOper* oper = mach->memory_inputs(base, index);
155 if (oper == NULL || oper == (MachOper*)-1) {
156 continue; // Not an memory op; skip it
157 }
158 if (val == base ||
159 val == index && val->bottom_type()->isa_narrowoop()) {
160 break; // Found it
161 } else {
162 continue; // Skip it
163 }
164 }
165 break;
166 }
167 // check if the offset is not too high for implicit exception
168 {
169 intptr_t offset = 0;
170 const TypePtr *adr_type = NULL; // Do not need this return value here
171 const Node* base = mach->get_base_and_disp(offset, adr_type);
196 // Check ctrl input to see if the null-check dominates the memory op
197 Block *cb = cfg->_bbs[mach->_idx];
198 cb = cb->_idom; // Always hoist at least 1 block
199 if( !was_store ) { // Stores can be hoisted only one block
200 while( cb->_dom_depth > (_dom_depth + 1))
201 cb = cb->_idom; // Hoist loads as far as we want
202 // The non-null-block should dominate the memory op, too. Live
203 // range spilling will insert a spill in the non-null-block if it is
204 // needs to spill the memory op for an implicit null check.
205 if (cb->_dom_depth == (_dom_depth + 1)) {
206 if (cb != not_null_block) continue;
207 cb = cb->_idom;
208 }
209 }
210 if( cb != this ) continue;
211
212 // Found a memory user; see if it can be hoisted to check-block
213 uint vidx = 0; // Capture index of value into memop
214 uint j;
215 for( j = mach->req()-1; j > 0; j-- ) {
216 if( mach->in(j) == val ) vidx = j;
217 // Block of memory-op input
218 Block *inb = cfg->_bbs[mach->in(j)->_idx];
219 Block *b = this; // Start from nul check
220 while( b != inb && b->_dom_depth > inb->_dom_depth )
221 b = b->_idom; // search upwards for input
222 // See if input dominates null check
223 if( b != inb )
224 break;
225 }
226 if( j > 0 )
227 continue;
228 Block *mb = cfg->_bbs[mach->_idx];
229 // Hoisting stores requires more checks for the anti-dependence case.
230 // Give up hoisting if we have to move the store past any load.
231 if( was_store ) {
232 Block *b = mb; // Start searching here for a local load
233 // mach use (faulting) trying to hoist
234 // n might be blocker to hoisting
235 while( b != this ) {
236 uint k;
254 if( e->is_MachNullCheck() && e->in(1) == mach )
255 continue; // Already being used as a NULL check
256
257 // Found a candidate! Pick one with least dom depth - the highest
258 // in the dom tree should be closest to the null check.
259 if( !best ||
260 cfg->_bbs[mach->_idx]->_dom_depth < cfg->_bbs[best->_idx]->_dom_depth ) {
261 best = mach;
262 bidx = vidx;
263
264 }
265 }
266 // No candidate!
267 if( !best ) return;
268
269 // ---- Found an implicit null check
270 extern int implicit_null_checks;
271 implicit_null_checks++;
272
273 // Hoist the memory candidate up to the end of the test block.
274 Block *old_block = cfg->_bbs[best->_idx];
275 old_block->find_remove(best);
276 add_inst(best);
277 cfg->_bbs.map(best->_idx,this);
278
279 // Move the control dependence
280 if (best->in(0) && best->in(0) == old_block->_nodes[0])
281 best->set_req(0, _nodes[0]);
282
283 // Check for flag-killing projections that also need to be hoisted
284 // Should be DU safe because no edge updates.
285 for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) {
286 Node* n = best->fast_out(j);
287 if( n->Opcode() == Op_MachProj ) {
288 cfg->_bbs[n->_idx]->find_remove(n);
289 add_inst(n);
290 cfg->_bbs.map(n->_idx,this);
291 }
292 }
293
|
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
20 * CA 95054 USA or visit www.sun.com if you need additional information or
21 * have any questions.
22 *
23 */
24
25 // Optimization - Graph Style
26
27 #include "incls/_precompiled.incl"
28 #include "incls/_lcm.cpp.incl"
29
30 //------------------------------implicit_null_check----------------------------
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.
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.
35 // The val is the pointer being checked for nullness or
36 // decodeHeapOop_not_null node if it did not fold into address.
37 void Block::implicit_null_check(PhaseCFG *cfg, Node *proj, Node *val, int allowed_reasons) {
38 // Assume if null check need for 0 offset then always needed
39 // Intel solaris doesn't support any null checks yet and no
40 // mechanism exists (yet) to set the switches at an os_cpu level
41 if( !ImplicitNullChecks || MacroAssembler::needs_explicit_null_check(0)) return;
42
43 // Make sure the ptr-is-null path appears to be uncommon!
44 float f = end()->as_MachIf()->_prob;
45 if( proj->Opcode() == Op_IfTrue ) f = 1.0f - f;
46 if( f > PROB_UNLIKELY_MAG(4) ) return;
47
48 uint bidx = 0; // Capture index of value into memop
49 bool was_store; // Memory op is a store op
50
51 // Get the successor block for if the test ptr is non-null
52 Block* not_null_block; // this one goes with the proj
53 Block* null_block;
54 if (_nodes[_nodes.size()-1] == proj) {
55 null_block = _succs[0];
56 not_null_block = _succs[1];
80 Deoptimization::DeoptReason reason = Deoptimization::trap_request_reason(tr_con);
81 Deoptimization::DeoptAction action = Deoptimization::trap_request_action(tr_con);
82 assert((int)reason < (int)BitsPerInt, "recode bit map");
83 if (is_set_nth_bit(allowed_reasons, (int) reason)
84 && action != Deoptimization::Action_none) {
85 // This uncommon trap is sure to recompile, eventually.
86 // When that happens, C->too_many_traps will prevent
87 // this transformation from happening again.
88 found_trap = true;
89 }
90 }
91 break;
92 }
93 }
94 if (!found_trap) {
95 // We did not find an uncommon trap.
96 return;
97 }
98 }
99
100 // Check for decodeHeapOop_not_null node which did not fold into address.
101 bool is_decoden = val->is_Mach() &&
102 (val->as_Mach()->ideal_Opcode() == Op_DecodeN);
103
104 // Search the successor block for a load or store who's base value is also
105 // the tested value. There may be several.
106 Node_List *out = new Node_List(Thread::current()->resource_area());
107 MachNode *best = NULL; // Best found so far
108 for (DUIterator i = val->outs(); val->has_out(i); i++) {
109 Node *m = val->out(i);
110 if( !m->is_Mach() ) continue;
111 MachNode *mach = m->as_Mach();
112 was_store = false;
113 switch( mach->ideal_Opcode() ) {
114 case Op_LoadB:
115 case Op_LoadUS:
116 case Op_LoadD:
117 case Op_LoadF:
118 case Op_LoadI:
119 case Op_LoadL:
120 case Op_LoadP:
121 case Op_LoadN:
122 case Op_LoadS:
123 case Op_LoadKlass:
136 case Op_StoreL:
137 case Op_StoreP:
138 case Op_StoreN:
139 was_store = true; // Memory op is a store op
140 // Stores will have their address in slot 2 (memory in slot 1).
141 // If the value being nul-checked is in another slot, it means we
142 // are storing the checked value, which does NOT check the value!
143 if( mach->in(2) != val ) continue;
144 break; // Found a memory op?
145 case Op_StrComp:
146 case Op_StrEquals:
147 case Op_StrIndexOf:
148 case Op_AryEq:
149 // Not a legit memory op for implicit null check regardless of
150 // embedded loads
151 continue;
152 default: // Also check for embedded loads
153 if( !mach->needs_anti_dependence_check() )
154 continue; // Not an memory op; skip it
155 {
156 // Check that value is used in memory address in
157 // instructions with embedded load (CmpP val1,(val2+off)).
158 Node* base;
159 Node* index;
160 const MachOper* oper = mach->memory_inputs(base, index);
161 if (oper == NULL || oper == (MachOper*)-1) {
162 continue; // Not an memory op; skip it
163 }
164 if (val == base ||
165 val == index && val->bottom_type()->isa_narrowoop()) {
166 break; // Found it
167 } else {
168 continue; // Skip it
169 }
170 }
171 break;
172 }
173 // check if the offset is not too high for implicit exception
174 {
175 intptr_t offset = 0;
176 const TypePtr *adr_type = NULL; // Do not need this return value here
177 const Node* base = mach->get_base_and_disp(offset, adr_type);
202 // Check ctrl input to see if the null-check dominates the memory op
203 Block *cb = cfg->_bbs[mach->_idx];
204 cb = cb->_idom; // Always hoist at least 1 block
205 if( !was_store ) { // Stores can be hoisted only one block
206 while( cb->_dom_depth > (_dom_depth + 1))
207 cb = cb->_idom; // Hoist loads as far as we want
208 // The non-null-block should dominate the memory op, too. Live
209 // range spilling will insert a spill in the non-null-block if it is
210 // needs to spill the memory op for an implicit null check.
211 if (cb->_dom_depth == (_dom_depth + 1)) {
212 if (cb != not_null_block) continue;
213 cb = cb->_idom;
214 }
215 }
216 if( cb != this ) continue;
217
218 // Found a memory user; see if it can be hoisted to check-block
219 uint vidx = 0; // Capture index of value into memop
220 uint j;
221 for( j = mach->req()-1; j > 0; j-- ) {
222 if( mach->in(j) == val ) {
223 vidx = j;
224 // Ignore DecodeN val since it could be hoisted to where needed.
225 if( is_decoden ) continue;
226 }
227 // Block of memory-op input
228 Block *inb = cfg->_bbs[mach->in(j)->_idx];
229 Block *b = this; // Start from nul check
230 while( b != inb && b->_dom_depth > inb->_dom_depth )
231 b = b->_idom; // search upwards for input
232 // See if input dominates null check
233 if( b != inb )
234 break;
235 }
236 if( j > 0 )
237 continue;
238 Block *mb = cfg->_bbs[mach->_idx];
239 // Hoisting stores requires more checks for the anti-dependence case.
240 // Give up hoisting if we have to move the store past any load.
241 if( was_store ) {
242 Block *b = mb; // Start searching here for a local load
243 // mach use (faulting) trying to hoist
244 // n might be blocker to hoisting
245 while( b != this ) {
246 uint k;
264 if( e->is_MachNullCheck() && e->in(1) == mach )
265 continue; // Already being used as a NULL check
266
267 // Found a candidate! Pick one with least dom depth - the highest
268 // in the dom tree should be closest to the null check.
269 if( !best ||
270 cfg->_bbs[mach->_idx]->_dom_depth < cfg->_bbs[best->_idx]->_dom_depth ) {
271 best = mach;
272 bidx = vidx;
273
274 }
275 }
276 // No candidate!
277 if( !best ) return;
278
279 // ---- Found an implicit null check
280 extern int implicit_null_checks;
281 implicit_null_checks++;
282
283 // Hoist the memory candidate up to the end of the test block.
284 if( is_decoden ) {
285 // Check if we need to hoist DecodeN val first.
286 Block *valb = cfg->_bbs[val->_idx];
287 if( this != valb && this->_dom_depth < valb->_dom_depth ) {
288 valb->find_remove(val);
289 this->add_inst(val);
290 cfg->_bbs.map(val->_idx,this);
291 }
292 }
293 Block *old_block = cfg->_bbs[best->_idx];
294 old_block->find_remove(best);
295 add_inst(best);
296 cfg->_bbs.map(best->_idx,this);
297
298 // Move the control dependence
299 if (best->in(0) && best->in(0) == old_block->_nodes[0])
300 best->set_req(0, _nodes[0]);
301
302 // Check for flag-killing projections that also need to be hoisted
303 // Should be DU safe because no edge updates.
304 for (DUIterator_Fast jmax, j = best->fast_outs(jmax); j < jmax; j++) {
305 Node* n = best->fast_out(j);
306 if( n->Opcode() == Op_MachProj ) {
307 cfg->_bbs[n->_idx]->find_remove(n);
308 add_inst(n);
309 cfg->_bbs.map(n->_idx,this);
310 }
311 }
312
|