Mercurial > hg > graal-jvmci-8
comparison src/share/vm/opto/superword.cpp @ 952:ace8397c8563
6876276: assert(!is_visited,"visit only once")
Summary: schedule the superword loads based on dependence constraints
Reviewed-by: kvn, never
author | cfang |
---|---|
date | Mon, 31 Aug 2009 08:31:45 -0700 |
parents | 78af5ae8e731 |
children | 685e959d09ea |
comparison
equal
deleted
inserted
replaced
951:1fbd5d696bf4 | 952:ace8397c8563 |
---|---|
988 // (4) If there is no dependence restriction for a sandwiched memory op, we simply | 988 // (4) If there is no dependence restriction for a sandwiched memory op, we simply |
989 // schedule this store AFTER the pack | 989 // schedule this store AFTER the pack |
990 // (5) We know there is no dependence cycle, so there in no other case; | 990 // (5) We know there is no dependence cycle, so there in no other case; |
991 // (6) Finally, all memory ops in another single pack should be moved in the same direction. | 991 // (6) Finally, all memory ops in another single pack should be moved in the same direction. |
992 // | 992 // |
993 // To schedule a load pack: the memory edge of every loads in the pack must be | 993 // To schedule a load pack, we use the memory state of either the first or the last load in |
994 // the same as the memory edge of the last executed load in the pack | 994 // the pack, based on the dependence constraint. |
995 void SuperWord::co_locate_pack(Node_List* pk) { | 995 void SuperWord::co_locate_pack(Node_List* pk) { |
996 if (pk->at(0)->is_Store()) { | 996 if (pk->at(0)->is_Store()) { |
997 MemNode* first = executed_first(pk)->as_Mem(); | 997 MemNode* first = executed_first(pk)->as_Mem(); |
998 MemNode* last = executed_last(pk)->as_Mem(); | 998 MemNode* last = executed_last(pk)->as_Mem(); |
999 Unique_Node_List schedule_before_pack; | 999 Unique_Node_List schedule_before_pack; |
1074 | 1074 |
1075 if (current == first) break; | 1075 if (current == first) break; |
1076 current = my_mem->as_Mem(); | 1076 current = my_mem->as_Mem(); |
1077 } // end while | 1077 } // end while |
1078 } else if (pk->at(0)->is_Load()) { //load | 1078 } else if (pk->at(0)->is_Load()) { //load |
1079 // all use the memory state that the last executed load uses | 1079 // all loads in the pack should have the same memory state. By default, |
1080 LoadNode* last_load = executed_last(pk)->as_Load(); | 1080 // we use the memory state of the last load. However, if any load could |
1081 Node* last_mem = last_load->in(MemNode::Memory); | 1081 // not be moved down due to the dependence constraint, we use the memory |
1082 _igvn.hash_delete(last_mem); | 1082 // state of the first load. |
1083 // Give each load same memory state as last | 1083 Node* last_mem = executed_last(pk)->in(MemNode::Memory); |
1084 Node* first_mem = executed_first(pk)->in(MemNode::Memory); | |
1085 bool schedule_last = true; | |
1086 for (uint i = 0; i < pk->size(); i++) { | |
1087 Node* ld = pk->at(i); | |
1088 for (Node* current = last_mem; current != ld->in(MemNode::Memory); | |
1089 current=current->in(MemNode::Memory)) { | |
1090 assert(current != first_mem, "corrupted memory graph"); | |
1091 if(current->is_Mem() && !independent(current, ld)){ | |
1092 schedule_last = false; // a later store depends on this load | |
1093 break; | |
1094 } | |
1095 } | |
1096 } | |
1097 | |
1098 Node* mem_input = schedule_last ? last_mem : first_mem; | |
1099 _igvn.hash_delete(mem_input); | |
1100 // Give each load the same memory state | |
1084 for (uint i = 0; i < pk->size(); i++) { | 1101 for (uint i = 0; i < pk->size(); i++) { |
1085 LoadNode* ld = pk->at(i)->as_Load(); | 1102 LoadNode* ld = pk->at(i)->as_Load(); |
1086 _igvn.hash_delete(ld); | 1103 _igvn.hash_delete(ld); |
1087 ld->set_req(MemNode::Memory, last_mem); | 1104 ld->set_req(MemNode::Memory, mem_input); |
1088 _igvn._worklist.push(ld); | 1105 _igvn._worklist.push(ld); |
1089 } | 1106 } |
1090 } | 1107 } |
1091 } | 1108 } |
1092 | 1109 |