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