src/share/vm/opto/mulnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
8034812 Cdiff src/share/vm/opto/mulnode.cpp
src/share/vm/opto/mulnode.cpp
Print this page
*** 197,230 ****
// Get low bit; check for being the only bit
Node *res = NULL;
jint bit1 = con & -con; // Extract low bit
if( bit1 == con ) { // Found a power of 2?
! res = new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) );
} else {
// Check for constant with 2 bits set
jint bit2 = con-bit1;
bit2 = bit2 & -bit2; // Extract 2nd bit
if( bit2 + bit1 == con ) { // Found all bits in con?
! Node *n1 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) );
! Node *n2 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) );
! res = new (phase->C) AddINode( n2, n1 );
} else if (is_power_of_2(con+1)) {
// Sleezy: power-of-2 -1. Next time be generic.
jint temp = (jint) (con + 1);
! Node *n1 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) );
! res = new (phase->C) SubINode( n1, in(1) );
} else {
return MulNode::Ideal(phase, can_reshape);
}
}
if( sign_flip ) { // Need to negate result?
res = phase->transform(res);// Transform, before making the zero con
! res = new (phase->C) SubINode(phase->intcon(0),res);
}
return res; // Return final result
}
--- 197,230 ----
// Get low bit; check for being the only bit
Node *res = NULL;
jint bit1 = con & -con; // Extract low bit
if( bit1 == con ) { // Found a power of 2?
! res = new LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) );
} else {
// Check for constant with 2 bits set
jint bit2 = con-bit1;
bit2 = bit2 & -bit2; // Extract 2nd bit
if( bit2 + bit1 == con ) { // Found all bits in con?
! Node *n1 = phase->transform( new LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) );
! Node *n2 = phase->transform( new LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) );
! res = new AddINode( n2, n1 );
} else if (is_power_of_2(con+1)) {
// Sleezy: power-of-2 -1. Next time be generic.
jint temp = (jint) (con + 1);
! Node *n1 = phase->transform( new LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) );
! res = new SubINode( n1, in(1) );
} else {
return MulNode::Ideal(phase, can_reshape);
}
}
if( sign_flip ) { // Need to negate result?
res = phase->transform(res);// Transform, before making the zero con
! res = new SubINode(phase->intcon(0),res);
}
return res; // Return final result
}
*** 293,326 ****
// Get low bit; check for being the only bit
Node *res = NULL;
jlong bit1 = con & -con; // Extract low bit
if( bit1 == con ) { // Found a power of 2?
! res = new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) );
} else {
// Check for constant with 2 bits set
jlong bit2 = con-bit1;
bit2 = bit2 & -bit2; // Extract 2nd bit
if( bit2 + bit1 == con ) { // Found all bits in con?
! Node *n1 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) );
! Node *n2 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) );
! res = new (phase->C) AddLNode( n2, n1 );
} else if (is_power_of_2_long(con+1)) {
// Sleezy: power-of-2 -1. Next time be generic.
jlong temp = (jlong) (con + 1);
! Node *n1 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) );
! res = new (phase->C) SubLNode( n1, in(1) );
} else {
return MulNode::Ideal(phase, can_reshape);
}
}
if( sign_flip ) { // Need to negate result?
res = phase->transform(res);// Transform, before making the zero con
! res = new (phase->C) SubLNode(phase->longcon(0),res);
}
return res; // Return final result
}
--- 293,326 ----
// Get low bit; check for being the only bit
Node *res = NULL;
jlong bit1 = con & -con; // Extract low bit
if( bit1 == con ) { // Found a power of 2?
! res = new LShiftLNode( in(1), phase->intcon(log2_long(bit1)) );
} else {
// Check for constant with 2 bits set
jlong bit2 = con-bit1;
bit2 = bit2 & -bit2; // Extract 2nd bit
if( bit2 + bit1 == con ) { // Found all bits in con?
! Node *n1 = phase->transform( new LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) );
! Node *n2 = phase->transform( new LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) );
! res = new AddLNode( n2, n1 );
} else if (is_power_of_2_long(con+1)) {
// Sleezy: power-of-2 -1. Next time be generic.
jlong temp = (jlong) (con + 1);
! Node *n1 = phase->transform( new LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) );
! res = new SubLNode( n1, in(1) );
} else {
return MulNode::Ideal(phase, can_reshape);
}
}
if( sign_flip ) { // Need to negate result?
res = phase->transform(res);// Transform, before making the zero con
! res = new SubLNode(phase->longcon(0),res);
}
return res; // Return final result
}
*** 475,509 ****
uint lop = load->Opcode();
// Masking bits off of a Character? Hi bits are already zero.
if( lop == Op_LoadUS &&
(mask & 0xFFFF0000) ) // Can we make a smaller mask?
! return new (phase->C) AndINode(load,phase->intcon(mask&0xFFFF));
// Masking bits off of a Short? Loading a Character does some masking
if (can_reshape &&
load->outcnt() == 1 && load->unique_out() == this) {
if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
! Node *ldus = new (phase->C) LoadUSNode(load->in(MemNode::Control),
load->in(MemNode::Memory),
load->in(MemNode::Address),
load->adr_type(),
TypeInt::CHAR, MemNode::unordered);
ldus = phase->transform(ldus);
! return new (phase->C) AndINode(ldus, phase->intcon(mask & 0xFFFF));
}
// Masking sign bits off of a Byte? Do an unsigned byte load plus
// an and.
if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
! Node* ldub = new (phase->C) LoadUBNode(load->in(MemNode::Control),
load->in(MemNode::Memory),
load->in(MemNode::Address),
load->adr_type(),
TypeInt::UBYTE, MemNode::unordered);
ldub = phase->transform(ldub);
! return new (phase->C) AndINode(ldub, phase->intcon(mask));
}
}
// Masking off sign bits? Dont make them!
if( lop == Op_RShiftI ) {
--- 475,509 ----
uint lop = load->Opcode();
// Masking bits off of a Character? Hi bits are already zero.
if( lop == Op_LoadUS &&
(mask & 0xFFFF0000) ) // Can we make a smaller mask?
! return new AndINode(load,phase->intcon(mask&0xFFFF));
// Masking bits off of a Short? Loading a Character does some masking
if (can_reshape &&
load->outcnt() == 1 && load->unique_out() == this) {
if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
! Node *ldus = new LoadUSNode(load->in(MemNode::Control),
load->in(MemNode::Memory),
load->in(MemNode::Address),
load->adr_type(),
TypeInt::CHAR, MemNode::unordered);
ldus = phase->transform(ldus);
! return new AndINode(ldus, phase->intcon(mask & 0xFFFF));
}
// Masking sign bits off of a Byte? Do an unsigned byte load plus
// an and.
if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
! Node* ldub = new LoadUBNode(load->in(MemNode::Control),
load->in(MemNode::Memory),
load->in(MemNode::Address),
load->adr_type(),
TypeInt::UBYTE, MemNode::unordered);
ldub = phase->transform(ldub);
! return new AndINode(ldub, phase->intcon(mask));
}
}
// Masking off sign bits? Dont make them!
if( lop == Op_RShiftI ) {
*** 514,535 ****
const int sign_bits_mask = ~right_n_bits(BitsPerJavaInteger - shift);
// If the AND'ing of the 2 masks has no bits, then only original shifted
// bits survive. NO sign-extension bits survive the maskings.
if( (sign_bits_mask & mask) == 0 ) {
// Use zero-fill shift instead
! Node *zshift = phase->transform(new (phase->C) URShiftINode(load->in(1),load->in(2)));
! return new (phase->C) AndINode( zshift, in(2) );
}
}
}
// Check for 'negate/and-1', a pattern emitted when someone asks for
// 'mod 2'. Negate leaves the low order bit unchanged (think: complement
// plus 1) and the mask is of the low order bit. Skip the negate.
if( lop == Op_SubI && mask == 1 && load->in(1) &&
phase->type(load->in(1)) == TypeInt::ZERO )
! return new (phase->C) AndINode( load->in(2), in(2) );
return MulNode::Ideal(phase, can_reshape);
}
//=============================================================================
--- 514,535 ----
const int sign_bits_mask = ~right_n_bits(BitsPerJavaInteger - shift);
// If the AND'ing of the 2 masks has no bits, then only original shifted
// bits survive. NO sign-extension bits survive the maskings.
if( (sign_bits_mask & mask) == 0 ) {
// Use zero-fill shift instead
! Node *zshift = phase->transform(new URShiftINode(load->in(1),load->in(2)));
! return new AndINode( zshift, in(2) );
}
}
}
// Check for 'negate/and-1', a pattern emitted when someone asks for
// 'mod 2'. Negate leaves the low order bit unchanged (think: complement
// plus 1) and the mask is of the low order bit. Skip the negate.
if( lop == Op_SubI && mask == 1 && load->in(1) &&
phase->type(load->in(1)) == TypeInt::ZERO )
! return new AndINode( load->in(2), in(2) );
return MulNode::Ideal(phase, can_reshape);
}
//=============================================================================
*** 609,621 ****
// that fits in 32-bits? Commute them and use an AndINode. Don't
// convert masks which would cause a sign extension of the integer
// value. This check includes UI2L masks (0x00000000FFFFFFFF) which
// would be optimized away later in Identity.
if (op == Op_ConvI2L && (mask & CONST64(0xFFFFFFFF80000000)) == 0) {
! Node* andi = new (phase->C) AndINode(in1->in(1), phase->intcon(mask));
andi = phase->transform(andi);
! return new (phase->C) ConvI2LNode(andi);
}
// Masking off sign bits? Dont make them!
if (op == Op_RShiftL) {
const TypeInt* t12 = phase->type(in1->in(2))->isa_int();
--- 609,621 ----
// that fits in 32-bits? Commute them and use an AndINode. Don't
// convert masks which would cause a sign extension of the integer
// value. This check includes UI2L masks (0x00000000FFFFFFFF) which
// would be optimized away later in Identity.
if (op == Op_ConvI2L && (mask & CONST64(0xFFFFFFFF80000000)) == 0) {
! Node* andi = new AndINode(in1->in(1), phase->intcon(mask));
andi = phase->transform(andi);
! return new ConvI2LNode(andi);
}
// Masking off sign bits? Dont make them!
if (op == Op_RShiftL) {
const TypeInt* t12 = phase->type(in1->in(2))->isa_int();
*** 625,636 ****
const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - shift)) -1);
// If the AND'ing of the 2 masks has no bits, then only original shifted
// bits survive. NO sign-extension bits survive the maskings.
if( (sign_bits_mask & mask) == 0 ) {
// Use zero-fill shift instead
! Node *zshift = phase->transform(new (phase->C) URShiftLNode(in1->in(1), in1->in(2)));
! return new (phase->C) AndLNode(zshift, in(2));
}
}
}
return MulNode::Ideal(phase, can_reshape);
--- 625,636 ----
const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - shift)) -1);
// If the AND'ing of the 2 masks has no bits, then only original shifted
// bits survive. NO sign-extension bits survive the maskings.
if( (sign_bits_mask & mask) == 0 ) {
// Use zero-fill shift instead
! Node *zshift = phase->transform(new URShiftLNode(in1->in(1), in1->in(2)));
! return new AndLNode(zshift, in(2));
}
}
}
return MulNode::Ideal(phase, can_reshape);
*** 664,704 ****
if( t12 && t12->is_con() ){ // Left input is an add of a con?
// Transform is legal, but check for profit. Avoid breaking 'i2s'
// and 'i2b' patterns which typically fold into 'StoreC/StoreB'.
if( con < 16 ) {
// Compute X << con0
! Node *lsh = phase->transform( new (phase->C) LShiftINode( add1->in(1), in(2) ) );
// Compute X<<con0 + (con1<<con0)
! return new (phase->C) AddINode( lsh, phase->intcon(t12->get_con() << con));
}
}
}
// Check for "(x>>c0)<<c0" which just masks off low bits
if( (add1_op == Op_RShiftI || add1_op == Op_URShiftI ) &&
add1->in(2) == in(2) )
// Convert to "(x & -(1<<c0))"
! return new (phase->C) AndINode(add1->in(1),phase->intcon( -(1<<con)));
// Check for "((x>>c0) & Y)<<c0" which just masks off more low bits
if( add1_op == Op_AndI ) {
Node *add2 = add1->in(1);
int add2_op = add2->Opcode();
if( (add2_op == Op_RShiftI || add2_op == Op_URShiftI ) &&
add2->in(2) == in(2) ) {
// Convert to "(x & (Y<<c0))"
! Node *y_sh = phase->transform( new (phase->C) LShiftINode( add1->in(2), in(2) ) );
! return new (phase->C) AndINode( add2->in(1), y_sh );
}
}
// Check for ((x & ((1<<(32-c0))-1)) << c0) which ANDs off high bits
// before shifting them away.
const jint bits_mask = right_n_bits(BitsPerJavaInteger-con);
if( add1_op == Op_AndI &&
phase->type(add1->in(2)) == TypeInt::make( bits_mask ) )
! return new (phase->C) LShiftINode( add1->in(1), in(2) );
return NULL;
}
//------------------------------Value------------------------------------------
--- 664,704 ----
if( t12 && t12->is_con() ){ // Left input is an add of a con?
// Transform is legal, but check for profit. Avoid breaking 'i2s'
// and 'i2b' patterns which typically fold into 'StoreC/StoreB'.
if( con < 16 ) {
// Compute X << con0
! Node *lsh = phase->transform( new LShiftINode( add1->in(1), in(2) ) );
// Compute X<<con0 + (con1<<con0)
! return new AddINode( lsh, phase->intcon(t12->get_con() << con));
}
}
}
// Check for "(x>>c0)<<c0" which just masks off low bits
if( (add1_op == Op_RShiftI || add1_op == Op_URShiftI ) &&
add1->in(2) == in(2) )
// Convert to "(x & -(1<<c0))"
! return new AndINode(add1->in(1),phase->intcon( -(1<<con)));
// Check for "((x>>c0) & Y)<<c0" which just masks off more low bits
if( add1_op == Op_AndI ) {
Node *add2 = add1->in(1);
int add2_op = add2->Opcode();
if( (add2_op == Op_RShiftI || add2_op == Op_URShiftI ) &&
add2->in(2) == in(2) ) {
// Convert to "(x & (Y<<c0))"
! Node *y_sh = phase->transform( new LShiftINode( add1->in(2), in(2) ) );
! return new AndINode( add2->in(1), y_sh );
}
}
// Check for ((x & ((1<<(32-c0))-1)) << c0) which ANDs off high bits
// before shifting them away.
const jint bits_mask = right_n_bits(BitsPerJavaInteger-con);
if( add1_op == Op_AndI &&
phase->type(add1->in(2)) == TypeInt::make( bits_mask ) )
! return new LShiftINode( add1->in(1), in(2) );
return NULL;
}
//------------------------------Value------------------------------------------
*** 774,813 ****
// Avoid dead data cycles from dead loops
assert( add1 != add1->in(1), "dead loop in LShiftLNode::Ideal" );
const TypeLong *t12 = phase->type(add1->in(2))->isa_long();
if( t12 && t12->is_con() ){ // Left input is an add of a con?
// Compute X << con0
! Node *lsh = phase->transform( new (phase->C) LShiftLNode( add1->in(1), in(2) ) );
// Compute X<<con0 + (con1<<con0)
! return new (phase->C) AddLNode( lsh, phase->longcon(t12->get_con() << con));
}
}
// Check for "(x>>c0)<<c0" which just masks off low bits
if( (add1_op == Op_RShiftL || add1_op == Op_URShiftL ) &&
add1->in(2) == in(2) )
// Convert to "(x & -(1<<c0))"
! return new (phase->C) AndLNode(add1->in(1),phase->longcon( -(CONST64(1)<<con)));
// Check for "((x>>c0) & Y)<<c0" which just masks off more low bits
if( add1_op == Op_AndL ) {
Node *add2 = add1->in(1);
int add2_op = add2->Opcode();
if( (add2_op == Op_RShiftL || add2_op == Op_URShiftL ) &&
add2->in(2) == in(2) ) {
// Convert to "(x & (Y<<c0))"
! Node *y_sh = phase->transform( new (phase->C) LShiftLNode( add1->in(2), in(2) ) );
! return new (phase->C) AndLNode( add2->in(1), y_sh );
}
}
// Check for ((x & ((CONST64(1)<<(64-c0))-1)) << c0) which ANDs off high bits
// before shifting them away.
const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1);
if( add1_op == Op_AndL &&
phase->type(add1->in(2)) == TypeLong::make( bits_mask ) )
! return new (phase->C) LShiftLNode( add1->in(1), in(2) );
return NULL;
}
//------------------------------Value------------------------------------------
--- 774,813 ----
// Avoid dead data cycles from dead loops
assert( add1 != add1->in(1), "dead loop in LShiftLNode::Ideal" );
const TypeLong *t12 = phase->type(add1->in(2))->isa_long();
if( t12 && t12->is_con() ){ // Left input is an add of a con?
// Compute X << con0
! Node *lsh = phase->transform( new LShiftLNode( add1->in(1), in(2) ) );
// Compute X<<con0 + (con1<<con0)
! return new AddLNode( lsh, phase->longcon(t12->get_con() << con));
}
}
// Check for "(x>>c0)<<c0" which just masks off low bits
if( (add1_op == Op_RShiftL || add1_op == Op_URShiftL ) &&
add1->in(2) == in(2) )
// Convert to "(x & -(1<<c0))"
! return new AndLNode(add1->in(1),phase->longcon( -(CONST64(1)<<con)));
// Check for "((x>>c0) & Y)<<c0" which just masks off more low bits
if( add1_op == Op_AndL ) {
Node *add2 = add1->in(1);
int add2_op = add2->Opcode();
if( (add2_op == Op_RShiftL || add2_op == Op_URShiftL ) &&
add2->in(2) == in(2) ) {
// Convert to "(x & (Y<<c0))"
! Node *y_sh = phase->transform( new LShiftLNode( add1->in(2), in(2) ) );
! return new AndLNode( add2->in(1), y_sh );
}
}
// Check for ((x & ((CONST64(1)<<(64-c0))-1)) << c0) which ANDs off high bits
// before shifting them away.
const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1);
if( add1_op == Op_AndL &&
phase->type(add1->in(2)) == TypeLong::make( bits_mask ) )
! return new LShiftLNode( add1->in(1), in(2) );
return NULL;
}
//------------------------------Value------------------------------------------
*** 905,916 ****
(t3 = phase->type(mask->in(2))->isa_int()) &&
t3->is_con() ) {
Node *x = mask->in(1);
jint maskbits = t3->get_con();
// Convert to "(x >> shift) & (mask >> shift)"
! Node *shr_nomask = phase->transform( new (phase->C) RShiftINode(mask->in(1), in(2)) );
! return new (phase->C) AndINode(shr_nomask, phase->intcon( maskbits >> shift));
}
// Check for "(short[i] <<16)>>16" which simply sign-extends
const Node *shl = in(1);
if( shl->Opcode() != Op_LShiftI ) return NULL;
--- 905,916 ----
(t3 = phase->type(mask->in(2))->isa_int()) &&
t3->is_con() ) {
Node *x = mask->in(1);
jint maskbits = t3->get_con();
// Convert to "(x >> shift) & (mask >> shift)"
! Node *shr_nomask = phase->transform( new RShiftINode(mask->in(1), in(2)) );
! return new AndINode(shr_nomask, phase->intcon( maskbits >> shift));
}
// Check for "(short[i] <<16)>>16" which simply sign-extends
const Node *shl = in(1);
if( shl->Opcode() != Op_LShiftI ) return NULL;
*** 931,941 ****
}
else if( can_reshape &&
ld->Opcode() == Op_LoadUS &&
ld->outcnt() == 1 && ld->unique_out() == shl)
// Replace zero-extension-load with sign-extension-load
! return new (phase->C) LoadSNode( ld->in(MemNode::Control),
ld->in(MemNode::Memory),
ld->in(MemNode::Address),
ld->adr_type(), TypeInt::SHORT,
MemNode::unordered);
}
--- 931,941 ----
}
else if( can_reshape &&
ld->Opcode() == Op_LoadUS &&
ld->outcnt() == 1 && ld->unique_out() == shl)
// Replace zero-extension-load with sign-extension-load
! return new LoadSNode( ld->in(MemNode::Control),
ld->in(MemNode::Memory),
ld->in(MemNode::Address),
ld->adr_type(), TypeInt::SHORT,
MemNode::unordered);
}
*** 1117,1127 ****
if( t12 && t12->is_con() ) { // Right input is a constant
assert( in(1) != in(1)->in(1), "dead loop in URShiftINode::Ideal" );
const int con2 = t12->get_con() & 31; // Shift count is always masked
const int con3 = con+con2;
if( con3 < 32 ) // Only merge shifts if total is < 32
! return new (phase->C) URShiftINode( in(1)->in(1), phase->intcon(con3) );
}
}
// Check for ((x << z) + Y) >>> z. Replace with x + con>>>z
// The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z".
--- 1117,1127 ----
if( t12 && t12->is_con() ) { // Right input is a constant
assert( in(1) != in(1)->in(1), "dead loop in URShiftINode::Ideal" );
const int con2 = t12->get_con() & 31; // Shift count is always masked
const int con3 = con+con2;
if( con3 < 32 ) // Only merge shifts if total is < 32
! return new URShiftINode( in(1)->in(1), phase->intcon(con3) );
}
}
// Check for ((x << z) + Y) >>> z. Replace with x + con>>>z
// The idiom for rounding to a power of 2 is "(Q+(2^z-1)) >>> z".
*** 1130,1142 ****
Node *add = in(1);
if( in1_op == Op_AddI ) {
Node *lshl = add->in(1);
if( lshl->Opcode() == Op_LShiftI &&
phase->type(lshl->in(2)) == t2 ) {
! Node *y_z = phase->transform( new (phase->C) URShiftINode(add->in(2),in(2)) );
! Node *sum = phase->transform( new (phase->C) AddINode( lshl->in(1), y_z ) );
! return new (phase->C) AndINode( sum, phase->intcon(mask) );
}
}
// Check for (x & mask) >>> z. Replace with (x >>> z) & (mask >>> z)
// This shortens the mask. Also, if we are extracting a high byte and
--- 1130,1142 ----
Node *add = in(1);
if( in1_op == Op_AddI ) {
Node *lshl = add->in(1);
if( lshl->Opcode() == Op_LShiftI &&
phase->type(lshl->in(2)) == t2 ) {
! Node *y_z = phase->transform( new URShiftINode(add->in(2),in(2)) );
! Node *sum = phase->transform( new AddINode( lshl->in(1), y_z ) );
! return new AndINode( sum, phase->intcon(mask) );
}
}
// Check for (x & mask) >>> z. Replace with (x >>> z) & (mask >>> z)
// This shortens the mask. Also, if we are extracting a high byte and
*** 1145,1156 ****
if( in1_op == Op_AndI ) {
const TypeInt *t3 = phase->type( andi->in(2) )->isa_int();
if( t3 && t3->is_con() ) { // Right input is a constant
jint mask2 = t3->get_con();
mask2 >>= con; // *signed* shift downward (high-order zeroes do not help)
! Node *newshr = phase->transform( new (phase->C) URShiftINode(andi->in(1), in(2)) );
! return new (phase->C) AndINode(newshr, phase->intcon(mask2));
// The negative values are easier to materialize than positive ones.
// A typical case from address arithmetic is ((x & ~15) >> 4).
// It's better to change that to ((x >> 4) & ~0) versus
// ((x >> 4) & 0x0FFFFFFF). The difference is greatest in LP64.
}
--- 1145,1156 ----
if( in1_op == Op_AndI ) {
const TypeInt *t3 = phase->type( andi->in(2) )->isa_int();
if( t3 && t3->is_con() ) { // Right input is a constant
jint mask2 = t3->get_con();
mask2 >>= con; // *signed* shift downward (high-order zeroes do not help)
! Node *newshr = phase->transform( new URShiftINode(andi->in(1), in(2)) );
! return new AndINode(newshr, phase->intcon(mask2));
// The negative values are easier to materialize than positive ones.
// A typical case from address arithmetic is ((x & ~15) >> 4).
// It's better to change that to ((x >> 4) & ~0) versus
// ((x >> 4) & 0x0FFFFFFF). The difference is greatest in LP64.
}
*** 1158,1168 ****
// Check for "(X << z ) >>> z" which simply zero-extends
Node *shl = in(1);
if( in1_op == Op_LShiftI &&
phase->type(shl->in(2)) == t2 )
! return new (phase->C) AndINode( shl->in(1), phase->intcon(mask) );
return NULL;
}
//------------------------------Value------------------------------------------
--- 1158,1168 ----
// Check for "(X << z ) >>> z" which simply zero-extends
Node *shl = in(1);
if( in1_op == Op_LShiftI &&
phase->type(shl->in(2)) == t2 )
! return new AndINode( shl->in(1), phase->intcon(mask) );
return NULL;
}
//------------------------------Value------------------------------------------
*** 1263,1275 ****
Node *add = in(1);
if( add->Opcode() == Op_AddL ) {
Node *lshl = add->in(1);
if( lshl->Opcode() == Op_LShiftL &&
phase->type(lshl->in(2)) == t2 ) {
! Node *y_z = phase->transform( new (phase->C) URShiftLNode(add->in(2),in(2)) );
! Node *sum = phase->transform( new (phase->C) AddLNode( lshl->in(1), y_z ) );
! return new (phase->C) AndLNode( sum, phase->longcon(mask) );
}
}
// Check for (x & mask) >>> z. Replace with (x >>> z) & (mask >>> z)
// This shortens the mask. Also, if we are extracting a high byte and
--- 1263,1275 ----
Node *add = in(1);
if( add->Opcode() == Op_AddL ) {
Node *lshl = add->in(1);
if( lshl->Opcode() == Op_LShiftL &&
phase->type(lshl->in(2)) == t2 ) {
! Node *y_z = phase->transform( new URShiftLNode(add->in(2),in(2)) );
! Node *sum = phase->transform( new AddLNode( lshl->in(1), y_z ) );
! return new AndLNode( sum, phase->longcon(mask) );
}
}
// Check for (x & mask) >>> z. Replace with (x >>> z) & (mask >>> z)
// This shortens the mask. Also, if we are extracting a high byte and
*** 1278,1297 ****
if( andi->Opcode() == Op_AndL ) {
const TypeLong *t3 = phase->type( andi->in(2) )->isa_long();
if( t3 && t3->is_con() ) { // Right input is a constant
jlong mask2 = t3->get_con();
mask2 >>= con; // *signed* shift downward (high-order zeroes do not help)
! Node *newshr = phase->transform( new (phase->C) URShiftLNode(andi->in(1), in(2)) );
! return new (phase->C) AndLNode(newshr, phase->longcon(mask2));
}
}
// Check for "(X << z ) >>> z" which simply zero-extends
Node *shl = in(1);
if( shl->Opcode() == Op_LShiftL &&
phase->type(shl->in(2)) == t2 )
! return new (phase->C) AndLNode( shl->in(1), phase->longcon(mask) );
return NULL;
}
//------------------------------Value------------------------------------------
--- 1278,1297 ----
if( andi->Opcode() == Op_AndL ) {
const TypeLong *t3 = phase->type( andi->in(2) )->isa_long();
if( t3 && t3->is_con() ) { // Right input is a constant
jlong mask2 = t3->get_con();
mask2 >>= con; // *signed* shift downward (high-order zeroes do not help)
! Node *newshr = phase->transform( new URShiftLNode(andi->in(1), in(2)) );
! return new AndLNode(newshr, phase->longcon(mask2));
}
}
// Check for "(X << z ) >>> z" which simply zero-extends
Node *shl = in(1);
if( shl->Opcode() == Op_LShiftL &&
phase->type(shl->in(2)) == t2 )
! return new AndLNode( shl->in(1), phase->longcon(mask) );
return NULL;
}
//------------------------------Value------------------------------------------
src/share/vm/opto/mulnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File