8220416: Comparison of klass pointers is not optimized any more
Summary: Enables dead klass pointer optimization (since JDK-6964458) again.
Reviewed-by: roland, thartmann
--- a/src/hotspot/share/opto/subnode.cpp Thu Sep 12 12:12:26 2019 +0200
+++ b/src/hotspot/share/opto/subnode.cpp Thu Sep 12 12:23:25 2019 +0200
@@ -819,9 +819,11 @@
}
// See if it is 2 unrelated classes.
- const TypeOopPtr* p0 = r0->isa_oopptr();
- const TypeOopPtr* p1 = r1->isa_oopptr();
- if (p0 && p1) {
+ const TypeOopPtr* oop_p0 = r0->isa_oopptr();
+ const TypeOopPtr* oop_p1 = r1->isa_oopptr();
+ bool both_oop_ptr = oop_p0 && oop_p1;
+
+ if (both_oop_ptr) {
Node* in1 = in(1)->uncast();
Node* in2 = in(2)->uncast();
AllocateNode* alloc1 = AllocateNode::Ideal_allocation(in1, NULL);
@@ -829,13 +831,36 @@
if (MemNode::detect_ptr_independence(in1, alloc1, in2, alloc2, NULL)) {
return TypeInt::CC_GT; // different pointers
}
- ciKlass* klass0 = p0->klass();
- bool xklass0 = p0->klass_is_exact();
- ciKlass* klass1 = p1->klass();
- bool xklass1 = p1->klass_is_exact();
- int kps = (p0->isa_klassptr()?1:0) + (p1->isa_klassptr()?1:0);
+ }
+
+ const TypeKlassPtr* klass_p0 = r0->isa_klassptr();
+ const TypeKlassPtr* klass_p1 = r1->isa_klassptr();
+
+ if (both_oop_ptr || (klass_p0 && klass_p1)) { // both or neither are klass pointers
+ ciKlass* klass0 = NULL;
+ bool xklass0 = false;
+ ciKlass* klass1 = NULL;
+ bool xklass1 = false;
+
+ if (oop_p0) {
+ klass0 = oop_p0->klass();
+ xklass0 = oop_p0->klass_is_exact();
+ } else {
+ assert(klass_p0, "must be non-null if oop_p0 is null");
+ klass0 = klass_p0->klass();
+ xklass0 = klass_p0->klass_is_exact();
+ }
+
+ if (oop_p1) {
+ klass1 = oop_p1->klass();
+ xklass1 = oop_p1->klass_is_exact();
+ } else {
+ assert(klass_p1, "must be non-null if oop_p1 is null");
+ klass1 = klass_p1->klass();
+ xklass1 = klass_p1->klass_is_exact();
+ }
+
if (klass0 && klass1 &&
- kps != 1 && // both or neither are klass pointers
klass0->is_loaded() && !klass0->is_interface() && // do not trust interfaces
klass1->is_loaded() && !klass1->is_interface() &&
(!klass0->is_obj_array_klass() ||
@@ -1054,73 +1079,8 @@
// Simplify an CmpN (compare 2 pointers) node, based on local information.
// If both inputs are constants, compare them.
const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const {
- const TypePtr *r0 = t1->make_ptr(); // Handy access
- const TypePtr *r1 = t2->make_ptr();
-
- // Undefined inputs makes for an undefined result
- if ((r0 == NULL) || (r1 == NULL) ||
- TypePtr::above_centerline(r0->_ptr) ||
- TypePtr::above_centerline(r1->_ptr)) {
- return Type::TOP;
- }
- if (r0 == r1 && r0->singleton()) {
- // Equal pointer constants (klasses, nulls, etc.)
- return TypeInt::CC_EQ;
- }
-
- // See if it is 2 unrelated classes.
- const TypeOopPtr* p0 = r0->isa_oopptr();
- const TypeOopPtr* p1 = r1->isa_oopptr();
- if (p0 && p1) {
- ciKlass* klass0 = p0->klass();
- bool xklass0 = p0->klass_is_exact();
- ciKlass* klass1 = p1->klass();
- bool xklass1 = p1->klass_is_exact();
- int kps = (p0->isa_klassptr()?1:0) + (p1->isa_klassptr()?1:0);
- if (klass0 && klass1 &&
- kps != 1 && // both or neither are klass pointers
- !klass0->is_interface() && // do not trust interfaces
- !klass1->is_interface()) {
- bool unrelated_classes = false;
- // See if neither subclasses the other, or if the class on top
- // is precise. In either of these cases, the compare is known
- // to fail if at least one of the pointers is provably not null.
- if (klass0->equals(klass1)) { // if types are unequal but klasses are equal
- // Do nothing; we know nothing for imprecise types
- } else if (klass0->is_subtype_of(klass1)) {
- // If klass1's type is PRECISE, then classes are unrelated.
- unrelated_classes = xklass1;
- } else if (klass1->is_subtype_of(klass0)) {
- // If klass0's type is PRECISE, then classes are unrelated.
- unrelated_classes = xklass0;
- } else { // Neither subtypes the other
- unrelated_classes = true;
- }
- if (unrelated_classes) {
- // The oops classes are known to be unrelated. If the joined PTRs of
- // two oops is not Null and not Bottom, then we are sure that one
- // of the two oops is non-null, and the comparison will always fail.
- TypePtr::PTR jp = r0->join_ptr(r1->_ptr);
- if (jp != TypePtr::Null && jp != TypePtr::BotPTR) {
- return TypeInt::CC_GT;
- }
- }
- }
- }
-
- // Known constants can be compared exactly
- // Null can be distinguished from any NotNull pointers
- // Unknown inputs makes an unknown result
- if( r0->singleton() ) {
- intptr_t bits0 = r0->get_con();
- if( r1->singleton() )
- return bits0 == r1->get_con() ? TypeInt::CC_EQ : TypeInt::CC_GT;
- return ( r1->_ptr == TypePtr::NotNull && bits0==0 ) ? TypeInt::CC_GT : TypeInt::CC;
- } else if( r1->singleton() ) {
- intptr_t bits1 = r1->get_con();
- return ( r0->_ptr == TypePtr::NotNull && bits1==0 ) ? TypeInt::CC_GT : TypeInt::CC;
- } else
- return TypeInt::CC;
+ ShouldNotReachHere();
+ return bottom_type();
}
//------------------------------Ideal------------------------------------------