< prev index next >
src/hotspot/share/opto/superword.cpp
Print this page
*** 2137,2157 ****
} else if (pk->at(0)->is_Load()) { //load
// all loads in the pack should have the same memory state. By default,
// we use the memory state of the last load. However, if any load could
// not be moved down due to the dependence constraint, we use the memory
// state of the first load.
! Node* last_mem = executed_last(pk)->in(MemNode::Memory);
! Node* first_mem = executed_first(pk)->in(MemNode::Memory);
bool schedule_last = true;
for (uint i = 0; i < pk->size(); i++) {
Node* ld = pk->at(i);
! for (Node* current = last_mem; current != ld->in(MemNode::Memory);
! current=current->in(MemNode::Memory)) {
! assert(current != first_mem, "corrupted memory graph");
! if(current->is_Mem() && !independent(current, ld)){
schedule_last = false; // a later store depends on this load
- break;
}
}
}
Node* mem_input = schedule_last ? last_mem : first_mem;
--- 2137,2181 ----
} else if (pk->at(0)->is_Load()) { //load
// all loads in the pack should have the same memory state. By default,
// we use the memory state of the last load. However, if any load could
// not be moved down due to the dependence constraint, we use the memory
// state of the first load.
!
! // We first need to find the "first" and "last" loads. Start with
! // arbitrary values:
! Node* last_mem = pk->at(0)->in(MemNode::Memory);
! Node* first_mem = last_mem;
! // Walk the memory graph from the current first load until the
! // start of the loop and check if nodes on the way are memory
! // edges of loads in the pack. The last one we encounter is the
! // first load.
! for (Node* current = first_mem; in_bb(current); current = current->is_Phi() ? current->in(LoopNode::EntryControl) : current->in(MemNode::Memory)) {
! assert(current->is_Mem() || (current->is_Phi() && current->in(0) == bb()), "unexpected memory");
! for (uint i = 1; i < pk->size(); i++) {
! Node* ld = pk->at(i);
! if (ld->in(MemNode::Memory) == current) {
! first_mem = current;
! break;
! }
! }
! }
! // Find the last load by going over the pack again, and walking
! // the memory graph from the loads of the pack to the memory of
! // the first load. If we encounter the memory of the current last
! // load, then we started from further down in the memory graph and
! // the load we started from is the last load. Check for dependence
! // constraints in that loop as well.
bool schedule_last = true;
for (uint i = 0; i < pk->size(); i++) {
Node* ld = pk->at(i);
! for (Node* current = ld->in(MemNode::Memory); current != first_mem; current = current->in(MemNode::Memory)) {
! assert(current->is_Mem() && in_bb(current), "unexpected memory");
! if (current->in(MemNode::Memory) == last_mem) {
! last_mem = ld->in(MemNode::Memory);
! }
! if (!independent(current, ld)) {
schedule_last = false; // a later store depends on this load
}
}
}
Node* mem_input = schedule_last ? last_mem : first_mem;
< prev index next >