Skip to content

Commit 703a6ef

Browse files
Quan Anh MaiVladimir Kozlov
Quan Anh Mai
authored and
Vladimir Kozlov
committed
8283699: Improve the peephole mechanism of hotspot
Reviewed-by: kvn, dlong
1 parent 94a9b04 commit 703a6ef

File tree

14 files changed

+813
-144
lines changed

14 files changed

+813
-144
lines changed
+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
#include "precompiled.hpp"
25+
26+
#ifdef COMPILER2
27+
28+
#include "peephole_x86_64.hpp"
29+
30+
// This function transforms the shapes
31+
// mov d, s1; add d, s2 into
32+
// lea d, [s1 + s2] and
33+
// mov d, s1; shl d, s2 into
34+
// lea d, [s1 << s2] with s2 = 1, 2, 3
35+
bool lea_coalesce_helper(Block* block, int block_index, PhaseCFG* cfg_, PhaseRegAlloc* ra_,
36+
MachNode* (*new_root)(), uint inst0_rule, bool imm) {
37+
MachNode* inst0 = block->get_node(block_index)->as_Mach();
38+
assert(inst0->rule() == inst0_rule, "sanity");
39+
40+
OptoReg::Name dst = ra_->get_reg_first(inst0);
41+
MachNode* inst1 = nullptr;
42+
OptoReg::Name src1 = OptoReg::Bad;
43+
44+
if (inst0->in(1)->is_MachSpillCopy()) {
45+
OptoReg::Name in = ra_->get_reg_first(inst0->in(1)->in(1));
46+
if (OptoReg::is_reg(in) && OptoReg::as_VMReg(in)->is_Register()) {
47+
inst1 = inst0->in(1)->as_Mach();
48+
src1 = in;
49+
}
50+
}
51+
if (inst1 == nullptr) {
52+
return false;
53+
}
54+
assert(dst != src1, "");
55+
56+
// Only coalesce if inst1 is immediately followed by inst0
57+
// Can be improved for more general cases
58+
if (block_index < 1 || block->get_node(block_index - 1) != inst1) {
59+
return false;
60+
}
61+
int inst1_index = block_index - 1;
62+
Node* inst2;
63+
if (imm) {
64+
inst2 = nullptr;
65+
} else {
66+
inst2 = inst0->in(2);
67+
if (inst2 == inst1) {
68+
inst2 = inst2->in(1);
69+
}
70+
}
71+
72+
// See VM_Version::supports_fast_3op_lea()
73+
if (!imm) {
74+
Register rsrc1 = OptoReg::as_VMReg(src1)->as_Register();
75+
Register rsrc2 = OptoReg::as_VMReg(ra_->get_reg_first(inst2))->as_Register();
76+
if ((rsrc1 == rbp || rsrc1 == r13) && (rsrc2 == rbp || rsrc2 == r13)) {
77+
return false;
78+
}
79+
}
80+
81+
// Go down the block to find the output proj node (the flag output) of inst0
82+
int proj_index = -1;
83+
Node* proj = nullptr;
84+
for (uint pos = block_index + 1; pos < block->number_of_nodes(); pos++) {
85+
Node* curr = block->get_node(pos);
86+
if (curr->is_MachProj() && curr->in(0) == inst0) {
87+
proj_index = pos;
88+
proj = curr;
89+
break;
90+
}
91+
}
92+
assert(proj != nullptr, "");
93+
// If some node uses the flag, cannot remove
94+
if (proj->outcnt() > 0) {
95+
return false;
96+
}
97+
98+
MachNode* root = new_root();
99+
// Assign register for the newly allocated node
100+
ra_->set_oop(root, ra_->is_oop(inst0));
101+
ra_->set_pair(root->_idx, ra_->get_reg_second(inst0), ra_->get_reg_first(inst0));
102+
103+
// Set input and output for the node
104+
root->add_req(inst0->in(0));
105+
root->add_req(inst1->in(1));
106+
// No input for constant after matching
107+
if (!imm) {
108+
root->add_req(inst2);
109+
}
110+
inst0->replace_by(root);
111+
proj->set_req(0, inst0);
112+
113+
// Initialize the operand array
114+
root->_opnds[0] = inst0->_opnds[0]->clone();
115+
root->_opnds[1] = inst0->_opnds[1]->clone();
116+
root->_opnds[2] = inst0->_opnds[2]->clone();
117+
118+
// Modify the block
119+
inst0->set_removed();
120+
inst1->set_removed();
121+
block->remove_node(proj_index);
122+
block->remove_node(block_index);
123+
block->remove_node(inst1_index);
124+
block->insert_node(root, block_index - 1);
125+
126+
// Modify the CFG
127+
cfg_->map_node_to_block(inst0, nullptr);
128+
cfg_->map_node_to_block(inst1, nullptr);
129+
cfg_->map_node_to_block(proj, nullptr);
130+
cfg_->map_node_to_block(root, block);
131+
132+
return true;
133+
}
134+
135+
bool Peephole::lea_coalesce_reg(Block* block, int block_index, PhaseCFG* cfg_, PhaseRegAlloc* ra_,
136+
MachNode* (*new_root)(), uint inst0_rule) {
137+
return lea_coalesce_helper(block, block_index, cfg_, ra_, new_root, inst0_rule, false);
138+
}
139+
140+
bool Peephole::lea_coalesce_imm(Block* block, int block_index, PhaseCFG* cfg_, PhaseRegAlloc* ra_,
141+
MachNode* (*new_root)(), uint inst0_rule) {
142+
return lea_coalesce_helper(block, block_index, cfg_, ra_, new_root, inst0_rule, true);
143+
}
144+
145+
#endif // COMPILER2
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
25+
#ifndef CPU_X86_PEEPHOLE_X86_64_HPP
26+
#define CPU_X86_PEEPHOLE_X86_64_HPP
27+
28+
#include "opto/machnode.hpp"
29+
#include "opto/regalloc.hpp"
30+
31+
class Peephole {
32+
public:
33+
static bool lea_coalesce_reg(Block* block, int block_index, PhaseCFG* cfg_, PhaseRegAlloc* ra_,
34+
MachNode* (*new_root)(), uint inst0_rule);
35+
static bool lea_coalesce_imm(Block* block, int block_index, PhaseCFG* cfg_, PhaseRegAlloc* ra_,
36+
MachNode* (*new_root)(), uint inst0_rule);
37+
};
38+
39+
#endif // CPU_X86_PEEPHOLE_X86_64_HPP

src/hotspot/cpu/x86/x86_32.ad

+2-2
Original file line numberDiff line numberDiff line change
@@ -657,8 +657,8 @@ void MachEpilogNode::format( PhaseRegAlloc *ra_, outputStream* st ) const {
657657
}
658658
st->print_cr("POPL EBP"); st->print("\t");
659659
if (do_polling() && C->is_method_compilation()) {
660-
st->print("CMPL rsp, poll_offset[thread] \n\t"
661-
"JA #safepoint_stub\t"
660+
st->print("CMPL rsp, poll_offset[thread] \n\t"
661+
"JA #safepoint_stub\t"
662662
"# Safepoint: poll for GC");
663663
}
664664
}

0 commit comments

Comments
 (0)