Mercurial > hg > graal-compiler
comparison src/share/vm/opto/memnode.cpp @ 85:f3b3fe64f59f
6692301: Side effect in NumberFormat tests with -server -Xcomp
Summary: Optimization in CmpPNode::sub() removed the valid compare instruction because of false positive answer from detect_dominating_control().
Reviewed-by: jrose, sgoldman
author | kvn |
---|---|
date | Tue, 15 Apr 2008 10:49:32 -0700 |
parents | de93acbb64fc |
children | ec73d88d5b43 |
comparison
equal
deleted
inserted
replaced
84:6e085831cad7 | 85:f3b3fe64f59f |
---|---|
239 // let the subclass continue analyzing... | 239 // let the subclass continue analyzing... |
240 return NULL; | 240 return NULL; |
241 } | 241 } |
242 | 242 |
243 // Helper function for proving some simple control dominations. | 243 // Helper function for proving some simple control dominations. |
244 // Attempt to prove that control input 'dom' dominates (or equals) 'sub'. | 244 // Attempt to prove that all control inputs of 'dom' dominate 'sub'. |
245 // Already assumes that 'dom' is available at 'sub', and that 'sub' | 245 // Already assumes that 'dom' is available at 'sub', and that 'sub' |
246 // is not a constant (dominated by the method's StartNode). | 246 // is not a constant (dominated by the method's StartNode). |
247 // Used by MemNode::find_previous_store to prove that the | 247 // Used by MemNode::find_previous_store to prove that the |
248 // control input of a memory operation predates (dominates) | 248 // control input of a memory operation predates (dominates) |
249 // an allocation it wants to look past. | 249 // an allocation it wants to look past. |
250 bool MemNode::detect_dominating_control(Node* dom, Node* sub) { | 250 bool MemNode::all_controls_dominate(Node* dom, Node* sub) { |
251 if (dom == NULL) return false; | 251 if (dom == NULL || dom->is_top() || sub == NULL || sub->is_top()) |
252 if (dom->is_Proj()) dom = dom->in(0); | 252 return false; // Conservative answer for dead code |
253 if (dom->is_Start()) return true; // anything inside the method | 253 |
254 if (dom->is_Root()) return true; // dom 'controls' a constant | 254 // Check 'dom'. |
255 int cnt = 20; // detect cycle or too much effort | 255 dom = dom->find_exact_control(dom); |
256 while (sub != NULL) { // walk 'sub' up the chain to 'dom' | 256 if (dom == NULL || dom->is_top()) |
257 if (--cnt < 0) return false; // in a cycle or too complex | 257 return false; // Conservative answer for dead code |
258 if (sub == dom) return true; | 258 |
259 if (sub->is_Start()) return false; | 259 if (dom->is_Start() || dom->is_Root() || dom == sub) |
260 if (sub->is_Root()) return false; | 260 return true; |
261 Node* up = sub->in(0); | 261 |
262 if (sub == up && sub->is_Region()) { | 262 // 'dom' dominates 'sub' if its control edge and control edges |
263 for (uint i = 1; i < sub->req(); i++) { | 263 // of all its inputs dominate or equal to sub's control edge. |
264 Node* in = sub->in(i); | 264 |
265 if (in != NULL && !in->is_top() && in != sub) { | 265 // Currently 'sub' is either Allocate, Initialize or Start nodes. |
266 up = in; break; // take any path on the way up to 'dom' | 266 assert(sub->is_Allocate() || sub->is_Initialize() || sub->is_Start(), "expecting only these nodes"); |
267 | |
268 // Get control edge of 'sub'. | |
269 sub = sub->find_exact_control(sub->in(0)); | |
270 if (sub == NULL || sub->is_top()) | |
271 return false; // Conservative answer for dead code | |
272 | |
273 assert(sub->is_CFG(), "expecting control"); | |
274 | |
275 if (sub == dom) | |
276 return true; | |
277 | |
278 if (sub->is_Start() || sub->is_Root()) | |
279 return false; | |
280 | |
281 { | |
282 // Check all control edges of 'dom'. | |
283 | |
284 ResourceMark rm; | |
285 Arena* arena = Thread::current()->resource_area(); | |
286 Node_List nlist(arena); | |
287 Unique_Node_List dom_list(arena); | |
288 | |
289 dom_list.push(dom); | |
290 bool only_dominating_controls = false; | |
291 | |
292 for (uint next = 0; next < dom_list.size(); next++) { | |
293 Node* n = dom_list.at(next); | |
294 if (!n->is_CFG() && n->pinned()) { | |
295 // Check only own control edge for pinned non-control nodes. | |
296 n = n->find_exact_control(n->in(0)); | |
297 if (n == NULL || n->is_top()) | |
298 return false; // Conservative answer for dead code | |
299 assert(n->is_CFG(), "expecting control"); | |
300 } | |
301 if (n->is_Start() || n->is_Root()) { | |
302 only_dominating_controls = true; | |
303 } else if (n->is_CFG()) { | |
304 if (n->dominates(sub, nlist)) | |
305 only_dominating_controls = true; | |
306 else | |
307 return false; | |
308 } else { | |
309 // First, own control edge. | |
310 Node* m = n->find_exact_control(n->in(0)); | |
311 if (m == NULL) | |
312 continue; | |
313 if (m->is_top()) | |
314 return false; // Conservative answer for dead code | |
315 dom_list.push(m); | |
316 | |
317 // Now, the rest of edges. | |
318 uint cnt = n->req(); | |
319 for (uint i = 1; i < cnt; i++) { | |
320 m = n->find_exact_control(n->in(i)); | |
321 if (m == NULL || m->is_top()) | |
322 continue; | |
323 dom_list.push(m); | |
267 } | 324 } |
268 } | 325 } |
269 } | 326 } |
270 if (sub == up) return false; // some kind of tight cycle | 327 return only_dominating_controls; |
271 sub = up; | 328 } |
272 } | |
273 return false; | |
274 } | 329 } |
275 | 330 |
276 //---------------------detect_ptr_independence--------------------------------- | 331 //---------------------detect_ptr_independence--------------------------------- |
277 // Used by MemNode::find_previous_store to prove that two base | 332 // Used by MemNode::find_previous_store to prove that two base |
278 // pointers are never equal. | 333 // pointers are never equal. |
289 return (p1 != p2) && p1->is_Con() && p2->is_Con(); | 344 return (p1 != p2) && p1->is_Con() && p2->is_Con(); |
290 } else if (a1 != NULL && a2 != NULL) { // both allocations | 345 } else if (a1 != NULL && a2 != NULL) { // both allocations |
291 return (a1 != a2); | 346 return (a1 != a2); |
292 } else if (a1 != NULL) { // one allocation a1 | 347 } else if (a1 != NULL) { // one allocation a1 |
293 // (Note: p2->is_Con implies p2->in(0)->is_Root, which dominates.) | 348 // (Note: p2->is_Con implies p2->in(0)->is_Root, which dominates.) |
294 return detect_dominating_control(p2->in(0), a1->in(0)); | 349 return all_controls_dominate(p2, a1); |
295 } else { //(a2 != NULL) // one allocation a2 | 350 } else { //(a2 != NULL) // one allocation a2 |
296 return detect_dominating_control(p1->in(0), a2->in(0)); | 351 return all_controls_dominate(p1, a2); |
297 } | 352 } |
298 return false; | 353 return false; |
299 } | 354 } |
300 | 355 |
301 | 356 |
377 bool known_independent = false; | 432 bool known_independent = false; |
378 if (alloc == st_alloc) | 433 if (alloc == st_alloc) |
379 known_identical = true; | 434 known_identical = true; |
380 else if (alloc != NULL) | 435 else if (alloc != NULL) |
381 known_independent = true; | 436 known_independent = true; |
382 else if (ctrl != NULL && | 437 else if (all_controls_dominate(this, st_alloc)) |
383 detect_dominating_control(ctrl, st_alloc->in(0))) | |
384 known_independent = true; | 438 known_independent = true; |
385 | 439 |
386 if (known_independent) { | 440 if (known_independent) { |
387 // The bases are provably independent: Either they are | 441 // The bases are provably independent: Either they are |
388 // manifestly distinct allocations, or else the control | 442 // manifestly distinct allocations, or else the control |
1066 if (in(MemNode::Control) != NULL) { | 1120 if (in(MemNode::Control) != NULL) { |
1067 intptr_t ignore = 0; | 1121 intptr_t ignore = 0; |
1068 Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore); | 1122 Node* base = AddPNode::Ideal_base_and_offset(address, phase, ignore); |
1069 if (base != NULL | 1123 if (base != NULL |
1070 && phase->type(base)->higher_equal(TypePtr::NOTNULL) | 1124 && phase->type(base)->higher_equal(TypePtr::NOTNULL) |
1071 && detect_dominating_control(base->in(0), phase->C->start())) { | 1125 && all_controls_dominate(base, phase->C->start())) { |
1072 // A method-invariant, non-null address (constant or 'this' argument). | 1126 // A method-invariant, non-null address (constant or 'this' argument). |
1073 set_req(MemNode::Control, NULL); | 1127 set_req(MemNode::Control, NULL); |
1074 } | 1128 } |
1075 } | 1129 } |
1076 | 1130 |
2487 // If we already know that the enclosing memory op is pinned right after | 2541 // If we already know that the enclosing memory op is pinned right after |
2488 // the init, then any control flow that the store has picked up | 2542 // the init, then any control flow that the store has picked up |
2489 // must have preceded the init, or else be equal to the init. | 2543 // must have preceded the init, or else be equal to the init. |
2490 // Even after loop optimizations (which might change control edges) | 2544 // Even after loop optimizations (which might change control edges) |
2491 // a store is never pinned *before* the availability of its inputs. | 2545 // a store is never pinned *before* the availability of its inputs. |
2492 if (!MemNode::detect_dominating_control(ctl, this->in(0))) | 2546 if (!MemNode::all_controls_dominate(n, this)) |
2493 return false; // failed to prove a good control | 2547 return false; // failed to prove a good control |
2494 | 2548 |
2495 } | 2549 } |
2496 | 2550 |
2497 // Check data edges for possible dependencies on 'this'. | 2551 // Check data edges for possible dependencies on 'this'. |