Skip to content

Commit ba7c0a6

Browse files
Do not eagerly replace shift amounts in nested lshift
1 parent 6dcc6c1 commit ba7c0a6

File tree

1 file changed

+48
-28
lines changed

1 file changed

+48
-28
lines changed

Diff for: src/hotspot/share/opto/mulnode.cpp

+48-28
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,8 @@ LShiftNode* LShiftNode::make(Node* in1, Node* in2, BasicType bt) {
952952

953953
//=============================================================================
954954

955-
static bool const_shift_count(PhaseGVN* phase, Node* shiftNode, int* count) {
955+
// Returns whether the shift amount is constant. If so, sets count.
956+
static bool const_shift_count(PhaseGVN* phase, const Node* shiftNode, int* count) {
956957
const TypeInt* tcount = phase->type(shiftNode->in(2))->isa_int();
957958
if (tcount != nullptr && tcount->is_con()) {
958959
*count = tcount->get_con();
@@ -961,53 +962,72 @@ static bool const_shift_count(PhaseGVN* phase, Node* shiftNode, int* count) {
961962
return false;
962963
}
963964

964-
static int maskShiftAmount(PhaseGVN* phase, Node* shiftNode, uint nBits) {
965-
int count = 0;
966-
if (const_shift_count(phase, shiftNode, &count)) {
967-
int maskedShift = count & (nBits - 1);
968-
if (maskedShift == 0) {
965+
// Returns whether the shift amount is constant. If so, sets real_shift and masked_shift.
966+
static bool mask_shift_amount(PhaseGVN* phase, const Node* shiftNode, uint nBits, int& real_shift, int& masked_shift) {
967+
if (const_shift_count(phase, shiftNode, &real_shift)) {
968+
masked_shift = real_shift & (nBits - 1);
969+
return true;
970+
}
971+
return false;
972+
}
973+
974+
// Convenience for when we don't care about the real amount
975+
static bool mask_shift_amount(PhaseGVN* phase, const Node* shiftNode, uint nBits, int& masked_shift) {
976+
int real_shift;
977+
return mask_shift_amount(phase, shiftNode, nBits, real_shift, masked_shift);
978+
}
979+
980+
// Use this in ::Ideal only with shiftNode == this!
981+
// Returns the masked shift amount if constant or 0 if not constant.
982+
static int mask_and_replace_shift_amount(PhaseGVN* phase, Node* shiftNode, uint nBits) {
983+
int real_shift;
984+
int masked_shift;
985+
if (mask_shift_amount(phase, shiftNode, nBits, real_shift, masked_shift)) {
986+
if (masked_shift == 0) {
969987
// Let Identity() handle 0 shift count.
970988
return 0;
971989
}
972990

973-
if (count != maskedShift) {
991+
if (real_shift != masked_shift) {
974992
PhaseIterGVN* igvn = phase->is_IterGVN();
975-
if (igvn) {
993+
if (igvn != nullptr) {
976994
igvn->rehash_node_delayed(shiftNode);
977995
}
978-
shiftNode->set_req(2, phase->intcon(maskedShift)); // Replace shift count with masked value.
996+
shiftNode->set_req(2, phase->intcon(masked_shift)); // Replace shift count with masked value.
979997
}
980-
return maskedShift;
998+
return masked_shift;
981999
}
1000+
// Not a shift by a constant.
9821001
return 0;
9831002
}
9841003

9851004
// Called with
986-
// outer_shift = (_ << con0)
1005+
// outer_shift = (_ << rhs0)
9871006
// We are looking for the pattern:
988-
// outer_shift = ((X << con1) << con0)
989-
// we denote inner_shift the nested expression (X << con1)
990-
//
991-
// con0 and con1 are both in [0..nbits), as they are computed by maskShiftAmount.
1007+
// outer_shift = ((X << rhs1) << rhs0)
1008+
// where rhs0 and rhs1 are constant
1009+
// we denote inner_shift the nested expression (X << rhs1)
1010+
// con0 = rhs1 % nbits and con0 = rhs1 % nbits
1011+
// where nbits is the number of bits of the shifts
9921012
//
9931013
// There are 2 cases:
9941014
// if con0 + con1 >= nbits => 0
9951015
// if con0 + con1 < nbits => X << (con1 + con0)
996-
static Node* collapse_nested_shift_left(PhaseGVN* phase, Node* outer_shift, int con0, BasicType bt) {
1016+
static Node* collapse_nested_shift_left(PhaseGVN* phase, const Node* outer_shift, int con0, BasicType bt) {
9971017
assert(bt == T_LONG || bt == T_INT, "Unexpected type");
998-
Node* inner_shift = outer_shift->in(1);
1018+
const Node* inner_shift = outer_shift->in(1);
9991019
if (inner_shift->Opcode() != Op_LShift(bt)) {
10001020
return nullptr;
10011021
}
10021022

1003-
if (!phase->is_IterGVN()) {
1004-
phase->record_for_igvn(outer_shift);
1023+
int nbits = static_cast<int>(bits_per_java_integer(bt));
1024+
int con1;
1025+
if (!mask_shift_amount(phase, inner_shift, nbits, con1)) {
10051026
return nullptr;
10061027
}
10071028

1008-
int nbits = static_cast<int>(bits_per_java_integer(bt));
1009-
int con1 = maskShiftAmount(phase, inner_shift, nbits);
1010-
if (con1 == 0) { // Either non-const, or actually 0 (up to mask) and then delegated to Identity()
1029+
if (con1 == 0) {
1030+
// We let the Identity() of the inner shift do its job.
10111031
return nullptr;
10121032
}
10131033

@@ -1041,7 +1061,7 @@ Node* LShiftINode::Identity(PhaseGVN* phase) {
10411061
// Also collapse nested left-shifts with constant rhs:
10421062
// (X << con1) << con2 ==> X << (con1 + con2)
10431063
Node *LShiftINode::Ideal(PhaseGVN *phase, bool can_reshape) {
1044-
int con = maskShiftAmount(phase, this, BitsPerJavaInteger);
1064+
int con = mask_and_replace_shift_amount(phase, this, BitsPerJavaInteger);
10451065
if (con == 0) {
10461066
return nullptr;
10471067
}
@@ -1227,7 +1247,7 @@ Node* LShiftLNode::Identity(PhaseGVN* phase) {
12271247
// Also collapse nested left-shifts with constant rhs:
12281248
// (X << con1) << con2 ==> X << (con1 + con2)
12291249
Node *LShiftLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
1230-
int con = maskShiftAmount(phase, this, BitsPerJavaLong);
1250+
int con = mask_and_replace_shift_amount(phase, this, BitsPerJavaLong);
12311251
if (con == 0) {
12321252
return nullptr;
12331253
}
@@ -1448,7 +1468,7 @@ Node* RShiftNode::IdealIL(PhaseGVN* phase, bool can_reshape, BasicType bt) {
14481468
if (t1 == nullptr) {
14491469
return NodeSentinel; // Left input is an integer
14501470
}
1451-
int shift = maskShiftAmount(phase, this, bits_per_java_integer(bt));
1471+
int shift = mask_and_replace_shift_amount(phase, this, bits_per_java_integer(bt));
14521472
if (shift == 0) {
14531473
return NodeSentinel;
14541474
}
@@ -1478,7 +1498,7 @@ Node* RShiftINode::Ideal(PhaseGVN* phase, bool can_reshape) {
14781498
if (progress != nullptr) {
14791499
return progress;
14801500
}
1481-
int shift = maskShiftAmount(phase, this, BitsPerJavaInteger);
1501+
int shift = mask_and_replace_shift_amount(phase, this, BitsPerJavaInteger);
14821502
assert(shift != 0, "handled by IdealIL");
14831503

14841504
// Check for "(short[i] <<16)>>16" which simply sign-extends
@@ -1665,7 +1685,7 @@ Node* URShiftINode::Identity(PhaseGVN* phase) {
16651685

16661686
//------------------------------Ideal------------------------------------------
16671687
Node *URShiftINode::Ideal(PhaseGVN *phase, bool can_reshape) {
1668-
int con = maskShiftAmount(phase, this, BitsPerJavaInteger);
1688+
int con = mask_and_replace_shift_amount(phase, this, BitsPerJavaInteger);
16691689
if (con == 0) {
16701690
return nullptr;
16711691
}
@@ -1829,7 +1849,7 @@ Node* URShiftLNode::Identity(PhaseGVN* phase) {
18291849

18301850
//------------------------------Ideal------------------------------------------
18311851
Node *URShiftLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
1832-
int con = maskShiftAmount(phase, this, BitsPerJavaLong);
1852+
int con = mask_and_replace_shift_amount(phase, this, BitsPerJavaLong);
18331853
if (con == 0) {
18341854
return nullptr;
18351855
}

0 commit comments

Comments
 (0)