1215 // Now we should be home |
1215 // Now we should be home |
1216 phase->igvn().set_delay_transform(false); |
1216 phase->igvn().set_delay_transform(false); |
1217 } |
1217 } |
1218 |
1218 |
1219 // Sort out the loads that are between a call ant its catch blocks |
1219 // Sort out the loads that are between a call ant its catch blocks |
1220 static void process_catch_cleanup_candidate(PhaseIdealLoop* phase, LoadNode* load) { |
1220 static void process_catch_cleanup_candidate(PhaseIdealLoop* phase, LoadNode* load, bool verify) { |
1221 bool trace = phase->C->directive()->ZTraceLoadBarriersOption; |
1221 bool trace = phase->C->directive()->ZTraceLoadBarriersOption; |
1222 |
1222 |
1223 Node* ctrl = get_ctrl_normalized(phase, load); |
1223 Node* ctrl = get_ctrl_normalized(phase, load); |
1224 if (!ctrl->is_Proj() || (ctrl->in(0) == NULL) || !ctrl->in(0)->isa_Call()) { |
1224 if (!ctrl->is_Proj() || (ctrl->in(0) == NULL) || !ctrl->in(0)->isa_Call()) { |
1225 return; |
1225 return; |
1226 } |
1226 } |
1227 |
1227 |
1228 Node* catch_node = ctrl->isa_Proj()->raw_out(0); |
1228 Node* catch_node = ctrl->isa_Proj()->raw_out(0); |
1229 if (catch_node->is_Catch()) { |
1229 if (catch_node->is_Catch()) { |
1230 if (catch_node->outcnt() > 1) { |
1230 if (catch_node->outcnt() > 1) { |
|
1231 assert(!verify, "All loads should already have been moved"); |
1231 call_catch_cleanup_one(phase, load, ctrl); |
1232 call_catch_cleanup_one(phase, load, ctrl); |
1232 } else { |
1233 } else { |
1233 if (trace) tty->print_cr("Call catch cleanup with only one catch: load %i ", load->_idx); |
1234 if (trace) tty->print_cr("Call catch cleanup with only one catch: load %i ", load->_idx); |
1234 } |
1235 } |
1235 } |
1236 } |
1243 bool ZBarrierSetC2::optimize_loops(PhaseIdealLoop* phase, LoopOptsMode mode, VectorSet& visited, Node_Stack& nstack, Node_List& worklist) const { |
1244 bool ZBarrierSetC2::optimize_loops(PhaseIdealLoop* phase, LoopOptsMode mode, VectorSet& visited, Node_Stack& nstack, Node_List& worklist) const { |
1244 |
1245 |
1245 if (mode == LoopOptsZBarrierInsertion) { |
1246 if (mode == LoopOptsZBarrierInsertion) { |
1246 // First make sure all loads between call and catch are moved to the catch block |
1247 // First make sure all loads between call and catch are moved to the catch block |
1247 clean_catch_blocks(phase); |
1248 clean_catch_blocks(phase); |
|
1249 DEBUG_ONLY(clean_catch_blocks(phase, true /* verify */);) |
1248 |
1250 |
1249 // Then expand barriers on all loads |
1251 // Then expand barriers on all loads |
1250 insert_load_barriers(phase); |
1252 insert_load_barriers(phase); |
1251 |
1253 |
1252 // Handle all Unsafe that need barriers. |
1254 // Handle all Unsafe that need barriers. |
1396 // before any store. |
1398 // before any store. |
1397 // |
1399 // |
1398 // Sometimes the loads use will be at a place dominated by all catch blocks, then we need |
1400 // Sometimes the loads use will be at a place dominated by all catch blocks, then we need |
1399 // a load in each catch block, and a Phi at the dominated use. |
1401 // a load in each catch block, and a Phi at the dominated use. |
1400 |
1402 |
1401 void ZBarrierSetC2::clean_catch_blocks(PhaseIdealLoop* phase) const { |
1403 void ZBarrierSetC2::clean_catch_blocks(PhaseIdealLoop* phase, bool verify) const { |
1402 |
1404 |
1403 Compile *C = phase->C; |
1405 Compile *C = phase->C; |
1404 uint new_ids = C->unique(); |
1406 uint new_ids = C->unique(); |
1405 PhaseIterGVN &igvn = phase->igvn(); |
1407 PhaseIterGVN &igvn = phase->igvn(); |
1406 VectorSet visited(Thread::current()->resource_area()); |
1408 VectorSet visited(Thread::current()->resource_area()); |
1423 bool is_old_node = (n->_idx < new_ids); // don't process nodes that were created during cleanup |
1425 bool is_old_node = (n->_idx < new_ids); // don't process nodes that were created during cleanup |
1424 if (n->is_Load() && is_old_node) { |
1426 if (n->is_Load() && is_old_node) { |
1425 LoadNode* load = n->isa_Load(); |
1427 LoadNode* load = n->isa_Load(); |
1426 // only care about loads that will have a barrier |
1428 // only care about loads that will have a barrier |
1427 if (load_require_barrier(load)) { |
1429 if (load_require_barrier(load)) { |
1428 process_catch_cleanup_candidate(phase, load); |
1430 process_catch_cleanup_candidate(phase, load, verify); |
1429 } |
1431 } |
1430 } |
1432 } |
1431 } |
1433 } |
1432 |
1434 |
1433 C->print_method(PHASE_CALL_CATCH_CLEANUP, 2); |
1435 C->print_method(PHASE_CALL_CATCH_CLEANUP, 2); |