Skip to content

Commit fb0b1f0

Browse files
jaskarthTobiHartmann
authored andcommitted
8051725: Improve expansion of Conv2B nodes in the middle-end
Reviewed-by: thartmann, qamai, sviswanathan
1 parent 3eced01 commit fb0b1f0

File tree

13 files changed

+277
-152
lines changed

13 files changed

+277
-152
lines changed

src/hotspot/cpu/aarch64/aarch64.ad

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -15018,42 +15018,6 @@ instruct convL2I_reg(iRegINoSp dst, iRegL src) %{
1501815018
ins_pipe(ialu_reg);
1501915019
%}
1502015020

15021-
instruct convI2B(iRegINoSp dst, iRegIorL2I src, rFlagsReg cr)
15022-
%{
15023-
match(Set dst (Conv2B src));
15024-
effect(KILL cr);
15025-
15026-
format %{
15027-
"cmpw $src, zr\n\t"
15028-
"cset $dst, ne"
15029-
%}
15030-
15031-
ins_encode %{
15032-
__ cmpw(as_Register($src$$reg), zr);
15033-
__ cset(as_Register($dst$$reg), Assembler::NE);
15034-
%}
15035-
15036-
ins_pipe(ialu_reg);
15037-
%}
15038-
15039-
instruct convP2B(iRegINoSp dst, iRegP src, rFlagsReg cr)
15040-
%{
15041-
match(Set dst (Conv2B src));
15042-
effect(KILL cr);
15043-
15044-
format %{
15045-
"cmp $src, zr\n\t"
15046-
"cset $dst, ne"
15047-
%}
15048-
15049-
ins_encode %{
15050-
__ cmp(as_Register($src$$reg), zr);
15051-
__ cset(as_Register($dst$$reg), Assembler::NE);
15052-
%}
15053-
15054-
ins_pipe(ialu_reg);
15055-
%}
15056-
1505715021
instruct convD2F_reg(vRegF dst, vRegD src) %{
1505815022
match(Set dst (ConvD2F src));
1505915023

src/hotspot/cpu/arm/arm.ad

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7042,39 +7042,6 @@ instruct xorL_reg_immRot(iRegL dst, iRegL src1, immLlowRot con) %{
70427042
ins_pipe(ialu_reg_imm);
70437043
%}
70447044

7045-
//----------Convert to Boolean-------------------------------------------------
7046-
instruct convI2B( iRegI dst, iRegI src, flagsReg ccr ) %{
7047-
match(Set dst (Conv2B src));
7048-
effect(KILL ccr);
7049-
size(12);
7050-
ins_cost(DEFAULT_COST*2);
7051-
format %{ "TST $src,$src \n\t"
7052-
"MOV $dst, 0 \n\t"
7053-
"MOV.ne $dst, 1" %}
7054-
ins_encode %{ // FIXME: can do better?
7055-
__ tst($src$$Register, $src$$Register);
7056-
__ mov($dst$$Register, 0);
7057-
__ mov($dst$$Register, 1, ne);
7058-
%}
7059-
ins_pipe(ialu_reg_ialu);
7060-
%}
7061-
7062-
instruct convP2B( iRegI dst, iRegP src, flagsReg ccr ) %{
7063-
match(Set dst (Conv2B src));
7064-
effect(KILL ccr);
7065-
size(12);
7066-
ins_cost(DEFAULT_COST*2);
7067-
format %{ "TST $src,$src \n\t"
7068-
"MOV $dst, 0 \n\t"
7069-
"MOV.ne $dst, 1" %}
7070-
ins_encode %{
7071-
__ tst($src$$Register, $src$$Register);
7072-
__ mov($dst$$Register, 0);
7073-
__ mov($dst$$Register, 1, ne);
7074-
%}
7075-
ins_pipe(ialu_reg_ialu);
7076-
%}
7077-
70787045
instruct cmpLTMask_reg_reg( iRegI dst, iRegI p, iRegI q, flagsReg ccr ) %{
70797046
match(Set dst (CmpLTMask p q));
70807047
effect( KILL ccr );

src/hotspot/cpu/x86/assembler_x86.cpp

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5888,21 +5888,6 @@ void Assembler::setb(Condition cc, Register dst) {
58885888
emit_int24(0x0F, (unsigned char)0x90 | cc, (0xC0 | encode));
58895889
}
58905890

5891-
void Assembler::sete(Register dst) {
5892-
int encode = prefix_and_encode(dst->encoding(), true);
5893-
emit_int24(0x0F, (unsigned char)0x94, (0xC0 | encode));
5894-
}
5895-
5896-
void Assembler::setl(Register dst) {
5897-
int encode = prefix_and_encode(dst->encoding(), true);
5898-
emit_int24(0x0F, (unsigned char)0x9C, (0xC0 | encode));
5899-
}
5900-
5901-
void Assembler::setne(Register dst) {
5902-
int encode = prefix_and_encode(dst->encoding(), true);
5903-
emit_int24(0x0F, (unsigned char)0x95, (0xC0 | encode));
5904-
}
5905-
59065891
void Assembler::palignr(XMMRegister dst, XMMRegister src, int imm8) {
59075892
assert(VM_Version::supports_ssse3(), "");
59085893
InstructionAttr attributes(AVX_128bit, /* rex_w */ false, /* legacy_mode */ _legacy_mode_bw, /* no_mask_reg */ true, /* uses_vl */ true);
@@ -12406,19 +12391,10 @@ void Assembler::pusha() { // 32bit
1240612391
emit_int8(0x60);
1240712392
}
1240812393

12409-
void Assembler::set_byte_if_not_zero(Register dst) {
12410-
emit_int24(0x0F, (unsigned char)0x95, (0xC0 | dst->encoding()));
12411-
}
12412-
1241312394
#else // LP64
1241412395

1241512396
// 64bit only pieces of the assembler
1241612397

12417-
void Assembler::set_byte_if_not_zero(Register dst) {
12418-
int enc = prefix_and_encode(dst->encoding(), true);
12419-
emit_int24(0x0F, (unsigned char)0x95, (0xC0 | enc));
12420-
}
12421-
1242212398
// This should only be used by 64bit instructions that can use rip-relative
1242312399
// it cannot be used by instructions that want an immediate value.
1242412400

src/hotspot/cpu/x86/assembler_x86.hpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2087,10 +2087,6 @@ class Assembler : public AbstractAssembler {
20872087

20882088
void setb(Condition cc, Register dst);
20892089

2090-
void sete(Register dst);
2091-
void setl(Register dst);
2092-
void setne(Register dst);
2093-
20942090
void palignr(XMMRegister dst, XMMRegister src, int imm8);
20952091
void vpalignr(XMMRegister dst, XMMRegister src1, XMMRegister src2, int imm8, int vector_len);
20962092
void evalignq(XMMRegister dst, XMMRegister nds, XMMRegister src, uint8_t imm8);
@@ -2238,8 +2234,6 @@ class Assembler : public AbstractAssembler {
22382234
void xorq(Register dst, int32_t imm32);
22392235
void xorq(Address dst, Register src);
22402236

2241-
void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0
2242-
22432237
// AVX 3-operands scalar instructions (encoded with VEX prefix)
22442238

22452239
void vaddsd(XMMRegister dst, XMMRegister nds, Address src);

src/hotspot/cpu/x86/c1_LIRAssembler_x86.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2834,7 +2834,7 @@ void LIR_Assembler::comp_fl2i(LIR_Code code, LIR_Opr left, LIR_Opr right, LIR_Op
28342834
__ cmpptr(left->as_register_lo(), right->as_register_lo());
28352835
__ movl(dest, -1);
28362836
__ jccb(Assembler::less, done);
2837-
__ set_byte_if_not_zero(dest);
2837+
__ setb(Assembler::notZero, dest);
28382838
__ movzbl(dest, dest);
28392839
__ bind(done);
28402840
#else

src/hotspot/cpu/x86/x86_64.ad

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8093,7 +8093,7 @@ instruct compareAndSwapP(rRegI res,
80938093
ins_encode %{
80948094
__ lock();
80958095
__ cmpxchgq($newval$$Register, $mem_ptr$$Address);
8096-
__ sete($res$$Register);
8096+
__ setb(Assembler::equal, $res$$Register);
80978097
__ movzbl($res$$Register, $res$$Register);
80988098
%}
80998099
ins_pipe( pipe_cmpxchg );
@@ -8116,7 +8116,7 @@ instruct compareAndSwapL(rRegI res,
81168116
ins_encode %{
81178117
__ lock();
81188118
__ cmpxchgq($newval$$Register, $mem_ptr$$Address);
8119-
__ sete($res$$Register);
8119+
__ setb(Assembler::equal, $res$$Register);
81208120
__ movzbl($res$$Register, $res$$Register);
81218121
%}
81228122
ins_pipe( pipe_cmpxchg );
@@ -8138,7 +8138,7 @@ instruct compareAndSwapI(rRegI res,
81388138
ins_encode %{
81398139
__ lock();
81408140
__ cmpxchgl($newval$$Register, $mem_ptr$$Address);
8141-
__ sete($res$$Register);
8141+
__ setb(Assembler::equal, $res$$Register);
81428142
__ movzbl($res$$Register, $res$$Register);
81438143
%}
81448144
ins_pipe( pipe_cmpxchg );
@@ -8160,7 +8160,7 @@ instruct compareAndSwapB(rRegI res,
81608160
ins_encode %{
81618161
__ lock();
81628162
__ cmpxchgb($newval$$Register, $mem_ptr$$Address);
8163-
__ sete($res$$Register);
8163+
__ setb(Assembler::equal, $res$$Register);
81648164
__ movzbl($res$$Register, $res$$Register);
81658165
%}
81668166
ins_pipe( pipe_cmpxchg );
@@ -8182,7 +8182,7 @@ instruct compareAndSwapS(rRegI res,
81828182
ins_encode %{
81838183
__ lock();
81848184
__ cmpxchgw($newval$$Register, $mem_ptr$$Address);
8185-
__ sete($res$$Register);
8185+
__ setb(Assembler::equal, $res$$Register);
81868186
__ movzbl($res$$Register, $res$$Register);
81878187
%}
81888188
ins_pipe( pipe_cmpxchg );
@@ -8203,7 +8203,7 @@ instruct compareAndSwapN(rRegI res,
82038203
ins_encode %{
82048204
__ lock();
82058205
__ cmpxchgl($newval$$Register, $mem_ptr$$Address);
8206-
__ sete($res$$Register);
8206+
__ setb(Assembler::equal, $res$$Register);
82078207
__ movzbl($res$$Register, $res$$Register);
82088208
%}
82098209
ins_pipe( pipe_cmpxchg );
@@ -10626,40 +10626,6 @@ instruct xorL_mem_imm(memory dst, immL32 src, rFlagsReg cr)
1062610626
ins_pipe(ialu_mem_imm);
1062710627
%}
1062810628

10629-
// Convert Int to Boolean
10630-
instruct convI2B(rRegI dst, rRegI src, rFlagsReg cr)
10631-
%{
10632-
match(Set dst (Conv2B src));
10633-
effect(KILL cr);
10634-
10635-
format %{ "testl $src, $src\t# ci2b\n\t"
10636-
"setnz $dst\n\t"
10637-
"movzbl $dst, $dst" %}
10638-
ins_encode %{
10639-
__ testl($src$$Register, $src$$Register);
10640-
__ set_byte_if_not_zero($dst$$Register);
10641-
__ movzbl($dst$$Register, $dst$$Register);
10642-
%}
10643-
ins_pipe(pipe_slow); // XXX
10644-
%}
10645-
10646-
// Convert Pointer to Boolean
10647-
instruct convP2B(rRegI dst, rRegP src, rFlagsReg cr)
10648-
%{
10649-
match(Set dst (Conv2B src));
10650-
effect(KILL cr);
10651-
10652-
format %{ "testq $src, $src\t# cp2b\n\t"
10653-
"setnz $dst\n\t"
10654-
"movzbl $dst, $dst" %}
10655-
ins_encode %{
10656-
__ testq($src$$Register, $src$$Register);
10657-
__ set_byte_if_not_zero($dst$$Register);
10658-
__ movzbl($dst$$Register, $dst$$Register);
10659-
%}
10660-
ins_pipe(pipe_slow); // XXX
10661-
%}
10662-
1066310629
instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr)
1066410630
%{
1066510631
match(Set dst (CmpLTMask p q));
@@ -10672,7 +10638,7 @@ instruct cmpLTMask(rRegI dst, rRegI p, rRegI q, rFlagsReg cr)
1067210638
"negl $dst" %}
1067310639
ins_encode %{
1067410640
__ cmpl($p$$Register, $q$$Register);
10675-
__ setl($dst$$Register);
10641+
__ setb(Assembler::less, $dst$$Register);
1067610642
__ movzbl($dst$$Register, $dst$$Register);
1067710643
__ negl($dst$$Register);
1067810644
%}
@@ -12828,7 +12794,7 @@ instruct cmpU3_reg_reg(rRegI dst, rRegI src1, rRegI src2, rFlagsReg flags)
1282812794
__ cmpl($src1$$Register, $src2$$Register);
1282912795
__ movl($dst$$Register, -1);
1283012796
__ jccb(Assembler::below, done);
12831-
__ setne($dst$$Register);
12797+
__ setb(Assembler::notZero, $dst$$Register);
1283212798
__ movzbl($dst$$Register, $dst$$Register);
1283312799
__ bind(done);
1283412800
%}
@@ -12854,7 +12820,7 @@ instruct cmpL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
1285412820
__ cmpq($src1$$Register, $src2$$Register);
1285512821
__ movl($dst$$Register, -1);
1285612822
__ jccb(Assembler::less, done);
12857-
__ setne($dst$$Register);
12823+
__ setb(Assembler::notZero, $dst$$Register);
1285812824
__ movzbl($dst$$Register, $dst$$Register);
1285912825
__ bind(done);
1286012826
%}
@@ -12880,7 +12846,7 @@ instruct cmpUL3_reg_reg(rRegI dst, rRegL src1, rRegL src2, rFlagsReg flags)
1288012846
__ cmpq($src1$$Register, $src2$$Register);
1288112847
__ movl($dst$$Register, -1);
1288212848
__ jccb(Assembler::below, done);
12883-
__ setne($dst$$Register);
12849+
__ setb(Assembler::notZero, $dst$$Register);
1288412850
__ movzbl($dst$$Register, $dst$$Register);
1288512851
__ bind(done);
1288612852
%}

src/hotspot/share/opto/addnode.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,34 @@ Node* XorINode::Ideal(PhaseGVN* phase, bool can_reshape) {
886886
phase->record_for_igvn(this);
887887
}
888888
}
889+
890+
// Propagate xor through constant cmoves. This pattern can occur after expansion of Conv2B nodes.
891+
const TypeInt* in2_type = phase->type(in2)->isa_int();
892+
if (in1->Opcode() == Op_CMoveI && in2_type != nullptr && in2_type->is_con()) {
893+
int in2_val = in2_type->get_con();
894+
895+
// Get types of both sides of the CMove
896+
const TypeInt* left = phase->type(in1->in(CMoveNode::IfFalse))->isa_int();
897+
const TypeInt* right = phase->type(in1->in(CMoveNode::IfTrue))->isa_int();
898+
899+
// Ensure that both sides are int constants
900+
if (left != nullptr && right != nullptr && left->is_con() && right->is_con()) {
901+
Node* cond = in1->in(CMoveNode::Condition);
902+
903+
// Check that the comparison is a bool and that the cmp node type is correct
904+
if (cond->is_Bool()) {
905+
int cmp_op = cond->in(1)->Opcode();
906+
907+
if (cmp_op == Op_CmpI || cmp_op == Op_CmpP) {
908+
int l_val = left->get_con();
909+
int r_val = right->get_con();
910+
911+
return new CMoveINode(cond, phase->intcon(l_val ^ in2_val), phase->intcon(r_val ^ in2_val), TypeInt::INT);
912+
}
913+
}
914+
}
915+
}
916+
889917
return AddNode::Ideal(phase, can_reshape);
890918
}
891919

src/hotspot/share/opto/cfgnode.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,6 +1522,12 @@ Node* PhiNode::unique_input(PhaseValues* phase, bool uncast) {
15221522
// Convert Phi to an ConvIB.
15231523
static Node *is_x2logic( PhaseGVN *phase, PhiNode *phi, int true_path ) {
15241524
assert(true_path !=0, "only diamond shape graph expected");
1525+
1526+
// If we're late in the optimization process, we may have already expanded Conv2B nodes
1527+
if (phase->C->post_loop_opts_phase() && !Matcher::match_rule_supported(Op_Conv2B)) {
1528+
return nullptr;
1529+
}
1530+
15251531
// Convert the true/false index into an expected 0/1 return.
15261532
// Map 2->0 and 1->1.
15271533
int flipped = 2-true_path;
@@ -1564,9 +1570,10 @@ static Node *is_x2logic( PhaseGVN *phase, PhiNode *phi, int true_path ) {
15641570
} else return nullptr;
15651571

15661572
// Build int->bool conversion
1567-
Node *n = new Conv2BNode(cmp->in(1));
1568-
if( flipped )
1569-
n = new XorINode( phase->transform(n), phase->intcon(1) );
1573+
Node* n = new Conv2BNode(cmp->in(1));
1574+
if (flipped) {
1575+
n = new XorINode(phase->transform(n), phase->intcon(1));
1576+
}
15701577

15711578
return n;
15721579
}

src/hotspot/share/opto/convertnode.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@
2525
#include "precompiled.hpp"
2626
#include "opto/addnode.hpp"
2727
#include "opto/castnode.hpp"
28+
#include "opto/connode.hpp"
2829
#include "opto/convertnode.hpp"
2930
#include "opto/matcher.hpp"
31+
#include "opto/movenode.hpp"
3032
#include "opto/phaseX.hpp"
3133
#include "opto/subnode.hpp"
3234
#include "runtime/stubRoutines.hpp"
@@ -61,6 +63,30 @@ const Type* Conv2BNode::Value(PhaseGVN* phase) const {
6163
return TypeInt::BOOL;
6264
}
6365

66+
Node* Conv2BNode::Ideal(PhaseGVN* phase, bool can_reshape) {
67+
if (!Matcher::match_rule_supported(Op_Conv2B)) {
68+
if (phase->C->post_loop_opts_phase()) {
69+
// Get type of comparison to make
70+
const Type* t = phase->type(in(1));
71+
Node* cmp = nullptr;
72+
if (t->isa_int()) {
73+
cmp = phase->transform(new CmpINode(in(1), phase->intcon(0)));
74+
} else if (t->isa_ptr()) {
75+
cmp = phase->transform(new CmpPNode(in(1), phase->zerocon(BasicType::T_OBJECT)));
76+
} else {
77+
assert(false, "Unrecognized comparison for Conv2B: %s", NodeClassNames[in(1)->Opcode()]);
78+
}
79+
80+
// Replace Conv2B with the cmove
81+
Node* bol = phase->transform(new BoolNode(cmp, BoolTest::eq));
82+
return new CMoveINode(bol, phase->intcon(1), phase->intcon(0), TypeInt::BOOL);
83+
} else {
84+
phase->C->record_for_post_loop_opts_igvn(this);
85+
}
86+
}
87+
return nullptr;
88+
}
89+
6490

6591
// The conversions operations are all Alpha sorted. Please keep it that way!
6692
//=============================================================================

0 commit comments

Comments
 (0)