Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8270366: C2: Add associative rule to add/sub node #4765

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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