8209544: AES encrypt performance regression in jdk11b11
Reviewed-by: kvn, vlivanov
This commit is contained in:
parent
25280e30d4
commit
052a740695
@ -1348,6 +1348,15 @@ Node* BoolNode::fold_cmpI(PhaseGVN* phase, SubNode* cmp, Node* cmp1, int cmp_op,
|
||||
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 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// 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 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// 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 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
}
|
||||
}
|
||||
|
||||
// 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 @@ Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
||||
// 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) ) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user