src/share/vm/opto/mulnode.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File 8000805 Sdiff src/share/vm/opto

src/share/vm/opto/mulnode.cpp

Print this page




 461       }
 462     }
 463   }
 464   return MulNode::Identity(phase);
 465 }
 466 
 467 //------------------------------Ideal------------------------------------------
 468 Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) {
 469   // Special case constant AND mask
 470   const TypeInt *t2 = phase->type( in(2) )->isa_int();
 471   if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
 472   const int mask = t2->get_con();
 473   Node *load = in(1);
 474   uint lop = load->Opcode();
 475 
 476   // Masking bits off of a Character?  Hi bits are already zero.
 477   if( lop == Op_LoadUS &&
 478       (mask & 0xFFFF0000) )     // Can we make a smaller mask?
 479     return new (phase->C) AndINode(load,phase->intcon(mask&0xFFFF));
 480 
 481   // Masking bits off of a Short?  Loading a Character does some masking
 482   if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
 483     Node *ldus = new (phase->C) LoadUSNode(load->in(MemNode::Control),
 484                                               load->in(MemNode::Memory),
 485                                               load->in(MemNode::Address),
 486                                               load->adr_type());
 487     ldus = phase->transform(ldus);
 488     return new (phase->C) AndINode(ldus, phase->intcon(mask & 0xFFFF));
 489   }
 490 
 491   // Masking sign bits off of a Byte?  Do an unsigned byte load plus
 492   // an and.
 493   if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
 494     Node* ldub = new (phase->C) LoadUBNode(load->in(MemNode::Control),
 495                                               load->in(MemNode::Memory),
 496                                               load->in(MemNode::Address),
 497                                               load->adr_type());
 498     ldub = phase->transform(ldub);
 499     return new (phase->C) AndINode(ldub, phase->intcon(mask));
 500   }
 501 
 502   // Masking off sign bits?  Dont make them!
 503   if( lop == Op_RShiftI ) {
 504     const TypeInt *t12 = phase->type(load->in(2))->isa_int();
 505     if( t12 && t12->is_con() ) { // Shift is by a constant
 506       int shift = t12->get_con();
 507       shift &= BitsPerJavaInteger-1;  // semantics of Java shifts
 508       const int sign_bits_mask = ~right_n_bits(BitsPerJavaInteger - shift);
 509       // If the AND'ing of the 2 masks has no bits, then only original shifted
 510       // bits survive.  NO sign-extension bits survive the maskings.
 511       if( (sign_bits_mask & mask) == 0 ) {
 512         // Use zero-fill shift instead
 513         Node *zshift = phase->transform(new (phase->C) URShiftINode(load->in(1),load->in(2)));
 514         return new (phase->C) AndINode( zshift, in(2) );
 515       }
 516     }
 517   }
 518 
 519   // Check for 'negate/and-1', a pattern emitted when someone asks for
 520   // 'mod 2'.  Negate leaves the low order bit unchanged (think: complement
 521   // plus 1) and the mask is of the low order bit.  Skip the negate.


 906   }
 907 
 908   // Check for "(short[i] <<16)>>16" which simply sign-extends
 909   const Node *shl = in(1);
 910   if( shl->Opcode() != Op_LShiftI ) return NULL;
 911 
 912   if( shift == 16 &&
 913       (t3 = phase->type(shl->in(2))->isa_int()) &&
 914       t3->is_con(16) ) {
 915     Node *ld = shl->in(1);
 916     if( ld->Opcode() == Op_LoadS ) {
 917       // Sign extension is just useless here.  Return a RShiftI of zero instead
 918       // returning 'ld' directly.  We cannot return an old Node directly as
 919       // that is the job of 'Identity' calls and Identity calls only work on
 920       // direct inputs ('ld' is an extra Node removed from 'this').  The
 921       // combined optimization requires Identity only return direct inputs.
 922       set_req(1, ld);
 923       set_req(2, phase->intcon(0));
 924       return this;
 925     }
 926     else if( ld->Opcode() == Op_LoadUS )
 927       // Replace zero-extension-load with sign-extension-load
 928       return new (phase->C) LoadSNode( ld->in(MemNode::Control),
 929                                 ld->in(MemNode::Memory),
 930                                 ld->in(MemNode::Address),
 931                                 ld->adr_type());
 932   }
 933 
 934   // Check for "(byte[i] <<24)>>24" which simply sign-extends
 935   if( shift == 24 &&
 936       (t3 = phase->type(shl->in(2))->isa_int()) &&
 937       t3->is_con(24) ) {
 938     Node *ld = shl->in(1);
 939     if( ld->Opcode() == Op_LoadB ) {
 940       // Sign extension is just useless here
 941       set_req(1, ld);
 942       set_req(2, phase->intcon(0));
 943       return this;
 944     }
 945   }
 946 
 947   return NULL;
 948 }
 949 
 950 //------------------------------Value------------------------------------------
 951 // A RShiftINode shifts its input2 right by input1 amount.




 461       }
 462     }
 463   }
 464   return MulNode::Identity(phase);
 465 }
 466 
 467 //------------------------------Ideal------------------------------------------
 468 Node *AndINode::Ideal(PhaseGVN *phase, bool can_reshape) {
 469   // Special case constant AND mask
 470   const TypeInt *t2 = phase->type( in(2) )->isa_int();
 471   if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
 472   const int mask = t2->get_con();
 473   Node *load = in(1);
 474   uint lop = load->Opcode();
 475 
 476   // Masking bits off of a Character?  Hi bits are already zero.
 477   if( lop == Op_LoadUS &&
 478       (mask & 0xFFFF0000) )     // Can we make a smaller mask?
 479     return new (phase->C) AndINode(load,phase->intcon(mask&0xFFFF));
 480 





















 481   // Masking off sign bits?  Dont make them!
 482   if( lop == Op_RShiftI ) {
 483     const TypeInt *t12 = phase->type(load->in(2))->isa_int();
 484     if( t12 && t12->is_con() ) { // Shift is by a constant
 485       int shift = t12->get_con();
 486       shift &= BitsPerJavaInteger-1;  // semantics of Java shifts
 487       const int sign_bits_mask = ~right_n_bits(BitsPerJavaInteger - shift);
 488       // If the AND'ing of the 2 masks has no bits, then only original shifted
 489       // bits survive.  NO sign-extension bits survive the maskings.
 490       if( (sign_bits_mask & mask) == 0 ) {
 491         // Use zero-fill shift instead
 492         Node *zshift = phase->transform(new (phase->C) URShiftINode(load->in(1),load->in(2)));
 493         return new (phase->C) AndINode( zshift, in(2) );
 494       }
 495     }
 496   }
 497 
 498   // Check for 'negate/and-1', a pattern emitted when someone asks for
 499   // 'mod 2'.  Negate leaves the low order bit unchanged (think: complement
 500   // plus 1) and the mask is of the low order bit.  Skip the negate.


 885   }
 886 
 887   // Check for "(short[i] <<16)>>16" which simply sign-extends
 888   const Node *shl = in(1);
 889   if( shl->Opcode() != Op_LShiftI ) return NULL;
 890 
 891   if( shift == 16 &&
 892       (t3 = phase->type(shl->in(2))->isa_int()) &&
 893       t3->is_con(16) ) {
 894     Node *ld = shl->in(1);
 895     if( ld->Opcode() == Op_LoadS ) {
 896       // Sign extension is just useless here.  Return a RShiftI of zero instead
 897       // returning 'ld' directly.  We cannot return an old Node directly as
 898       // that is the job of 'Identity' calls and Identity calls only work on
 899       // direct inputs ('ld' is an extra Node removed from 'this').  The
 900       // combined optimization requires Identity only return direct inputs.
 901       set_req(1, ld);
 902       set_req(2, phase->intcon(0));
 903       return this;
 904     }






 905   }
 906 
 907   // Check for "(byte[i] <<24)>>24" which simply sign-extends
 908   if( shift == 24 &&
 909       (t3 = phase->type(shl->in(2))->isa_int()) &&
 910       t3->is_con(24) ) {
 911     Node *ld = shl->in(1);
 912     if( ld->Opcode() == Op_LoadB ) {
 913       // Sign extension is just useless here
 914       set_req(1, ld);
 915       set_req(2, phase->intcon(0));
 916       return this;
 917     }
 918   }
 919 
 920   return NULL;
 921 }
 922 
 923 //------------------------------Value------------------------------------------
 924 // A RShiftINode shifts its input2 right by input1 amount.


src/share/vm/opto/mulnode.cpp
Index Unified diffs Context diffs Sdiffs Wdiffs Patch New Old Previous File Next File