Mercurial > hg > truffle
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 |