@@ -52,12 +52,6 @@ bool ShenandoahBarrierC2Support::expand(Compile* C, PhaseIterGVN& igvn) {
5252 C->clear_major_progress ();
5353 PhaseIdealLoop::optimize (igvn, LoopOptsShenandoahExpand);
5454 if (C->failing ()) return false ;
55-
56- C->set_major_progress ();
57- if (!C->optimize_loops (igvn, LoopOptsShenandoahPostExpand)) {
58- return false ;
59- }
60- C->clear_major_progress ();
6155 C->process_for_post_loop_opts_igvn (igvn);
6256 if (C->failing ()) return false ;
6357
@@ -1482,236 +1476,6 @@ Node* ShenandoahBarrierC2Support::get_load_addr(PhaseIdealLoop* phase, VectorSet
14821476
14831477}
14841478
1485- void ShenandoahBarrierC2Support::move_gc_state_test_out_of_loop (IfNode* iff, PhaseIdealLoop* phase) {
1486- IdealLoopTree *loop = phase->get_loop (iff);
1487- Node* loop_head = loop->_head ;
1488- Node* entry_c = loop_head->in (LoopNode::EntryControl);
1489-
1490- Node* bol = iff->in (1 );
1491- Node* cmp = bol->in (1 );
1492- Node* andi = cmp->in (1 );
1493- Node* load = andi->in (1 );
1494-
1495- assert (is_gc_state_load (load), " broken" );
1496- if (!phase->is_dominator (load->in (0 ), entry_c)) {
1497- Node* mem_ctrl = nullptr ;
1498- Node* mem = dom_mem (load->in (MemNode::Memory), loop_head, Compile::AliasIdxRaw, mem_ctrl, phase);
1499- load = load->clone ();
1500- load->set_req (MemNode::Memory, mem);
1501- load->set_req (0 , entry_c);
1502- phase->register_new_node (load, entry_c);
1503- andi = andi->clone ();
1504- andi->set_req (1 , load);
1505- phase->register_new_node (andi, entry_c);
1506- cmp = cmp->clone ();
1507- cmp->set_req (1 , andi);
1508- phase->register_new_node (cmp, entry_c);
1509- bol = bol->clone ();
1510- bol->set_req (1 , cmp);
1511- phase->register_new_node (bol, entry_c);
1512-
1513- phase->igvn ().replace_input_of (iff, 1 , bol);
1514- }
1515- }
1516-
1517- bool ShenandoahBarrierC2Support::identical_backtoback_ifs (Node* n, PhaseIdealLoop* phase) {
1518- if (!n->is_If () || n->is_CountedLoopEnd ()) {
1519- return false ;
1520- }
1521- Node* region = n->in (0 );
1522-
1523- if (!region->is_Region ()) {
1524- return false ;
1525- }
1526- Node* dom = phase->idom (region);
1527- if (!dom->is_If ()) {
1528- return false ;
1529- }
1530-
1531- if (!is_heap_stable_test (n) || !is_heap_stable_test (dom)) {
1532- return false ;
1533- }
1534-
1535- IfNode* dom_if = dom->as_If ();
1536- Node* proj_true = dom_if->proj_out (1 );
1537- Node* proj_false = dom_if->proj_out (0 );
1538-
1539- for (uint i = 1 ; i < region->req (); i++) {
1540- if (phase->is_dominator (proj_true, region->in (i))) {
1541- continue ;
1542- }
1543- if (phase->is_dominator (proj_false, region->in (i))) {
1544- continue ;
1545- }
1546- return false ;
1547- }
1548-
1549- return true ;
1550- }
1551-
1552- bool ShenandoahBarrierC2Support::merge_point_safe (Node* region) {
1553- for (DUIterator_Fast imax, i = region->fast_outs (imax); i < imax; i++) {
1554- Node* n = region->fast_out (i);
1555- if (n->is_LoadStore ()) {
1556- // Splitting a LoadStore node through phi, causes it to lose its SCMemProj: the split if code doesn't have support
1557- // for a LoadStore at the region the if is split through because that's not expected to happen (LoadStore nodes
1558- // should be between barrier nodes). It does however happen with Shenandoah though because barriers can get
1559- // expanded around a LoadStore node.
1560- return false ;
1561- }
1562- }
1563- return true ;
1564- }
1565-
1566-
1567- void ShenandoahBarrierC2Support::merge_back_to_back_tests (Node* n, PhaseIdealLoop* phase) {
1568- assert (is_heap_stable_test (n), " no other tests" );
1569- if (identical_backtoback_ifs (n, phase)) {
1570- Node* n_ctrl = n->in (0 );
1571- if (phase->can_split_if (n_ctrl) && merge_point_safe (n_ctrl)) {
1572- IfNode* dom_if = phase->idom (n_ctrl)->as_If ();
1573- if (is_heap_stable_test (n)) {
1574- Node* gc_state_load = n->in (1 )->in (1 )->in (1 )->in (1 );
1575- assert (is_gc_state_load (gc_state_load), " broken" );
1576- Node* dom_gc_state_load = dom_if->in (1 )->in (1 )->in (1 )->in (1 );
1577- assert (is_gc_state_load (dom_gc_state_load), " broken" );
1578- if (gc_state_load != dom_gc_state_load) {
1579- phase->igvn ().replace_node (gc_state_load, dom_gc_state_load);
1580- }
1581- }
1582- PhiNode* bolphi = PhiNode::make_blank (n_ctrl, n->in (1 ));
1583- Node* proj_true = dom_if->proj_out (1 );
1584- Node* proj_false = dom_if->proj_out (0 );
1585- Node* con_true = phase->igvn ().makecon (TypeInt::ONE);
1586- Node* con_false = phase->igvn ().makecon (TypeInt::ZERO);
1587-
1588- for (uint i = 1 ; i < n_ctrl->req (); i++) {
1589- if (phase->is_dominator (proj_true, n_ctrl->in (i))) {
1590- bolphi->init_req (i, con_true);
1591- } else {
1592- assert (phase->is_dominator (proj_false, n_ctrl->in (i)), " bad if" );
1593- bolphi->init_req (i, con_false);
1594- }
1595- }
1596- phase->register_new_node (bolphi, n_ctrl);
1597- phase->igvn ().replace_input_of (n, 1 , bolphi);
1598- phase->do_split_if (n);
1599- }
1600- }
1601- }
1602-
1603- IfNode* ShenandoahBarrierC2Support::find_unswitching_candidate (const IdealLoopTree* loop, PhaseIdealLoop* phase) {
1604- // Find first invariant test that doesn't exit the loop
1605- LoopNode *head = loop->_head ->as_Loop ();
1606- IfNode* unswitch_iff = nullptr ;
1607- Node* n = head->in (LoopNode::LoopBackControl);
1608- int loop_has_sfpts = -1 ;
1609- while (n != head) {
1610- Node* n_dom = phase->idom (n);
1611- if (n->is_Region ()) {
1612- if (n_dom->is_If ()) {
1613- IfNode* iff = n_dom->as_If ();
1614- if (iff->in (1 )->is_Bool ()) {
1615- BoolNode* bol = iff->in (1 )->as_Bool ();
1616- if (bol->in (1 )->is_Cmp ()) {
1617- // If condition is invariant and not a loop exit,
1618- // then found reason to unswitch.
1619- if (is_heap_stable_test (iff) &&
1620- (loop_has_sfpts == -1 || loop_has_sfpts == 0 )) {
1621- assert (!loop->is_loop_exit (iff), " both branches should be in the loop" );
1622- if (loop_has_sfpts == -1 ) {
1623- for (uint i = 0 ; i < loop->_body .size (); i++) {
1624- Node *m = loop->_body [i];
1625- if (m->is_SafePoint () && !m->is_CallLeaf ()) {
1626- loop_has_sfpts = 1 ;
1627- break ;
1628- }
1629- }
1630- if (loop_has_sfpts == -1 ) {
1631- loop_has_sfpts = 0 ;
1632- }
1633- }
1634- if (!loop_has_sfpts) {
1635- unswitch_iff = iff;
1636- }
1637- }
1638- }
1639- }
1640- }
1641- }
1642- n = n_dom;
1643- }
1644- return unswitch_iff;
1645- }
1646-
1647-
1648- void ShenandoahBarrierC2Support::optimize_after_expansion (VectorSet &visited, Node_Stack &stack, Node_List &old_new, PhaseIdealLoop* phase) {
1649- Node_List heap_stable_tests;
1650- stack.push (phase->C ->start (), 0 );
1651- do {
1652- Node* n = stack.node ();
1653- uint i = stack.index ();
1654-
1655- if (i < n->outcnt ()) {
1656- Node* u = n->raw_out (i);
1657- stack.set_index (i+1 );
1658- if (!visited.test_set (u->_idx )) {
1659- stack.push (u, 0 );
1660- }
1661- } else {
1662- stack.pop ();
1663- if (n->is_If () && is_heap_stable_test (n)) {
1664- heap_stable_tests.push (n);
1665- }
1666- }
1667- } while (stack.size () > 0 );
1668-
1669- for (uint i = 0 ; i < heap_stable_tests.size (); i++) {
1670- Node* n = heap_stable_tests.at (i);
1671- assert (is_heap_stable_test (n), " only evacuation test" );
1672- merge_back_to_back_tests (n, phase);
1673- }
1674-
1675- if (!phase->C ->major_progress ()) {
1676- VectorSet seen;
1677- for (uint i = 0 ; i < heap_stable_tests.size (); i++) {
1678- Node* n = heap_stable_tests.at (i);
1679- IdealLoopTree* loop = phase->get_loop (n);
1680- if (loop != phase->ltree_root () &&
1681- loop->_child == nullptr &&
1682- !loop->_irreducible ) {
1683- Node* head = loop->_head ;
1684- if (head->is_Loop () &&
1685- (!head->is_CountedLoop () || head->as_CountedLoop ()->is_main_loop () || head->as_CountedLoop ()->is_normal_loop ()) &&
1686- !seen.test_set (head->_idx )) {
1687- IfNode* iff = find_unswitching_candidate (loop, phase);
1688- if (iff != nullptr ) {
1689- Node* bol = iff->in (1 );
1690- if (head->as_Loop ()->is_strip_mined ()) {
1691- head->as_Loop ()->verify_strip_mined (0 );
1692- }
1693- move_gc_state_test_out_of_loop (iff, phase);
1694-
1695- AutoNodeBudget node_budget (phase);
1696-
1697- if (loop->policy_unswitching (phase)) {
1698- if (head->as_Loop ()->is_strip_mined ()) {
1699- OuterStripMinedLoopNode* outer = head->as_CountedLoop ()->outer_loop ();
1700- hide_strip_mined_loop (outer, head->as_CountedLoop (), phase);
1701- }
1702- phase->do_unswitching (loop, old_new);
1703- } else {
1704- // Not proceeding with unswitching. Move load back in
1705- // the loop.
1706- phase->igvn ().replace_input_of (iff, 1 , bol);
1707- }
1708- }
1709- }
1710- }
1711- }
1712- }
1713- }
1714-
17151479#ifdef ASSERT
17161480static bool has_never_branch (Node* root) {
17171481 for (uint i = 1 ; i < root->req (); i++) {
0 commit comments