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