Mercurial > hg > graal-compiler
comparison src/share/vm/opto/loopTransform.cpp @ 1813:c77e8f982901
6984979: OptimizeFill misses some cases with an odd memory graph
Reviewed-by: kvn
author | never |
---|---|
date | Wed, 15 Sep 2010 20:25:37 -0700 |
parents | 5e4f03302987 |
children | 75588558f1bf |
comparison
equal
deleted
inserted
replaced
1796:18c378513575 | 1813:c77e8f982901 |
---|---|
2445 if (msg == NULL && !store->in(MemNode::Address)->is_AddP()) { | 2445 if (msg == NULL && !store->in(MemNode::Address)->is_AddP()) { |
2446 msg = "can't handle store address"; | 2446 msg = "can't handle store address"; |
2447 msg_node = store->in(MemNode::Address); | 2447 msg_node = store->in(MemNode::Address); |
2448 } | 2448 } |
2449 | 2449 |
2450 if (msg == NULL && | |
2451 (!store->in(MemNode::Memory)->is_Phi() || | |
2452 store->in(MemNode::Memory)->in(LoopNode::LoopBackControl) != store)) { | |
2453 msg = "store memory isn't proper phi"; | |
2454 msg_node = store->in(MemNode::Memory); | |
2455 } | |
2456 | |
2450 // Make sure there is an appropriate fill routine | 2457 // Make sure there is an appropriate fill routine |
2451 BasicType t = store->as_Mem()->memory_type(); | 2458 BasicType t = store->as_Mem()->memory_type(); |
2452 const char* fill_name; | 2459 const char* fill_name; |
2453 if (msg == NULL && | 2460 if (msg == NULL && |
2454 StubRoutines::select_fill_function(t, false, fill_name) == NULL) { | 2461 StubRoutines::select_fill_function(t, false, fill_name) == NULL) { |
2568 // Make sure no unexpected values are used outside the loop | 2575 // Make sure no unexpected values are used outside the loop |
2569 for (uint i = 0; msg == NULL && i < lpt->_body.size(); i++) { | 2576 for (uint i = 0; msg == NULL && i < lpt->_body.size(); i++) { |
2570 Node* n = lpt->_body.at(i); | 2577 Node* n = lpt->_body.at(i); |
2571 // These values can be replaced with other nodes if they are used | 2578 // These values can be replaced with other nodes if they are used |
2572 // outside the loop. | 2579 // outside the loop. |
2573 if (n == store || n == head->loopexit() || n == head->incr()) continue; | 2580 if (n == store || n == head->loopexit() || n == head->incr() || n == store->in(MemNode::Memory)) continue; |
2574 for (SimpleDUIterator iter(n); iter.has_next(); iter.next()) { | 2581 for (SimpleDUIterator iter(n); iter.has_next(); iter.next()) { |
2575 Node* use = iter.get(); | 2582 Node* use = iter.get(); |
2576 if (!lpt->_body.contains(use)) { | 2583 if (!lpt->_body.contains(use)) { |
2577 msg = "node is used outside loop"; | 2584 msg = "node is used outside loop"; |
2578 // lpt->_body.dump(); | 2585 // lpt->_body.dump(); |
2713 } | 2720 } |
2714 } | 2721 } |
2715 | 2722 |
2716 // Redirect the old control and memory edges that are outside the loop. | 2723 // Redirect the old control and memory edges that are outside the loop. |
2717 Node* exit = head->loopexit()->proj_out(0); | 2724 Node* exit = head->loopexit()->proj_out(0); |
2725 // Sometimes the memory phi of the head is used as the outgoing | |
2726 // state of the loop. It's safe in this case to replace it with the | |
2727 // result_mem. | |
2728 _igvn.replace_node(store->in(MemNode::Memory), result_mem); | |
2718 _igvn.replace_node(exit, result_ctrl); | 2729 _igvn.replace_node(exit, result_ctrl); |
2719 _igvn.replace_node(store, result_mem); | 2730 _igvn.replace_node(store, result_mem); |
2720 // Any uses the increment outside of the loop become the loop limit. | 2731 // Any uses the increment outside of the loop become the loop limit. |
2721 _igvn.replace_node(head->incr(), head->limit()); | 2732 _igvn.replace_node(head->incr(), head->limit()); |
2722 | 2733 |