src/share/vm/opto/mulnode.cpp

Print this page
rev 5661 : 8024921: PPC64 (part 113): Extend Load and Store nodes to know about memory ordering.


 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 (can_reshape &&
 483       load->outcnt() == 1 && load->unique_out() == this) {
 484     if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
 485       Node *ldus = new (phase->C) LoadUSNode(load->in(MemNode::Control),
 486                                              load->in(MemNode::Memory),
 487                                              load->in(MemNode::Address),
 488                                              load->adr_type());

 489       ldus = phase->transform(ldus);
 490       return new (phase->C) AndINode(ldus, phase->intcon(mask & 0xFFFF));
 491     }
 492 
 493     // Masking sign bits off of a Byte?  Do an unsigned byte load plus
 494     // an and.
 495     if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
 496       Node* ldub = new (phase->C) LoadUBNode(load->in(MemNode::Control),
 497                                              load->in(MemNode::Memory),
 498                                              load->in(MemNode::Address),
 499                                              load->adr_type());

 500       ldub = phase->transform(ldub);
 501       return new (phase->C) AndINode(ldub, phase->intcon(mask));
 502     }
 503   }
 504 
 505   // Masking off sign bits?  Dont make them!
 506   if( lop == Op_RShiftI ) {
 507     const TypeInt *t12 = phase->type(load->in(2))->isa_int();
 508     if( t12 && t12->is_con() ) { // Shift is by a constant
 509       int shift = t12->get_con();
 510       shift &= BitsPerJavaInteger-1;  // semantics of Java shifts
 511       const int sign_bits_mask = ~right_n_bits(BitsPerJavaInteger - shift);
 512       // If the AND'ing of the 2 masks has no bits, then only original shifted
 513       // bits survive.  NO sign-extension bits survive the maskings.
 514       if( (sign_bits_mask & mask) == 0 ) {
 515         // Use zero-fill shift instead
 516         Node *zshift = phase->transform(new (phase->C) URShiftINode(load->in(1),load->in(2)));
 517         return new (phase->C) AndINode( zshift, in(2) );
 518       }
 519     }


 916       (t3 = phase->type(shl->in(2))->isa_int()) &&
 917       t3->is_con(16) ) {
 918     Node *ld = shl->in(1);
 919     if( ld->Opcode() == Op_LoadS ) {
 920       // Sign extension is just useless here.  Return a RShiftI of zero instead
 921       // returning 'ld' directly.  We cannot return an old Node directly as
 922       // that is the job of 'Identity' calls and Identity calls only work on
 923       // direct inputs ('ld' is an extra Node removed from 'this').  The
 924       // combined optimization requires Identity only return direct inputs.
 925       set_req(1, ld);
 926       set_req(2, phase->intcon(0));
 927       return this;
 928     }
 929     else if( can_reshape &&
 930              ld->Opcode() == Op_LoadUS &&
 931              ld->outcnt() == 1 && ld->unique_out() == shl)
 932       // Replace zero-extension-load with sign-extension-load
 933       return new (phase->C) LoadSNode( ld->in(MemNode::Control),
 934                                 ld->in(MemNode::Memory),
 935                                 ld->in(MemNode::Address),
 936                                 ld->adr_type());

 937   }
 938 
 939   // Check for "(byte[i] <<24)>>24" which simply sign-extends
 940   if( shift == 24 &&
 941       (t3 = phase->type(shl->in(2))->isa_int()) &&
 942       t3->is_con(24) ) {
 943     Node *ld = shl->in(1);
 944     if( ld->Opcode() == Op_LoadB ) {
 945       // Sign extension is just useless here
 946       set_req(1, ld);
 947       set_req(2, phase->intcon(0));
 948       return this;
 949     }
 950   }
 951 
 952   return NULL;
 953 }
 954 
 955 //------------------------------Value------------------------------------------
 956 // A RShiftINode shifts its input2 right by input1 amount.




 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 (can_reshape &&
 483       load->outcnt() == 1 && load->unique_out() == this) {
 484     if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
 485       Node *ldus = new (phase->C) LoadUSNode(load->in(MemNode::Control),
 486                                              load->in(MemNode::Memory),
 487                                              load->in(MemNode::Address),
 488                                              load->adr_type(),
 489                                              TypeInt::CHAR, LoadNode::unordered);
 490       ldus = phase->transform(ldus);
 491       return new (phase->C) AndINode(ldus, phase->intcon(mask & 0xFFFF));
 492     }
 493 
 494     // Masking sign bits off of a Byte?  Do an unsigned byte load plus
 495     // an and.
 496     if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
 497       Node* ldub = new (phase->C) LoadUBNode(load->in(MemNode::Control),
 498                                              load->in(MemNode::Memory),
 499                                              load->in(MemNode::Address),
 500                                              load->adr_type(),
 501                                              TypeInt::UBYTE, LoadNode::unordered);
 502       ldub = phase->transform(ldub);
 503       return new (phase->C) AndINode(ldub, phase->intcon(mask));
 504     }
 505   }
 506 
 507   // Masking off sign bits?  Dont make them!
 508   if( lop == Op_RShiftI ) {
 509     const TypeInt *t12 = phase->type(load->in(2))->isa_int();
 510     if( t12 && t12->is_con() ) { // Shift is by a constant
 511       int shift = t12->get_con();
 512       shift &= BitsPerJavaInteger-1;  // semantics of Java shifts
 513       const int sign_bits_mask = ~right_n_bits(BitsPerJavaInteger - shift);
 514       // If the AND'ing of the 2 masks has no bits, then only original shifted
 515       // bits survive.  NO sign-extension bits survive the maskings.
 516       if( (sign_bits_mask & mask) == 0 ) {
 517         // Use zero-fill shift instead
 518         Node *zshift = phase->transform(new (phase->C) URShiftINode(load->in(1),load->in(2)));
 519         return new (phase->C) AndINode( zshift, in(2) );
 520       }
 521     }


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