Mercurial > hg > graal-jvmci-8
diff src/share/vm/opto/mulnode.cpp @ 824:18a08a7e16b5
5057225: Remove useless I2L conversions
Summary: 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
author | twisti |
---|---|
date | Fri, 26 Jun 2009 07:26:10 -0700 |
parents | 337400e7a5dd |
children | 52898b0c43e9 |
line wrap: on
line diff
--- a/src/share/vm/opto/mulnode.cpp Wed Jun 24 12:00:51 2009 -0700 +++ b/src/share/vm/opto/mulnode.cpp Fri Jun 26 07:26:10 2009 -0700 @@ -430,31 +430,28 @@ // 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 @@ 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* 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 @@ 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 @@ 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)); } } }