comparison src/share/vm/opto/subnode.cpp @ 6131:8f6ce6f1049b

7170463: C2 should recognize "obj.getClass() == A.class" code pattern Summary: optimize this code pattern obj.getClass() == A.class. Reviewed-by: jrose, kvn Contributed-by: Krystal Mok <sajia@taobao.com>
author kvn
date Fri, 25 May 2012 07:53:11 -0700
parents 6759698e3140
children ae9241bbce4a
comparison
equal deleted inserted replaced
6088:7089278210e2 6131:8f6ce6f1049b
700 return ( r0->_ptr == TypePtr::NotNull && bits1==0 ) ? TypeInt::CC_GT : TypeInt::CC; 700 return ( r0->_ptr == TypePtr::NotNull && bits1==0 ) ? TypeInt::CC_GT : TypeInt::CC;
701 } else 701 } else
702 return TypeInt::CC; 702 return TypeInt::CC;
703 } 703 }
704 704
705 static inline Node* isa_java_mirror_load(PhaseGVN* phase, Node* n) {
706 // Return the klass node for
707 // LoadP(AddP(foo:Klass, #java_mirror))
708 // or NULL if not matching.
709 if (n->Opcode() != Op_LoadP) return NULL;
710
711 const TypeInstPtr* tp = phase->type(n)->isa_instptr();
712 if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL;
713
714 Node* adr = n->in(MemNode::Address);
715 intptr_t off = 0;
716 Node* k = AddPNode::Ideal_base_and_offset(adr, phase, off);
717 if (k == NULL) return NULL;
718 const TypeKlassPtr* tkp = phase->type(k)->isa_klassptr();
719 if (!tkp || off != in_bytes(Klass::java_mirror_offset())) return NULL;
720
721 // We've found the klass node of a Java mirror load.
722 return k;
723 }
724
725 static inline Node* isa_const_java_mirror(PhaseGVN* phase, Node* n) {
726 // for ConP(Foo.class) return ConP(Foo.klass)
727 // otherwise return NULL
728 if (!n->is_Con()) return NULL;
729
730 const TypeInstPtr* tp = phase->type(n)->isa_instptr();
731 if (!tp) return NULL;
732
733 ciType* mirror_type = tp->java_mirror_type();
734 // TypeInstPtr::java_mirror_type() returns non-NULL for compile-
735 // time Class constants only.
736 if (!mirror_type) return NULL;
737
738 // x.getClass() == int.class can never be true (for all primitive types)
739 // Return a ConP(NULL) node for this case.
740 if (mirror_type->is_classless()) {
741 return phase->makecon(TypePtr::NULL_PTR);
742 }
743
744 // return the ConP(Foo.klass)
745 assert(mirror_type->is_klass(), "mirror_type should represent a klassOop");
746 return phase->makecon(TypeKlassPtr::make(mirror_type->as_klass()));
747 }
748
705 //------------------------------Ideal------------------------------------------ 749 //------------------------------Ideal------------------------------------------
706 // Check for the case of comparing an unknown klass loaded from the primary 750 // Normalize comparisons between Java mirror loads to compare the klass instead.
751 //
752 // Also check for the case of comparing an unknown klass loaded from the primary
707 // super-type array vs a known klass with no subtypes. This amounts to 753 // super-type array vs a known klass with no subtypes. This amounts to
708 // checking to see an unknown klass subtypes a known klass with no subtypes; 754 // checking to see an unknown klass subtypes a known klass with no subtypes;
709 // this only happens on an exact match. We can shorten this test by 1 load. 755 // this only happens on an exact match. We can shorten this test by 1 load.
710 Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) { 756 Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) {
757 // Normalize comparisons between Java mirrors into comparisons of the low-
758 // level klass, where a dependent load could be shortened.
759 //
760 // The new pattern has a nice effect of matching the same pattern used in the
761 // fast path of instanceof/checkcast/Class.isInstance(), which allows
762 // redundant exact type check be optimized away by GVN.
763 // For example, in
764 // if (x.getClass() == Foo.class) {
765 // Foo foo = (Foo) x;
766 // // ... use a ...
767 // }
768 // a CmpPNode could be shared between if_acmpne and checkcast
769 {
770 Node* k1 = isa_java_mirror_load(phase, in(1));
771 Node* k2 = isa_java_mirror_load(phase, in(2));
772 Node* conk2 = isa_const_java_mirror(phase, in(2));
773
774 if (k1 && (k2 || conk2)) {
775 Node* lhs = k1;
776 Node* rhs = (k2 != NULL) ? k2 : conk2;
777 this->set_req(1, lhs);
778 this->set_req(2, rhs);
779 return this;
780 }
781 }
782
711 // Constant pointer on right? 783 // Constant pointer on right?
712 const TypeKlassPtr* t2 = phase->type(in(2))->isa_klassptr(); 784 const TypeKlassPtr* t2 = phase->type(in(2))->isa_klassptr();
713 if (t2 == NULL || !t2->klass_is_exact()) 785 if (t2 == NULL || !t2->klass_is_exact())
714 return NULL; 786 return NULL;
715 // Get the constant klass we are comparing to. 787 // Get the constant klass we are comparing to.