Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
8270366: C2: Add associative rule to add/sub node
Reviewed-by: kvn, adinn
  • Loading branch information
zhengyu123 committed Jul 15, 2021
1 parent 1f995e5 commit 746fe5d
Show file tree
Hide file tree
Showing 3 changed files with 374 additions and 0 deletions.
68 changes: 68 additions & 0 deletions src/hotspot/share/opto/addnode.cpp
Expand Up @@ -321,6 +321,40 @@ Node *AddINode::Ideal(PhaseGVN *phase, bool can_reshape) {
if( op1 == Op_SubI && phase->type(in1->in(1)) == TypeInt::ZERO )
return new SubINode( in2, in1->in(2) );

// Associative
if (op1 == Op_MulI && op2 == Op_MulI) {
Node* add_in1 = NULL;
Node* add_in2 = NULL;
Node* mul_in = NULL;

if (in1->in(1) == in2->in(1)) {
// Convert "a*b+a*c into a*(b+c)
add_in1 = in1->in(2);
add_in2 = in2->in(2);
mul_in = in1->in(1);
} else if (in1->in(2) == in2->in(1)) {
// Convert a*b+b*c into b*(a+c)
add_in1 = in1->in(1);
add_in2 = in2->in(2);
mul_in = in1->in(2);
} else if (in1->in(2) == in2->in(2)) {
// Convert a*c+b*c into (a+b)*c
add_in1 = in1->in(1);
add_in2 = in2->in(1);
mul_in = in1->in(2);
} else if (in1->in(1) == in2->in(2)) {
// Convert a*b+c*a into a*(b+c)
add_in1 = in1->in(2);
add_in2 = in2->in(1);
mul_in = in1->in(1);
}

if (mul_in != NULL) {
Node* add = phase->transform(new AddINode(add_in1, add_in2));
return new MulINode(mul_in, add);
}
}

// Convert (x>>>z)+y into (x+(y<<z))>>>z for small constant z and y.
// Helps with array allocation math constant folding
// See 4790063:
Expand Down Expand Up @@ -469,6 +503,40 @@ Node *AddLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
if( op1 == Op_SubL && phase->type(in1->in(1)) == TypeLong::ZERO )
return new SubLNode( in2, in1->in(2) );

// Associative
if (op1 == Op_MulL && op2 == Op_MulL) {
Node* add_in1 = NULL;
Node* add_in2 = NULL;
Node* mul_in = NULL;

if (in1->in(1) == in2->in(1)) {
// Convert "a*b+a*c into a*(b+c)
add_in1 = in1->in(2);
add_in2 = in2->in(2);
mul_in = in1->in(1);
} else if (in1->in(2) == in2->in(1)) {
// Convert a*b+b*c into b*(a+c)
add_in1 = in1->in(1);
add_in2 = in2->in(2);
mul_in = in1->in(2);
} else if (in1->in(2) == in2->in(2)) {
// Convert a*c+b*c into (a+b)*c
add_in1 = in1->in(1);
add_in2 = in2->in(1);
mul_in = in1->in(2);
} else if (in1->in(1) == in2->in(2)) {
// Convert a*b+c*a into a*(b+c)
add_in1 = in1->in(2);
add_in2 = in2->in(1);
mul_in = in1->in(1);
}

if (mul_in != NULL) {
Node* add = phase->transform(new AddLNode(add_in1, add_in2));
return new MulLNode(mul_in, add);
}
}

// Convert (x >>> rshift) + (x << lshift) into RotateRight(x, rshift)
if (Matcher::match_rule_supported(Op_RotateRight) &&
((op1 == Op_URShiftL && op2 == Op_LShiftL) || (op1 == Op_LShiftL && op2 == Op_URShiftL)) &&
Expand Down
68 changes: 68 additions & 0 deletions src/hotspot/share/opto/subnode.cpp
Expand Up @@ -269,6 +269,40 @@ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){
return new SubINode( add1, in2->in(1) );
}

// Associative
if (op1 == Op_MulI && op2 == Op_MulI) {
Node* sub_in1 = NULL;
Node* sub_in2 = NULL;
Node* mul_in = NULL;

if (in1->in(1) == in2->in(1)) {
// Convert "a*b-a*c into a*(b-c)
sub_in1 = in1->in(2);
sub_in2 = in2->in(2);
mul_in = in1->in(1);
} else if (in1->in(2) == in2->in(1)) {
// Convert a*b-b*c into b*(a-c)
sub_in1 = in1->in(1);
sub_in2 = in2->in(2);
mul_in = in1->in(2);
} else if (in1->in(2) == in2->in(2)) {
// Convert a*c-b*c into (a-b)*c
sub_in1 = in1->in(1);
sub_in2 = in2->in(1);
mul_in = in1->in(2);
} else if (in1->in(1) == in2->in(2)) {
// Convert a*b-c*a into a*(b-c)
sub_in1 = in1->in(2);
sub_in2 = in2->in(1);
mul_in = in1->in(1);
}

if (mul_in != NULL) {
Node* sub = phase->transform(new SubINode(sub_in1, sub_in2));
return new MulINode(mul_in, sub);
}
}

// Convert "0-(A>>31)" into "(A>>>31)"
if ( op2 == Op_RShiftI ) {
Node *in21 = in2->in(1);
Expand Down Expand Up @@ -393,6 +427,40 @@ Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
return new SubLNode( add1, in2->in(1) );
}

// Associative
if (op1 == Op_MulL && op2 == Op_MulL) {
Node* sub_in1 = NULL;
Node* sub_in2 = NULL;
Node* mul_in = NULL;

if (in1->in(1) == in2->in(1)) {
// Convert "a*b-a*c into a*(b+c)
sub_in1 = in1->in(2);
sub_in2 = in2->in(2);
mul_in = in1->in(1);
} else if (in1->in(2) == in2->in(1)) {
// Convert a*b-b*c into b*(a-c)
sub_in1 = in1->in(1);
sub_in2 = in2->in(2);
mul_in = in1->in(2);
} else if (in1->in(2) == in2->in(2)) {
// Convert a*c-b*c into (a-b)*c
sub_in1 = in1->in(1);
sub_in2 = in2->in(1);
mul_in = in1->in(2);
} else if (in1->in(1) == in2->in(2)) {
// Convert a*b-c*a into a*(b-c)
sub_in1 = in1->in(2);
sub_in2 = in2->in(1);
mul_in = in1->in(1);
}

if (mul_in != NULL) {
Node* sub = phase->transform(new SubLNode(sub_in1, sub_in2));
return new MulLNode(mul_in, sub);
}
}

// Convert "0L-(A>>63)" into "(A>>>63)"
if ( op2 == Op_RShiftL ) {
Node *in21 = in2->in(1);
Expand Down

1 comment on commit 746fe5d

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.