src/share/vm/opto/superword.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 6876276 Cdiff src/share/vm/opto/superword.cpp

src/share/vm/opto/superword.cpp

Print this page

        

*** 988,999 **** // (4) If there is no dependence restriction for a sandwiched memory op, we simply // schedule this store AFTER the pack // (5) We know there is no dependence cycle, so there in no other case; // (6) Finally, all memory ops in another single pack should be moved in the same direction. // ! // To schedule a load pack: the memory edge of every loads in the pack must be ! // the same as the memory edge of the last executed load in the pack void SuperWord::co_locate_pack(Node_List* pk) { if (pk->at(0)->is_Store()) { MemNode* first = executed_first(pk)->as_Mem(); MemNode* last = executed_last(pk)->as_Mem(); Unique_Node_List schedule_before_pack; --- 988,999 ---- // (4) If there is no dependence restriction for a sandwiched memory op, we simply // schedule this store AFTER the pack // (5) We know there is no dependence cycle, so there in no other case; // (6) Finally, all memory ops in another single pack should be moved in the same direction. // ! // To schedule a load pack, we use the memory state of either the first or the last load in ! // the pack, based on the dependence constraint. void SuperWord::co_locate_pack(Node_List* pk) { if (pk->at(0)->is_Store()) { MemNode* first = executed_first(pk)->as_Mem(); MemNode* last = executed_last(pk)->as_Mem(); Unique_Node_List schedule_before_pack;
*** 1074,1092 **** if (current == first) break; current = my_mem->as_Mem(); } // end while } else if (pk->at(0)->is_Load()) { //load ! // all use the memory state that the last executed load uses ! LoadNode* last_load = executed_last(pk)->as_Load(); ! Node* last_mem = last_load->in(MemNode::Memory); ! _igvn.hash_delete(last_mem); ! // Give each load same memory state as last for (uint i = 0; i < pk->size(); i++) { LoadNode* ld = pk->at(i)->as_Load(); _igvn.hash_delete(ld); ! ld->set_req(MemNode::Memory, last_mem); _igvn._worklist.push(ld); } } } --- 1074,1108 ---- if (current == first) break; current = my_mem->as_Mem(); } // end while } 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)) { + 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; + _igvn.hash_delete(mem_input); + // Give each load the same memory state + for (uint i = 0; i < pk->size(); i++) { LoadNode* ld = pk->at(i)->as_Load(); _igvn.hash_delete(ld); ! ld->set_req(MemNode::Memory, mem_input); _igvn._worklist.push(ld); } } }
src/share/vm/opto/superword.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File