8209544: AES encrypt performance regression in jdk11b11
authorroland
Thu, 06 Sep 2018 16:27:07 +0200
changeset 51666 7e6b86eb7914
parent 51665 cda49f297cb1
child 51667 799cddff49fe
8209544: AES encrypt performance regression in jdk11b11 Reviewed-by: kvn, vlivanov
src/hotspot/share/opto/subnode.cpp
--- 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) ) {