599 } 600 PhaseIterGVN *igvn = phase->is_IterGVN(); 601 if( igvn ) { 602 set_req_X(Address,address,igvn); 603 set_req_X(Offset,offset,igvn); 604 } else { 605 set_req(Address,address); 606 set_req(Offset,offset); 607 } 608 return this; 609 } 610 } 611 612 // Raw pointers? 613 if( in(Base)->bottom_type() == Type::TOP ) { 614 // If this is a NULL+long form (from unsafe accesses), switch to a rawptr. 615 if (phase->type(in(Address)) == TypePtr::NULL_PTR) { 616 Node* offset = in(Offset); 617 return new CastX2PNode(offset); 618 } 619 } 620 621 // If the right is an add of a constant, push the offset down. 622 // Convert: (ptr + (offset+con)) into (ptr+offset)+con. 623 // The idea is to merge array_base+scaled_index groups together, 624 // and only have different constant offsets from the same base. 625 const Node *add = in(Offset); 626 if( add->Opcode() == Op_AddX && add->in(1) != add ) { 627 const Type *t22 = phase->type( add->in(2) ); 628 if( t22->singleton() && (t22 != Type::TOP) ) { // Right input is an add of a constant? 629 set_req(Address, phase->transform(new AddPNode(in(Base),in(Address),add->in(1)))); 630 set_req(Offset, add->in(2)); 631 PhaseIterGVN *igvn = phase->is_IterGVN(); 632 if (add->outcnt() == 0 && igvn) { 633 // add disconnected. 634 igvn->_worklist.push((Node*)add); 635 } 636 return this; // Made progress 637 } 638 } | 599 } 600 PhaseIterGVN *igvn = phase->is_IterGVN(); 601 if( igvn ) { 602 set_req_X(Address,address,igvn); 603 set_req_X(Offset,offset,igvn); 604 } else { 605 set_req(Address,address); 606 set_req(Offset,offset); 607 } 608 return this; 609 } 610 } 611 612 // Raw pointers? 613 if( in(Base)->bottom_type() == Type::TOP ) { 614 // If this is a NULL+long form (from unsafe accesses), switch to a rawptr. 615 if (phase->type(in(Address)) == TypePtr::NULL_PTR) { 616 Node* offset = in(Offset); 617 return new CastX2PNode(offset); 618 } 619 // Mixed unsafe access with non-null base. Convert to on-heap access. 620 if (in(Address)->is_CheckCastPP() && 621 in(Address)->bottom_type()->isa_rawptr()) { 622 Node* base = in(Address)->in(1); 623 const TypePtr* base_type = phase->type(base)->isa_oopptr(); 624 if (base_type != NULL && 625 !TypePtr::NULL_PTR->higher_equal(base_type) && 626 base_type->offset() == 0 /* always? convert to assert? */) { 627 return new AddPNode(base, base, in(Offset)); 628 } 629 } 630 } 631 632 // If the right is an add of a constant, push the offset down. 633 // Convert: (ptr + (offset+con)) into (ptr+offset)+con. 634 // The idea is to merge array_base+scaled_index groups together, 635 // and only have different constant offsets from the same base. 636 const Node *add = in(Offset); 637 if( add->Opcode() == Op_AddX && add->in(1) != add ) { 638 const Type *t22 = phase->type( add->in(2) ); 639 if( t22->singleton() && (t22 != Type::TOP) ) { // Right input is an add of a constant? 640 set_req(Address, phase->transform(new AddPNode(in(Base),in(Address),add->in(1)))); 641 set_req(Offset, add->in(2)); 642 PhaseIterGVN *igvn = phase->is_IterGVN(); 643 if (add->outcnt() == 0 && igvn) { 644 // add disconnected. 645 igvn->_worklist.push((Node*)add); 646 } 647 return this; // Made progress 648 } 649 } |