8209544: AES encrypt performance regression in jdk11b11
Reviewed-by: kvn, vlivanov
--- a/src/hotspot/share/opto/subnode.cpp Thu Sep 06 17:45:15 2018 -0700
+++ b/src/hotspot/share/opto/subnode.cpp Thu Sep 06 16:27:07 2018 +0200
@@ -1348,6 +1348,15 @@
return NULL;
}
+static bool is_counted_loop_cmp(Node *cmp) {
+ Node *n = cmp->in(1)->in(1);
+ return n != NULL &&
+ n->is_Phi() &&
+ n->in(0) != NULL &&
+ n->in(0)->is_CountedLoop() &&
+ n->in(0)->as_CountedLoop()->phi() == n;
+}
+
//------------------------------Ideal------------------------------------------
Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Change "bool tst (cmp con x)" into "bool ~tst (cmp x con)".
@@ -1406,7 +1415,7 @@
// Change ((x & m) u<= m) or ((m & x) u<= m) to always true
// Same with ((x & m) u< m+1) and ((m & x) u< m+1)
if (cop == Op_CmpU &&
- cmp1->Opcode() == Op_AndI) {
+ cmp1_op == Op_AndI) {
Node* bound = NULL;
if (_test._test == BoolTest::le) {
bound = cmp2;
@@ -1424,7 +1433,7 @@
// This is the off-by-one variant of the above
if (cop == Op_CmpU &&
_test._test == BoolTest::lt &&
- cmp1->Opcode() == Op_AndI) {
+ cmp1_op == Op_AndI) {
Node* l = cmp1->in(1);
Node* r = cmp1->in(2);
for (int repeat = 0; repeat < 2; repeat++) {
@@ -1445,13 +1454,24 @@
}
}
+ // Change x u< 1 or x u<= 0 to x == 0
+ if (cop == Op_CmpU &&
+ cmp1_op != Op_LoadRange &&
+ ((_test._test == BoolTest::lt &&
+ cmp2->find_int_con(-1) == 1) ||
+ (_test._test == BoolTest::le &&
+ cmp2->find_int_con(-1) == 0))) {
+ Node* ncmp = phase->transform(new CmpINode(cmp1, phase->intcon(0)));
+ return new BoolNode(ncmp, BoolTest::eq);
+ }
+
// Change (arraylength <= 0) or (arraylength == 0)
// into (arraylength u<= 0)
// Also change (arraylength != 0) into (arraylength u> 0)
// The latter version matches the code pattern generated for
// array range checks, which will more likely be optimized later.
if (cop == Op_CmpI &&
- cmp1->Opcode() == Op_LoadRange &&
+ cmp1_op == Op_LoadRange &&
cmp2->find_int_con(-1) == 0) {
if (_test._test == BoolTest::le || _test._test == BoolTest::eq) {
Node* ncmp = phase->transform(new CmpUNode(cmp1, cmp2));
@@ -1481,17 +1501,32 @@
// due to possible integer overflow.
if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
(cop == Op_CmpI) &&
- (cmp1->Opcode() == Op_SubI) &&
+ (cmp1_op == Op_SubI) &&
( cmp2_type == TypeInt::ZERO ) ) {
Node *ncmp = phase->transform( new CmpINode(cmp1->in(1),cmp1->in(2)));
return new BoolNode( ncmp, _test._test );
}
+ // Same as above but with and AddI of a constant
+ if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
+ cop == Op_CmpI &&
+ cmp1_op == Op_AddI &&
+ cmp1->in(2) != NULL &&
+ phase->type(cmp1->in(2))->isa_int() &&
+ phase->type(cmp1->in(2))->is_int()->is_con() &&
+ cmp2_type == TypeInt::ZERO &&
+ !is_counted_loop_cmp(cmp) // modifying the exit test of a counted loop messes the counted loop shape
+ ) {
+ const TypeInt* cmp1_in2 = phase->type(cmp1->in(2))->is_int();
+ Node *ncmp = phase->transform( new CmpINode(cmp1->in(1),phase->intcon(-cmp1_in2->_hi)));
+ return new BoolNode( ncmp, _test._test );
+ }
+
// Change (-A vs 0) into (A vs 0) by commuting the test. Disallow in the
// most general case because negating 0x80000000 does nothing. Needed for
// the CmpF3/SubI/CmpI idiom.
if( cop == Op_CmpI &&
- cmp1->Opcode() == Op_SubI &&
+ cmp1_op == Op_SubI &&
cmp2_type == TypeInt::ZERO &&
phase->type( cmp1->in(1) ) == TypeInt::ZERO &&
phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) {