Skip to content

Commit 0495f3c

Browse files
author
duke
committed
Backport 4eae9b5ba61bfe262b43346a7499c98c1a54d2fe
1 parent 2b7f593 commit 0495f3c

File tree

6 files changed

+3
-251
lines changed

6 files changed

+3
-251
lines changed

src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -826,11 +826,6 @@ bool ShenandoahBarrierSetC2::optimize_loops(PhaseIdealLoop* phase, LoopOptsMode
826826
assert(UseShenandoahGC, "only for shenandoah");
827827
ShenandoahBarrierC2Support::pin_and_expand(phase);
828828
return true;
829-
} else if (mode == LoopOptsShenandoahPostExpand) {
830-
assert(UseShenandoahGC, "only for shenandoah");
831-
visited.clear();
832-
ShenandoahBarrierC2Support::optimize_after_expansion(visited, nstack, worklist, phase);
833-
return true;
834829
}
835830
return false;
836831
}

src/hotspot/share/gc/shenandoah/c2/shenandoahBarrierSetC2.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,8 @@ class ShenandoahBarrierSetC2 : public BarrierSetC2 {
122122
virtual Node* step_over_gc_barrier(Node* c) const;
123123
virtual bool expand_barriers(Compile* C, PhaseIterGVN& igvn) const;
124124
virtual bool optimize_loops(PhaseIdealLoop* phase, LoopOptsMode mode, VectorSet& visited, Node_Stack& nstack, Node_List& worklist) const;
125-
virtual bool strip_mined_loops_expanded(LoopOptsMode mode) const { return mode == LoopOptsShenandoahExpand || mode == LoopOptsShenandoahPostExpand; }
126-
virtual bool is_gc_specific_loop_opts_pass(LoopOptsMode mode) const { return mode == LoopOptsShenandoahExpand || mode == LoopOptsShenandoahPostExpand; }
125+
virtual bool strip_mined_loops_expanded(LoopOptsMode mode) const { return mode == LoopOptsShenandoahExpand; }
126+
virtual bool is_gc_specific_loop_opts_pass(LoopOptsMode mode) const { return mode == LoopOptsShenandoahExpand; }
127127

128128
// Support for macro expanded GC barriers
129129
virtual void register_potential_barrier_node(Node* node) const;

src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.cpp

Lines changed: 0 additions & 236 deletions
Original file line numberDiff line numberDiff line change
@@ -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
17391503
static bool has_never_branch(Node* root) {
17401504
for (uint i = 1; i < root->req(); i++) {

src/hotspot/share/gc/shenandoah/c2/shenandoahSupport.hpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,7 @@ class ShenandoahBarrierC2Support : public AllStatic {
6363
static void call_lrb_stub(Node*& ctrl, Node*& val, Node* load_addr,
6464
DecoratorSet decorators, PhaseIdealLoop* phase);
6565
static void test_in_cset(Node*& ctrl, Node*& not_cset_ctrl, Node* val, Node* raw_mem, PhaseIdealLoop* phase);
66-
static void move_gc_state_test_out_of_loop(IfNode* iff, PhaseIdealLoop* phase);
67-
static void merge_back_to_back_tests(Node* n, PhaseIdealLoop* phase);
68-
static bool merge_point_safe(Node* region);
69-
static bool identical_backtoback_ifs(Node *n, PhaseIdealLoop* phase);
7066
static void fix_ctrl(Node* barrier, Node* region, const MemoryGraphFixer& fixer, Unique_Node_List& uses, Unique_Node_List& uses_to_ignore, uint last, PhaseIdealLoop* phase);
71-
static IfNode* find_unswitching_candidate(const IdealLoopTree *loop, PhaseIdealLoop* phase);
7267

7368
static Node* get_load_addr(PhaseIdealLoop* phase, VectorSet& visited, Node* lrb);
7469
public:
@@ -80,7 +75,6 @@ class ShenandoahBarrierC2Support : public AllStatic {
8075

8176
static bool expand(Compile* C, PhaseIterGVN& igvn);
8277
static void pin_and_expand(PhaseIdealLoop* phase);
83-
static void optimize_after_expansion(VectorSet& visited, Node_Stack& nstack, Node_List& old_new, PhaseIdealLoop* phase);
8478

8579
#ifdef ASSERT
8680
static void verify(RootNode* root);

src/hotspot/share/opto/compile.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ enum LoopOptsMode {
104104
LoopOptsNone,
105105
LoopOptsMaxUnroll,
106106
LoopOptsShenandoahExpand,
107-
LoopOptsShenandoahPostExpand,
108107
LoopOptsSkipSplitIf,
109108
LoopOptsVerify
110109
};

test/hotspot/jtreg/compiler/gcbarriers/TestShenandoahBarrierExpansion.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ private static int testLoadTwoObjectFieldsWithNullCheck() {
7171

7272
@Test
7373
@IR(failOn = IRNode.IF, phase = CompilePhase.AFTER_PARSING)
74-
@IR(counts = { IRNode.IF, "3" }, phase = CompilePhase.BARRIER_EXPANSION)
74+
@IR(counts = { IRNode.IF, "4" }, phase = CompilePhase.BARRIER_EXPANSION)
7575
private static void testLoadTwoFieldObjectAndEscape() {
7676
final A field2 = staticField2;
7777
final A field3 = staticField3;

0 commit comments

Comments
 (0)