< prev index next >

src/hotspot/share/opto/loopopts.cpp

Print this page
rev 54995 : 8224675: Late GC barrier insertion for ZGC
Reviewed-by:


1178   // into LoopNodes.
1179   IdealLoopTree *n_loop = get_loop(n_ctrl);
1180   for (uint j = 1; j < n_ctrl->req(); j++) {
1181     if (get_loop(n_ctrl->in(j)) != n_loop) {
1182       return false;
1183     }
1184   }
1185 
1186   // Check for safety of the merge point.
1187   if (!merge_point_safe(n_ctrl)) {
1188     return false;
1189   }
1190 
1191   return true;
1192 }
1193 
1194 //------------------------------split_if_with_blocks_post----------------------
1195 // Do the real work in a non-recursive function.  CFG hackery wants to be
1196 // in the post-order, so it can dirty the I-DOM info and not use the dirtied
1197 // info.
1198 void PhaseIdealLoop::split_if_with_blocks_post(Node *n, bool last_round) {
1199 
1200   // Cloning Cmp through Phi's involves the split-if transform.
1201   // FastLock is not used by an If
1202   if (n->is_Cmp() && !n->is_FastLock() && !last_round) {
1203     Node *n_ctrl = get_ctrl(n);
1204     // Determine if the Node has inputs from some local Phi.
1205     // Returns the block to clone thru.
1206     Node *n_blk = has_local_phi_input(n);
1207     if (n_blk != n_ctrl) {
1208       return;
1209     }
1210 
1211     if (!can_split_if(n_ctrl)) {
1212       return;
1213     }
1214 
1215     if (n->outcnt() != 1) {
1216       return; // Multiple bool's from 1 compare?
1217     }
1218     Node *bol = n->unique_out();
1219     assert(bol->is_Bool(), "expect a bool here");
1220     if (bol->outcnt() != 1) {
1221       return;// Multiple branches from 1 compare?
1222     }


1434             // to fold a StoreP and an AddP together (as part of an
1435             // address expression) and the AddP and StoreP have
1436             // different controls.
1437             if (!x->is_Load() && !x->is_DecodeNarrowPtr()) _igvn._worklist.yank(x);
1438           }
1439           _igvn.remove_dead_node(n);
1440         }
1441       }
1442     }
1443   }
1444 
1445   try_move_store_after_loop(n);
1446 
1447   // Check for Opaque2's who's loop has disappeared - who's input is in the
1448   // same loop nest as their output.  Remove 'em, they are no longer useful.
1449   if( n_op == Op_Opaque2 &&
1450       n->in(1) != NULL &&
1451       get_loop(get_ctrl(n)) == get_loop(get_ctrl(n->in(1))) ) {
1452     _igvn.replace_node( n, n->in(1) );
1453   }
1454 
1455 #if INCLUDE_ZGC
1456   if (UseZGC) {
1457     ZBarrierSetC2::loop_optimize_gc_barrier(this, n, last_round);
1458   }
1459 #endif
1460 }
1461 
1462 //------------------------------split_if_with_blocks---------------------------
1463 // Check for aggressive application of 'split-if' optimization,
1464 // using basic block level info.
1465 void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack, bool last_round) {
1466   Node* root = C->root();
1467   visited.set(root->_idx); // first, mark root as visited
1468   // Do pre-visit work for root
1469   Node* n   = split_if_with_blocks_pre(root);
1470   uint  cnt = n->outcnt();
1471   uint  i   = 0;
1472 
1473   while (true) {
1474     // Visit all children
1475     if (i < cnt) {
1476       Node* use = n->raw_out(i);
1477       ++i;
1478       if (use->outcnt() != 0 && !visited.test_set(use->_idx)) {
1479         // Now do pre-visit work for this use
1480         use = split_if_with_blocks_pre(use);
1481         nstack.push(n, i); // Save parent and next use's index.
1482         n   = use;         // Process all children of current use.
1483         cnt = use->outcnt();
1484         i   = 0;
1485       }
1486     }
1487     else {
1488       // All of n's children have been processed, complete post-processing.
1489       if (cnt != 0 && !n->is_Con()) {
1490         assert(has_node(n), "no dead nodes");
1491         split_if_with_blocks_post(n, last_round);
1492       }
1493       if (must_throttle_split_if()) {
1494         nstack.clear();
1495       }
1496       if (nstack.is_empty()) {
1497         // Finished all nodes on stack.
1498         break;
1499       }
1500       // Get saved parent node and next use's index. Visit the rest of uses.
1501       n   = nstack.node();
1502       cnt = n->outcnt();
1503       i   = nstack.index();
1504       nstack.pop();
1505     }
1506   }
1507 }
1508 
1509 
1510 //=============================================================================
1511 //




1178   // into LoopNodes.
1179   IdealLoopTree *n_loop = get_loop(n_ctrl);
1180   for (uint j = 1; j < n_ctrl->req(); j++) {
1181     if (get_loop(n_ctrl->in(j)) != n_loop) {
1182       return false;
1183     }
1184   }
1185 
1186   // Check for safety of the merge point.
1187   if (!merge_point_safe(n_ctrl)) {
1188     return false;
1189   }
1190 
1191   return true;
1192 }
1193 
1194 //------------------------------split_if_with_blocks_post----------------------
1195 // Do the real work in a non-recursive function.  CFG hackery wants to be
1196 // in the post-order, so it can dirty the I-DOM info and not use the dirtied
1197 // info.
1198 void PhaseIdealLoop::split_if_with_blocks_post(Node *n) {
1199 
1200   // Cloning Cmp through Phi's involves the split-if transform.
1201   // FastLock is not used by an If
1202   if (n->is_Cmp() && !n->is_FastLock()) {
1203     Node *n_ctrl = get_ctrl(n);
1204     // Determine if the Node has inputs from some local Phi.
1205     // Returns the block to clone thru.
1206     Node *n_blk = has_local_phi_input(n);
1207     if (n_blk != n_ctrl) {
1208       return;
1209     }
1210 
1211     if (!can_split_if(n_ctrl)) {
1212       return;
1213     }
1214 
1215     if (n->outcnt() != 1) {
1216       return; // Multiple bool's from 1 compare?
1217     }
1218     Node *bol = n->unique_out();
1219     assert(bol->is_Bool(), "expect a bool here");
1220     if (bol->outcnt() != 1) {
1221       return;// Multiple branches from 1 compare?
1222     }


1434             // to fold a StoreP and an AddP together (as part of an
1435             // address expression) and the AddP and StoreP have
1436             // different controls.
1437             if (!x->is_Load() && !x->is_DecodeNarrowPtr()) _igvn._worklist.yank(x);
1438           }
1439           _igvn.remove_dead_node(n);
1440         }
1441       }
1442     }
1443   }
1444 
1445   try_move_store_after_loop(n);
1446 
1447   // Check for Opaque2's who's loop has disappeared - who's input is in the
1448   // same loop nest as their output.  Remove 'em, they are no longer useful.
1449   if( n_op == Op_Opaque2 &&
1450       n->in(1) != NULL &&
1451       get_loop(get_ctrl(n)) == get_loop(get_ctrl(n->in(1))) ) {
1452     _igvn.replace_node( n, n->in(1) );
1453   }






1454 }
1455 
1456 //------------------------------split_if_with_blocks---------------------------
1457 // Check for aggressive application of 'split-if' optimization,
1458 // using basic block level info.
1459 void PhaseIdealLoop::split_if_with_blocks(VectorSet &visited, Node_Stack &nstack) {
1460   Node* root = C->root();
1461   visited.set(root->_idx); // first, mark root as visited
1462   // Do pre-visit work for root
1463   Node* n   = split_if_with_blocks_pre(root);
1464   uint  cnt = n->outcnt();
1465   uint  i   = 0;
1466 
1467   while (true) {
1468     // Visit all children
1469     if (i < cnt) {
1470       Node* use = n->raw_out(i);
1471       ++i;
1472       if (use->outcnt() != 0 && !visited.test_set(use->_idx)) {
1473         // Now do pre-visit work for this use
1474         use = split_if_with_blocks_pre(use);
1475         nstack.push(n, i); // Save parent and next use's index.
1476         n   = use;         // Process all children of current use.
1477         cnt = use->outcnt();
1478         i   = 0;
1479       }
1480     }
1481     else {
1482       // All of n's children have been processed, complete post-processing.
1483       if (cnt != 0 && !n->is_Con()) {
1484         assert(has_node(n), "no dead nodes");
1485         split_if_with_blocks_post(n);
1486       }
1487       if (must_throttle_split_if()) {
1488         nstack.clear();
1489       }
1490       if (nstack.is_empty()) {
1491         // Finished all nodes on stack.
1492         break;
1493       }
1494       // Get saved parent node and next use's index. Visit the rest of uses.
1495       n   = nstack.node();
1496       cnt = n->outcnt();
1497       i   = nstack.index();
1498       nstack.pop();
1499     }
1500   }
1501 }
1502 
1503 
1504 //=============================================================================
1505 //


< prev index next >