Skip to content

Commit 599d07c

Browse files
Wang HuangWu Yan
authored andcommitted
8263006: Add optimization for Max(*)Node and Min(*)Node
Co-authored-by: Wang Huang <whuang@openjdk.org> Co-authored-by: Wu Yan <wuyan34@huawei.com> Reviewed-by: kvn
1 parent 16ca370 commit 599d07c

File tree

6 files changed

+473
-10
lines changed

6 files changed

+473
-10
lines changed

src/hotspot/share/opto/addnode.cpp

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,35 @@ Node* AddNode::Identity(PhaseGVN* phase) {
6262

6363
//------------------------------commute----------------------------------------
6464
// Commute operands to move loads and constants to the right.
65-
static bool commute(Node *add, bool con_left, bool con_right) {
65+
static bool commute(PhaseGVN* phase, Node* add) {
6666
Node *in1 = add->in(1);
6767
Node *in2 = add->in(2);
6868

69+
// convert "max(a,b) + min(a,b)" into "a+b".
70+
if ((in1->Opcode() == add->as_Add()->max_opcode() && in2->Opcode() == add->as_Add()->min_opcode())
71+
|| (in1->Opcode() == add->as_Add()->min_opcode() && in2->Opcode() == add->as_Add()->max_opcode())) {
72+
Node *in11 = in1->in(1);
73+
Node *in12 = in1->in(2);
74+
75+
Node *in21 = in2->in(1);
76+
Node *in22 = in2->in(2);
77+
78+
if ((in11 == in21 && in12 == in22) ||
79+
(in11 == in22 && in12 == in21)) {
80+
add->set_req(1, in11);
81+
add->set_req(2, in12);
82+
PhaseIterGVN* igvn = phase->is_IterGVN();
83+
if (igvn) {
84+
igvn->_worklist.push(in1);
85+
igvn->_worklist.push(in2);
86+
}
87+
return true;
88+
}
89+
}
90+
91+
bool con_left = phase->type(in1)->singleton();
92+
bool con_right = phase->type(in2)->singleton();
93+
6994
// Convert "1+x" into "x+1".
7095
// Right is a constant; leave it
7196
if( con_right ) return false;
@@ -115,7 +140,7 @@ Node *AddNode::Ideal(PhaseGVN *phase, bool can_reshape) {
115140
bool con_right = t2->singleton();
116141

117142
// Check for commutative operation desired
118-
if (commute(this, con_left, con_right)) return this;
143+
if (commute(phase, this)) return this;
119144

120145
AddNode *progress = NULL; // Progress flag
121146

@@ -539,9 +564,7 @@ Node *AddFNode::Ideal(PhaseGVN *phase, bool can_reshape) {
539564
}
540565

541566
// Floating point additions are not associative because of boundary conditions (infinity)
542-
return commute(this,
543-
phase->type( in(1) )->singleton(),
544-
phase->type( in(2) )->singleton() ) ? this : NULL;
567+
return commute(phase, this) ? this : NULL;
545568
}
546569

547570

@@ -576,9 +599,7 @@ Node *AddDNode::Ideal(PhaseGVN *phase, bool can_reshape) {
576599
}
577600

578601
// Floating point additions are not associative because of boundary conditions (infinity)
579-
return commute(this,
580-
phase->type( in(1) )->singleton(),
581-
phase->type( in(2) )->singleton() ) ? this : NULL;
602+
return commute(phase, this) ? this : NULL;
582603
}
583604

584605

src/hotspot/share/opto/addnode.hpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ class AddNode : public Node {
6868
// Supplied function to return the additive identity type
6969
virtual const Type *add_id() const = 0;
7070

71+
// Supplied function to return the additive opcode
72+
virtual int max_opcode() const = 0;
73+
74+
// Supplied function to return the multiplicative opcode
75+
virtual int min_opcode() const = 0;
76+
7177
virtual bool operates_on(BasicType bt, bool signed_int) const {
7278
assert(bt == T_INT || bt == T_LONG, "unsupported");
7379
return false;
@@ -84,6 +90,8 @@ class AddINode : public AddNode {
8490
virtual const Type *add_ring( const Type *, const Type * ) const;
8591
virtual const Type *add_id() const { return TypeInt::ZERO; }
8692
virtual const Type *bottom_type() const { return TypeInt::INT; }
93+
int max_opcode() const { return Op_MaxI; }
94+
int min_opcode() const { return Op_MinI; }
8795
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
8896
virtual Node* Identity(PhaseGVN* phase);
8997
virtual bool operates_on(BasicType bt, bool signed_int) const {
@@ -102,6 +110,8 @@ class AddLNode : public AddNode {
102110
virtual const Type *add_ring( const Type *, const Type * ) const;
103111
virtual const Type *add_id() const { return TypeLong::ZERO; }
104112
virtual const Type *bottom_type() const { return TypeLong::LONG; }
113+
int max_opcode() const { return Op_MaxL; }
114+
int min_opcode() const { return Op_MinL; }
105115
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
106116
virtual Node* Identity(PhaseGVN* phase);
107117
virtual bool operates_on(BasicType bt, bool signed_int) const {
@@ -122,6 +132,8 @@ class AddFNode : public AddNode {
122132
virtual const Type *add_ring( const Type *, const Type * ) const;
123133
virtual const Type *add_id() const { return TypeF::ZERO; }
124134
virtual const Type *bottom_type() const { return Type::FLOAT; }
135+
int max_opcode() const { return Op_MaxF; }
136+
int min_opcode() const { return Op_MinF; }
125137
virtual Node* Identity(PhaseGVN* phase) { return this; }
126138
virtual uint ideal_reg() const { return Op_RegF; }
127139
};
@@ -137,6 +149,8 @@ class AddDNode : public AddNode {
137149
virtual const Type *add_ring( const Type *, const Type * ) const;
138150
virtual const Type *add_id() const { return TypeD::ZERO; }
139151
virtual const Type *bottom_type() const { return Type::DOUBLE; }
152+
int max_opcode() const { return Op_MaxD; }
153+
int min_opcode() const { return Op_MinD; }
140154
virtual Node* Identity(PhaseGVN* phase) { return this; }
141155
virtual uint ideal_reg() const { return Op_RegD; }
142156
};
@@ -183,6 +197,8 @@ class OrINode : public AddNode {
183197
virtual const Type *add_ring( const Type *, const Type * ) const;
184198
virtual const Type *add_id() const { return TypeInt::ZERO; }
185199
virtual const Type *bottom_type() const { return TypeInt::INT; }
200+
int max_opcode() const { return Op_MaxI; }
201+
int min_opcode() const { return Op_MinI; }
186202
virtual Node* Identity(PhaseGVN* phase);
187203
virtual uint ideal_reg() const { return Op_RegI; }
188204
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
@@ -198,6 +214,8 @@ class OrLNode : public AddNode {
198214
virtual const Type *add_ring( const Type *, const Type * ) const;
199215
virtual const Type *add_id() const { return TypeLong::ZERO; }
200216
virtual const Type *bottom_type() const { return TypeLong::LONG; }
217+
int max_opcode() const { return Op_MaxL; }
218+
int min_opcode() const { return Op_MinL; }
201219
virtual Node* Identity(PhaseGVN* phase);
202220
virtual uint ideal_reg() const { return Op_RegL; }
203221
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
@@ -212,6 +230,8 @@ class XorINode : public AddNode {
212230
virtual const Type *add_ring( const Type *, const Type * ) const;
213231
virtual const Type *add_id() const { return TypeInt::ZERO; }
214232
virtual const Type *bottom_type() const { return TypeInt::INT; }
233+
int max_opcode() const { return Op_MaxI; }
234+
int min_opcode() const { return Op_MinI; }
215235
virtual const Type *Value(PhaseGVN *phase) const;
216236
virtual uint ideal_reg() const { return Op_RegI; }
217237
};
@@ -225,6 +245,8 @@ class XorLNode : public AddNode {
225245
virtual const Type *add_ring( const Type *, const Type * ) const;
226246
virtual const Type *add_id() const { return TypeLong::ZERO; }
227247
virtual const Type *bottom_type() const { return TypeLong::LONG; }
248+
int max_opcode() const { return Op_MaxL; }
249+
int min_opcode() const { return Op_MinL; }
228250
virtual const Type *Value(PhaseGVN *phase) const;
229251
virtual uint ideal_reg() const { return Op_RegL; }
230252
};
@@ -241,6 +263,8 @@ class MaxNode : public AddNode {
241263
public:
242264
MaxNode( Node *in1, Node *in2 ) : AddNode(in1,in2) {}
243265
virtual int Opcode() const = 0;
266+
virtual int max_opcode() const = 0;
267+
virtual int min_opcode() const = 0;
244268

245269
static Node* unsigned_max(Node* a, Node* b, const Type* t, PhaseGVN& gvn) {
246270
return build_min_max(a, b, true, true, t, gvn);
@@ -280,6 +304,8 @@ class MaxINode : public MaxNode {
280304
virtual const Type *add_id() const { return TypeInt::make(min_jint); }
281305
virtual const Type *bottom_type() const { return TypeInt::INT; }
282306
virtual uint ideal_reg() const { return Op_RegI; }
307+
int max_opcode() const { return Op_MaxI; }
308+
int min_opcode() const { return Op_MinI; }
283309
};
284310

285311
//------------------------------MinINode---------------------------------------
@@ -293,6 +319,8 @@ class MinINode : public MaxNode {
293319
virtual const Type *add_id() const { return TypeInt::make(max_jint); }
294320
virtual const Type *bottom_type() const { return TypeInt::INT; }
295321
virtual uint ideal_reg() const { return Op_RegI; }
322+
int max_opcode() const { return Op_MaxI; }
323+
int min_opcode() const { return Op_MinI; }
296324
virtual Node *Ideal(PhaseGVN *phase, bool can_reshape);
297325
};
298326

@@ -306,6 +334,8 @@ class MaxLNode : public MaxNode {
306334
virtual const Type *add_id() const { return TypeLong::make(min_jlong); }
307335
virtual const Type *bottom_type() const { return TypeLong::LONG; }
308336
virtual uint ideal_reg() const { return Op_RegL; }
337+
int max_opcode() const { return Op_MaxL; }
338+
int min_opcode() const { return Op_MinL; }
309339
};
310340

311341
//------------------------------MinLNode---------------------------------------
@@ -318,6 +348,8 @@ class MinLNode : public MaxNode {
318348
virtual const Type *add_id() const { return TypeLong::make(max_jlong); }
319349
virtual const Type *bottom_type() const { return TypeLong::LONG; }
320350
virtual uint ideal_reg() const { return Op_RegL; }
351+
int max_opcode() const { return Op_MaxL; }
352+
int min_opcode() const { return Op_MinL; }
321353
};
322354

323355
//------------------------------MaxFNode---------------------------------------
@@ -330,6 +362,8 @@ class MaxFNode : public MaxNode {
330362
virtual const Type *add_id() const { return TypeF::NEG_INF; }
331363
virtual const Type *bottom_type() const { return Type::FLOAT; }
332364
virtual uint ideal_reg() const { return Op_RegF; }
365+
int max_opcode() const { return Op_MaxF; }
366+
int min_opcode() const { return Op_MinF; }
333367
};
334368

335369
//------------------------------MinFNode---------------------------------------
@@ -342,6 +376,8 @@ class MinFNode : public MaxNode {
342376
virtual const Type *add_id() const { return TypeF::POS_INF; }
343377
virtual const Type *bottom_type() const { return Type::FLOAT; }
344378
virtual uint ideal_reg() const { return Op_RegF; }
379+
int max_opcode() const { return Op_MaxF; }
380+
int min_opcode() const { return Op_MinF; }
345381
};
346382

347383
//------------------------------MaxDNode---------------------------------------
@@ -354,6 +390,8 @@ class MaxDNode : public MaxNode {
354390
virtual const Type *add_id() const { return TypeD::NEG_INF; }
355391
virtual const Type *bottom_type() const { return Type::DOUBLE; }
356392
virtual uint ideal_reg() const { return Op_RegD; }
393+
int max_opcode() const { return Op_MaxD; }
394+
int min_opcode() const { return Op_MinD; }
357395
};
358396

359397
//------------------------------MinDNode---------------------------------------
@@ -366,6 +404,8 @@ class MinDNode : public MaxNode {
366404
virtual const Type *add_id() const { return TypeD::POS_INF; }
367405
virtual const Type *bottom_type() const { return Type::DOUBLE; }
368406
virtual uint ideal_reg() const { return Op_RegD; }
407+
int max_opcode() const { return Op_MaxD; }
408+
int min_opcode() const { return Op_MinD; }
369409
};
370410

371411
#endif // SHARE_OPTO_ADDNODE_HPP

src/hotspot/share/opto/mulnode.cpp

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -62,6 +62,31 @@ Node *MulNode::Ideal(PhaseGVN *phase, bool can_reshape) {
6262
const Type *t1 = phase->type( in(1) );
6363
const Type *t2 = phase->type( in(2) );
6464
Node *progress = NULL; // Progress flag
65+
66+
// convert "max(a,b) * min(a,b)" into "a*b".
67+
Node *in1 = in(1);
68+
Node *in2 = in(2);
69+
if ((in(1)->Opcode() == max_opcode() && in(2)->Opcode() == min_opcode())
70+
|| (in(1)->Opcode() == min_opcode() && in(2)->Opcode() == max_opcode())) {
71+
Node *in11 = in(1)->in(1);
72+
Node *in12 = in(1)->in(2);
73+
74+
Node *in21 = in(2)->in(1);
75+
Node *in22 = in(2)->in(2);
76+
77+
if ((in11 == in21 && in12 == in22) ||
78+
(in11 == in22 && in12 == in21)) {
79+
set_req(1, in11);
80+
set_req(2, in12);
81+
PhaseIterGVN* igvn = phase->is_IterGVN();
82+
if (igvn) {
83+
igvn->_worklist.push(in1);
84+
igvn->_worklist.push(in2);
85+
}
86+
progress = this;
87+
}
88+
}
89+
6590
// We are OK if right is a constant, or right is a load and
6691
// left is a non-constant.
6792
if( !(t2->singleton() ||

src/hotspot/share/opto/mulnode.hpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -75,6 +75,11 @@ class MulNode : public Node {
7575
// Supplied function to return the multiplicative opcode
7676
virtual int mul_opcode() const = 0;
7777

78+
// Supplied function to return the additive opcode
79+
virtual int max_opcode() const = 0;
80+
81+
// Supplied function to return the multiplicative opcode
82+
virtual int min_opcode() const = 0;
7883
};
7984

8085
//------------------------------MulINode---------------------------------------
@@ -89,6 +94,8 @@ class MulINode : public MulNode {
8994
const Type *add_id() const { return TypeInt::ZERO; }
9095
int add_opcode() const { return Op_AddI; }
9196
int mul_opcode() const { return Op_MulI; }
97+
int max_opcode() const { return Op_MaxI; }
98+
int min_opcode() const { return Op_MinI; }
9299
const Type *bottom_type() const { return TypeInt::INT; }
93100
virtual uint ideal_reg() const { return Op_RegI; }
94101
};
@@ -105,6 +112,8 @@ class MulLNode : public MulNode {
105112
const Type *add_id() const { return TypeLong::ZERO; }
106113
int add_opcode() const { return Op_AddL; }
107114
int mul_opcode() const { return Op_MulL; }
115+
int max_opcode() const { return Op_MaxL; }
116+
int min_opcode() const { return Op_MinL; }
108117
const Type *bottom_type() const { return TypeLong::LONG; }
109118
virtual uint ideal_reg() const { return Op_RegL; }
110119
};
@@ -121,6 +130,8 @@ class MulFNode : public MulNode {
121130
const Type *add_id() const { return TypeF::ZERO; }
122131
int add_opcode() const { return Op_AddF; }
123132
int mul_opcode() const { return Op_MulF; }
133+
int max_opcode() const { return Op_MaxF; }
134+
int min_opcode() const { return Op_MinF; }
124135
const Type *bottom_type() const { return Type::FLOAT; }
125136
virtual uint ideal_reg() const { return Op_RegF; }
126137
};
@@ -136,6 +147,8 @@ class MulDNode : public MulNode {
136147
const Type *add_id() const { return TypeD::ZERO; }
137148
int add_opcode() const { return Op_AddD; }
138149
int mul_opcode() const { return Op_MulD; }
150+
int max_opcode() const { return Op_MaxD; }
151+
int min_opcode() const { return Op_MinD; }
139152
const Type *bottom_type() const { return Type::DOUBLE; }
140153
virtual uint ideal_reg() const { return Op_RegD; }
141154
};
@@ -165,6 +178,8 @@ class AndINode : public MulINode {
165178
const Type *add_id() const { return TypeInt::ZERO; }
166179
int add_opcode() const { return Op_OrI; }
167180
int mul_opcode() const { return Op_AndI; }
181+
int max_opcode() const { return Op_MaxI; }
182+
int min_opcode() const { return Op_MinI; }
168183
virtual uint ideal_reg() const { return Op_RegI; }
169184
};
170185

@@ -182,6 +197,8 @@ class AndLNode : public MulLNode {
182197
const Type *add_id() const { return TypeLong::ZERO; }
183198
int add_opcode() const { return Op_OrL; }
184199
int mul_opcode() const { return Op_AndL; }
200+
int max_opcode() const { return Op_MaxL; }
201+
int min_opcode() const { return Op_MinL; }
185202
virtual uint ideal_reg() const { return Op_RegL; }
186203
};
187204

0 commit comments

Comments
 (0)