comparison src/share/vm/opto/mulnode.cpp @ 624:337400e7a5dd

6797305: Add LoadUB and LoadUI opcode class Summary: Add a LoadUB (unsigned byte) and LoadUI (unsigned int) opcode class so we have these load optimizations in the first place and do not need to handle them in the matcher. Reviewed-by: never, kvn
author twisti
date Mon, 09 Mar 2009 03:17:11 -0700
parents 7628781568e1
children 18a08a7e16b5
comparison
equal deleted inserted replaced
623:9adddb8c0fc8 624:337400e7a5dd
484 load->adr_type()); 484 load->adr_type());
485 ldus = phase->transform(ldus); 485 ldus = phase->transform(ldus);
486 return new (phase->C, 3) AndINode(ldus, phase->intcon(mask&0xFFFF)); 486 return new (phase->C, 3) AndINode(ldus, phase->intcon(mask&0xFFFF));
487 } 487 }
488 488
489 // Masking sign bits off of a Byte? Let the matcher use an unsigned load 489 // Masking sign bits off of a Byte? Do an unsigned byte load.
490 if( lop == Op_LoadB && 490 if (lop == Op_LoadB && mask == 0x000000FF) {
491 (!in(0) && load->in(0)) && 491 return new (phase->C, 3) LoadUBNode(load->in(MemNode::Control),
492 (mask == 0x000000FF) ) { 492 load->in(MemNode::Memory),
493 // Associate this node with the LoadB, so the matcher can see them together. 493 load->in(MemNode::Address),
494 // If we don't do this, it is common for the LoadB to have one control 494 load->adr_type());
495 // edge, and the store or call containing this AndI to have a different 495 }
496 // control edge. This will cause Label_Root to group the AndI with 496
497 // the encoding store or call, so the matcher has no chance to match 497 // Masking sign bits off of a Byte plus additional lower bits? Do
498 // this AndI together with the LoadB. Setting the control edge here 498 // an unsigned byte load plus an and.
499 // prevents Label_Root from grouping the AndI with the store or call, 499 if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
500 // if it has a control edge that is inconsistent with the LoadB. 500 Node* ldub = new (phase->C, 3) LoadUBNode(load->in(MemNode::Control),
501 set_req(0, load->in(0)); 501 load->in(MemNode::Memory),
502 return this; 502 load->in(MemNode::Address),
503 load->adr_type());
504 ldub = phase->transform(ldub);
505 return new (phase->C, 3) AndINode(ldub, phase->intcon(mask));
503 } 506 }
504 507
505 // Masking off sign bits? Dont make them! 508 // Masking off sign bits? Dont make them!
506 if( lop == Op_RShiftI ) { 509 if( lop == Op_RShiftI ) {
507 const TypeInt *t12 = phase->type(load->in(2))->isa_int(); 510 const TypeInt *t12 = phase->type(load->in(2))->isa_int();
597 // Special case constant AND mask 600 // Special case constant AND mask
598 const TypeLong *t2 = phase->type( in(2) )->isa_long(); 601 const TypeLong *t2 = phase->type( in(2) )->isa_long();
599 if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape); 602 if( !t2 || !t2->is_con() ) return MulNode::Ideal(phase, can_reshape);
600 const jlong mask = t2->get_con(); 603 const jlong mask = t2->get_con();
601 604
602 Node *rsh = in(1); 605 Node* in1 = in(1);
603 uint rop = rsh->Opcode(); 606 uint op = in1->Opcode();
607
608 // Masking sign bits off of an integer? Do an unsigned integer to long load.
609 if (op == Op_ConvI2L && in1->in(1)->Opcode() == Op_LoadI && mask == 0x00000000FFFFFFFFL) {
610 Node* load = in1->in(1);
611 return new (phase->C, 3) LoadUI2LNode(load->in(MemNode::Control),
612 load->in(MemNode::Memory),
613 load->in(MemNode::Address),
614 load->adr_type());
615 }
604 616
605 // Masking off sign bits? Dont make them! 617 // Masking off sign bits? Dont make them!
606 if( rop == Op_RShiftL ) { 618 if (op == Op_RShiftL) {
607 const TypeInt *t12 = phase->type(rsh->in(2))->isa_int(); 619 const TypeInt *t12 = phase->type(in1->in(2))->isa_int();
608 if( t12 && t12->is_con() ) { // Shift is by a constant 620 if( t12 && t12->is_con() ) { // Shift is by a constant
609 int shift = t12->get_con(); 621 int shift = t12->get_con();
610 shift &= BitsPerJavaLong - 1; // semantics of Java shifts 622 shift &= BitsPerJavaLong - 1; // semantics of Java shifts
611 const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - shift)) -1); 623 const jlong sign_bits_mask = ~(((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - shift)) -1);
612 // If the AND'ing of the 2 masks has no bits, then only original shifted 624 // If the AND'ing of the 2 masks has no bits, then only original shifted
613 // bits survive. NO sign-extension bits survive the maskings. 625 // bits survive. NO sign-extension bits survive the maskings.
614 if( (sign_bits_mask & mask) == 0 ) { 626 if( (sign_bits_mask & mask) == 0 ) {
615 // Use zero-fill shift instead 627 // Use zero-fill shift instead
616 Node *zshift = phase->transform(new (phase->C, 3) URShiftLNode(rsh->in(1),rsh->in(2))); 628 Node *zshift = phase->transform(new (phase->C, 3) URShiftLNode(in1->in(1), in1->in(2)));
617 return new (phase->C, 3) AndLNode( zshift, in(2) ); 629 return new (phase->C, 3) AndLNode( zshift, in(2) );
618 } 630 }
619 } 631 }
620 } 632 }
621 633