< prev index next >
src/hotspot/share/opto/subnode.cpp
Print this page
*** 713,722 ****
--- 713,739 ----
}
}
return NULL; // No change
}
+ //------------------------------Ideal------------------------------------------
+ Node* CmpLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
+ if (in(1)->Opcode() == Op_OrL && in(1)->in(1)->Opcode() == Op_CastP2X && in(1)->in(2)->Opcode() == Op_CastP2X) {
+ Node* a = in(1)->in(1)->in(1);
+ Node* b = in(1)->in(2)->in(1);
+ const Type* ta = phase->type(a);
+ const Type* tb = phase->type(b);
+ if (ta->is_zero_type() || tb->is_zero_type()) {
+ return new CmpPNode(a, b);
+ } else if (!TypePtr::NULL_PTR->higher_equal(ta) || !TypePtr::NULL_PTR->higher_equal(tb)) {
+ // One operand is never NULL, emit constant false
+ return new CmpLNode(phase->longcon(0), phase->longcon(1));
+ }
+ }
+ 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 {
*** 930,939 ****
--- 947,984 ----
// 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 ) {
+ Node* pert = has_perturbed_operand();
+ if (pert != NULL) {
+ // Optimize new acmp
+ Node* a = pert->in(AddPNode::Base); // unperturbed a
+ Node* b = in(2);
+ Node* cmp = phase->C->optimize_acmp(phase, a, b);
+ if (cmp != NULL) {
+ return cmp;
+ }
+ if ( TypePtr::NULL_PTR->higher_equal(phase->type(a)) &&
+ !TypePtr::NULL_PTR->higher_equal(phase->type(b))) {
+ // Operand 'b' is never null, swap operands to avoid null check
+ Node* is_value = phase->C->load_is_value_bit(phase, b);
+ set_req(1, phase->transform(new AddPNode(b, b, is_value)));
+ set_req(2, a);
+ return this;
+ }
+ } else {
+ // Optimize old acmp with value type operands
+ const TypeInstPtr* ta = phase->type(in(1))->isa_instptr();
+ const TypeInstPtr* tb = phase->type(in(2))->isa_instptr();
+ if (((ta != NULL && ta->is_loaded() && ta->is_value_based()) || (tb != NULL && tb->is_loaded() && tb->is_value_based())) &&
+ (!TypePtr::NULL_PTR->higher_equal(phase->type(in(1))) || !TypePtr::NULL_PTR->higher_equal(phase->type(in(2))))) {
+ // One operand is a value type and one operand is never null, fold to constant false
+ return new CmpINode(phase->intcon(0), phase->intcon(1));
+ }
+ }
+
// 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
*** 1030,1039 ****
--- 1075,1100 ----
this->set_req(1,ldk2);
return this;
}
+ // Checks if one operand is perturbed and returns it
+ Node* CmpPNode::has_perturbed_operand() const {
+ // We always perturbe the first operand
+ AddPNode* addP = in(1)->isa_AddP();
+ if (addP != NULL) {
+ Node* base = addP->in(AddPNode::Base);
+ if (base->is_top()) {
+ // RawPtr comparison
+ return NULL;
+ }
+ assert(UseNewAcmp, "unexpected perturbed oop");
+ return in(1);
+ }
+ return NULL;
+ }
+
//=============================================================================
//------------------------------sub--------------------------------------------
// 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 {
< prev index next >