mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-21 19:44:41 +02:00
5057225: Remove useless I2L conversions
The optimizer should be told to normalize (AndL (ConvI2L x) 0xFF) to (ConvI2L (AndI x 0xFF)), and then the existing matcher rule will work for free. Reviewed-by: kvn
This commit is contained in:
parent
8f6070ce0e
commit
a9ad90fa87
5 changed files with 541 additions and 59 deletions
|
@ -430,31 +430,28 @@ Node *AndINode::Identity( PhaseTransform *phase ) {
|
|||
// x & x => x
|
||||
if (phase->eqv(in(1), in(2))) return in(1);
|
||||
|
||||
Node *load = in(1);
|
||||
const TypeInt *t2 = phase->type( in(2) )->isa_int();
|
||||
if( t2 && t2->is_con() ) {
|
||||
Node* in1 = in(1);
|
||||
uint op = in1->Opcode();
|
||||
const TypeInt* t2 = phase->type(in(2))->isa_int();
|
||||
if (t2 && t2->is_con()) {
|
||||
int con = t2->get_con();
|
||||
// Masking off high bits which are always zero is useless.
|
||||
const TypeInt* t1 = phase->type( in(1) )->isa_int();
|
||||
if (t1 != NULL && t1->_lo >= 0) {
|
||||
jint t1_support = ((jint)1 << (1 + log2_intptr(t1->_hi))) - 1;
|
||||
jint t1_support = right_n_bits(1 + log2_intptr(t1->_hi));
|
||||
if ((t1_support & con) == t1_support)
|
||||
return load;
|
||||
return in1;
|
||||
}
|
||||
uint lop = load->Opcode();
|
||||
if( lop == Op_LoadUS &&
|
||||
con == 0x0000FFFF ) // Already zero-extended
|
||||
return load;
|
||||
// Masking off the high bits of a unsigned-shift-right is not
|
||||
// needed either.
|
||||
if( lop == Op_URShiftI ) {
|
||||
const TypeInt *t12 = phase->type( load->in(2) )->isa_int();
|
||||
if( t12 && t12->is_con() ) { // Shift is by a constant
|
||||
if (op == Op_URShiftI) {
|
||||
const TypeInt* t12 = phase->type(in1->in(2))->isa_int();
|
||||
if (t12 && t12->is_con()) { // Shift is by a constant
|
||||
int shift = t12->get_con();
|
||||
shift &= BitsPerJavaInteger - 1; // semantics of Java shifts
|
||||
int mask = max_juint >> shift;
|
||||
if( (mask&con) == mask ) // If AND is useless, skip it
|
||||
return load;
|
||||
if ((mask & con) == mask) // If AND is useless, skip it
|
||||
return in1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -476,26 +473,17 @@ Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||
return new (phase->C, 3) AndINode(load,phase->intcon(mask&0xFFFF));
|
||||
|
||||
// Masking bits off of a Short? Loading a Character does some masking
|
||||
if( lop == Op_LoadS &&
|
||||
(mask & 0xFFFF0000) == 0 ) {
|
||||
if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
|
||||
Node *ldus = new (phase->C, 3) LoadUSNode(load->in(MemNode::Control),
|
||||
load->in(MemNode::Memory),
|
||||
load->in(MemNode::Address),
|
||||
load->adr_type());
|
||||
load->in(MemNode::Memory),
|
||||
load->in(MemNode::Address),
|
||||
load->adr_type());
|
||||
ldus = phase->transform(ldus);
|
||||
return new (phase->C, 3) AndINode(ldus, phase->intcon(mask&0xFFFF));
|
||||
return new (phase->C, 3) AndINode(ldus, phase->intcon(mask & 0xFFFF));
|
||||
}
|
||||
|
||||
// Masking sign bits off of a Byte? Do an unsigned byte load.
|
||||
if (lop == Op_LoadB && mask == 0x000000FF) {
|
||||
return new (phase->C, 3) LoadUBNode(load->in(MemNode::Control),
|
||||
load->in(MemNode::Memory),
|
||||
load->in(MemNode::Address),
|
||||
load->adr_type());
|
||||
}
|
||||
|
||||
// Masking sign bits off of a Byte plus additional lower bits? Do
|
||||
// an unsigned byte load plus an and.
|
||||
// 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, 3) LoadUBNode(load->in(MemNode::Control),
|
||||
load->in(MemNode::Memory),
|
||||
|
@ -605,8 +593,13 @@ Node *AndLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||
Node* in1 = in(1);
|
||||
uint op = in1->Opcode();
|
||||
|
||||
// Masking sign bits off of an integer? Do an unsigned integer to long load.
|
||||
if (op == Op_ConvI2L && in1->in(1)->Opcode() == Op_LoadI && mask == 0x00000000FFFFFFFFL) {
|
||||
// Masking sign bits off of an integer? Do an unsigned integer to
|
||||
// long load.
|
||||
// NOTE: This check must be *before* we try to convert the AndLNode
|
||||
// to an AndINode and commute it with ConvI2LNode because
|
||||
// 0xFFFFFFFFL masks the whole integer and we get a sign extension,
|
||||
// which is wrong.
|
||||
if (op == Op_ConvI2L && in1->in(1)->Opcode() == Op_LoadI && mask == CONST64(0x00000000FFFFFFFF)) {
|
||||
Node* load = in1->in(1);
|
||||
return new (phase->C, 3) LoadUI2LNode(load->in(MemNode::Control),
|
||||
load->in(MemNode::Memory),
|
||||
|
@ -614,9 +607,22 @@ Node *AndLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||
load->adr_type());
|
||||
}
|
||||
|
||||
// Are we masking a long that was converted from an int with a mask
|
||||
// that fits in 32-bits? Commute them and use an AndINode.
|
||||
if (op == Op_ConvI2L && (mask & CONST64(0xFFFFFFFF00000000)) == 0) {
|
||||
// If we are doing an UI2L conversion (i.e. the mask is
|
||||
// 0x00000000FFFFFFFF) we cannot convert the AndL to an AndI
|
||||
// because the AndI would be optimized away later in Identity.
|
||||
if (mask != CONST64(0x00000000FFFFFFFF)) {
|
||||
Node* andi = new (phase->C, 3) AndINode(in1->in(1), phase->intcon(mask));
|
||||
andi = phase->transform(andi);
|
||||
return new (phase->C, 2) ConvI2LNode(andi);
|
||||
}
|
||||
}
|
||||
|
||||
// Masking off sign bits? Dont make them!
|
||||
if (op == Op_RShiftL) {
|
||||
const TypeInt *t12 = phase->type(in1->in(2))->isa_int();
|
||||
const TypeInt* t12 = phase->type(in1->in(2))->isa_int();
|
||||
if( t12 && t12->is_con() ) { // Shift is by a constant
|
||||
int shift = t12->get_con();
|
||||
shift &= BitsPerJavaLong - 1; // semantics of Java shifts
|
||||
|
@ -626,7 +632,7 @@ Node *AndLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
|
|||
if( (sign_bits_mask & mask) == 0 ) {
|
||||
// Use zero-fill shift instead
|
||||
Node *zshift = phase->transform(new (phase->C, 3) URShiftLNode(in1->in(1), in1->in(2)));
|
||||
return new (phase->C, 3) AndLNode( zshift, in(2) );
|
||||
return new (phase->C, 3) AndLNode(zshift, in(2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue