< prev index next >

src/hotspot/share/opto/subnode.cpp

Print this page

        

*** 721,730 **** --- 721,765 ---- } } return NULL; // No change } + //------------------------------Ideal------------------------------------------ + Node* CmpLNode::Ideal(PhaseGVN* phase, bool can_reshape) { + Node* a = NULL; + Node* b = NULL; + if (is_double_null_check(phase, a, b) && (phase->type(a)->is_zero_type() || phase->type(b)->is_zero_type())) { + // Degraded to a simple null check, use old acmp + return new CmpPNode(a, b); + } + return NULL; + } + + // Match double null check emitted by Compile::optimize_acmp() + bool CmpLNode::is_double_null_check(PhaseGVN* phase, Node*& a, Node*& b) const { + if (in(1)->Opcode() == Op_OrL && + in(1)->in(1)->Opcode() == Op_CastP2X && + in(1)->in(2)->Opcode() == Op_CastP2X && + in(2)->bottom_type()->is_zero_type()) { + assert(EnableValhalla, "unexpected double null check"); + a = in(1)->in(1)->in(1); + b = in(1)->in(2)->in(1); + return true; + } + return false; + } + + //------------------------------Value------------------------------------------ + const Type* CmpLNode::Value(PhaseGVN* phase) const { + Node* a = NULL; + Node* b = NULL; + if (is_double_null_check(phase, a, b) && (!phase->type(a)->maybe_null() || !phase->type(b)->maybe_null())) { + // One operand is never NULL, emit constant false + return TypeInt::CC_GT; + } + return SubNode::Value(phase); + } //============================================================================= // Simplify a CmpL (compare 2 longs ) node, based on local information. // If both inputs are constants, compare them. const Type *CmpLNode::sub( const Type *t1, const Type *t2 ) const {
*** 940,950 **** // // Also check for the case of comparing an unknown klass loaded from the primary // super-type array vs a known klass with no subtypes. This amounts to // checking to see an unknown klass subtypes a known klass with no subtypes; // this only happens on an exact match. We can shorten this test by 1 load. ! Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) { // Normalize comparisons between Java mirrors into comparisons of the low- // level klass, where a dependent load could be shortened. // // The new pattern has a nice effect of matching the same pattern used in the // fast path of instanceof/checkcast/Class.isInstance(), which allows --- 975,985 ---- // // Also check for the case of comparing an unknown klass loaded from the primary // super-type array vs a known klass with no subtypes. This amounts to // checking to see an unknown klass subtypes a known klass with no subtypes; // this only happens on an exact match. We can shorten this test by 1 load. ! Node* CmpPNode::Ideal(PhaseGVN *phase, bool can_reshape) { // Normalize comparisons between Java mirrors into comparisons of the low- // level klass, where a dependent load could be shortened. // // The new pattern has a nice effect of matching the same pattern used in the // fast path of instanceof/checkcast/Class.isInstance(), which allows
*** 1018,1027 **** --- 1053,1072 ---- // Verify that we understand the situation if (con2 != (intptr_t) superklass->super_check_offset()) return NULL; // Might be element-klass loading from array klass + // Do not fold the subtype check to an array klass pointer comparison for [V? arrays. + // [V is a subtype of [V? but the klass for [V is not equal to the klass for [V?. Perform a full test. + if (superklass->is_obj_array_klass()) { + ciObjArrayKlass* ak = superklass->as_obj_array_klass(); + if (!ak->storage_properties().is_null_free() && ak->element_klass()->is_valuetype()) { + // Do not bypass the klass load from the primary supertype array + return NULL; + } + } + // If 'superklass' has no subklasses and is not an interface, then we are // assured that the only input which will pass the type check is // 'superklass' itself. // // We could be more liberal here, and allow the optimization on interfaces
< prev index next >