*** 745,21 *** } } return NULL; // No change } ! Node *CmpLNode::Ideal( PhaseGVN *phase, bool can_reshape ) { const TypeLong *t2 = phase->type(in(2))->isa_long(); if (Opcode() == Op_CmpL && in(1)->Opcode() == Op_ConvI2L && t2 && t2->is_con()) { const jlong con = t2->get_con(); if (con >= min_jint && con <= max_jint) { return new CmpINode(in(1)->in(1), phase->intcon((jint)con)); } } return NULL; } //============================================================================= // 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 { const TypeLong *r0 = t1->is_long(); // Handy access --- 745,53 --- } } 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); + } const TypeLong *t2 = phase->type(in(2))->isa_long(); if (Opcode() == Op_CmpL && in(1)->Opcode() == Op_ConvI2L && t2 && t2->is_con()) { const jlong con = t2->get_con(); if (con >= min_jint && con <= max_jint) { return new CmpINode(in(1)->in(1), phase->intcon((jint)con)); } } 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 { const TypeLong *r0 = t1->is_long(); // Handy access
*** 914,10 *** --- 946,18 --- // If klass0's type is PRECISE, then classes are unrelated. unrelated_classes = xklass0; } else { // Neither subtypes the other unrelated_classes = true; } + if (!unrelated_classes) { + // Handle inline type arrays + if ((r0->flatten_array() && (!r1->can_be_inline_type() || (klass1->is_inlinetype() && !klass1->flatten_array()))) || + (r1->flatten_array() && (!r0->can_be_inline_type() || (klass0->is_inlinetype() && !klass0->flatten_array())))) { + // One type is flattened in arrays but the other type is not. Must be unrelated. + 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);
*** 999,11 *** // // 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 --- 1039,11 --- // // 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