mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-16 09:04:41 +02:00
6984979: OptimizeFill misses some cases with an odd memory graph
Reviewed-by: kvn
This commit is contained in:
parent
5e98ce13ab
commit
2e4e2602d7
1 changed files with 12 additions and 1 deletions
|
@ -2447,6 +2447,13 @@ bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& st
|
||||||
msg_node = store->in(MemNode::Address);
|
msg_node = store->in(MemNode::Address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (msg == NULL &&
|
||||||
|
(!store->in(MemNode::Memory)->is_Phi() ||
|
||||||
|
store->in(MemNode::Memory)->in(LoopNode::LoopBackControl) != store)) {
|
||||||
|
msg = "store memory isn't proper phi";
|
||||||
|
msg_node = store->in(MemNode::Memory);
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure there is an appropriate fill routine
|
// Make sure there is an appropriate fill routine
|
||||||
BasicType t = store->as_Mem()->memory_type();
|
BasicType t = store->as_Mem()->memory_type();
|
||||||
const char* fill_name;
|
const char* fill_name;
|
||||||
|
@ -2570,7 +2577,7 @@ bool PhaseIdealLoop::match_fill_loop(IdealLoopTree* lpt, Node*& store, Node*& st
|
||||||
Node* n = lpt->_body.at(i);
|
Node* n = lpt->_body.at(i);
|
||||||
// These values can be replaced with other nodes if they are used
|
// These values can be replaced with other nodes if they are used
|
||||||
// outside the loop.
|
// outside the loop.
|
||||||
if (n == store || n == head->loopexit() || n == head->incr()) continue;
|
if (n == store || n == head->loopexit() || n == head->incr() || n == store->in(MemNode::Memory)) continue;
|
||||||
for (SimpleDUIterator iter(n); iter.has_next(); iter.next()) {
|
for (SimpleDUIterator iter(n); iter.has_next(); iter.next()) {
|
||||||
Node* use = iter.get();
|
Node* use = iter.get();
|
||||||
if (!lpt->_body.contains(use)) {
|
if (!lpt->_body.contains(use)) {
|
||||||
|
@ -2715,6 +2722,10 @@ bool PhaseIdealLoop::intrinsify_fill(IdealLoopTree* lpt) {
|
||||||
|
|
||||||
// Redirect the old control and memory edges that are outside the loop.
|
// Redirect the old control and memory edges that are outside the loop.
|
||||||
Node* exit = head->loopexit()->proj_out(0);
|
Node* exit = head->loopexit()->proj_out(0);
|
||||||
|
// Sometimes the memory phi of the head is used as the outgoing
|
||||||
|
// state of the loop. It's safe in this case to replace it with the
|
||||||
|
// result_mem.
|
||||||
|
_igvn.replace_node(store->in(MemNode::Memory), result_mem);
|
||||||
_igvn.replace_node(exit, result_ctrl);
|
_igvn.replace_node(exit, result_ctrl);
|
||||||
_igvn.replace_node(store, result_mem);
|
_igvn.replace_node(store, result_mem);
|
||||||
// Any uses the increment outside of the loop become the loop limit.
|
// Any uses the increment outside of the loop become the loop limit.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue