8220416: Comparison of klass pointers is not optimized any more
authorchagedorn
Thu, 12 Sep 2019 12:23:25 +0200
changeset 58104 46e11f978852
parent 58103 689a80d20550
child 58105 efcda145fb2c
8220416: Comparison of klass pointers is not optimized any more Summary: Enables dead klass pointer optimization (since JDK-6964458) again. Reviewed-by: roland, thartmann
src/hotspot/share/opto/subnode.cpp
--- 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------------------------------------------