< prev index next >

## src/share/vm/opto/subnode.cpp

```*** 57,78 ****
phase->type( in(2)->in(1) )->higher_equal( zero ) ) {
return in(2)->in(2);
}

// Convert "(X+Y) - Y" into X and "(X+Y) - X" into Y
!   if( in(1)->Opcode() == Op_AddI ) {
if( phase->eqv(in(1)->in(2),in(2)) )
return in(1)->in(1);
if (phase->eqv(in(1)->in(1),in(2)))
return in(1)->in(2);

// Also catch: "(X + Opaque2(Y)) - Y".  In this case, 'Y' is a loop-varying
// trip counter and X is likely to be loop-invariant (that's how O2 Nodes
// are originally used, although the optimizer sometimes jiggers things).
// This folding through an O2 removes a loop-exit use of a loop-varying
// value and generally lowers register pressure in and around the loop.
!     if( in(1)->in(2)->Opcode() == Op_Opaque2 &&
phase->eqv(in(1)->in(2)->in(1),in(2)) )
return in(1)->in(1);
}

return ( phase->type( in(2) )->higher_equal( zero ) ) ? in(1) : this;
--- 57,78 ----
phase->type( in(2)->in(1) )->higher_equal( zero ) ) {
return in(2)->in(2);
}

// Convert "(X+Y) - Y" into X and "(X+Y) - X" into Y
!   if( in(1)->Opcode() == Opcodes::Op_AddI ) {
if( phase->eqv(in(1)->in(2),in(2)) )
return in(1)->in(1);
if (phase->eqv(in(1)->in(1),in(2)))
return in(1)->in(2);

// Also catch: "(X + Opaque2(Y)) - Y".  In this case, 'Y' is a loop-varying
// trip counter and X is likely to be loop-invariant (that's how O2 Nodes
// are originally used, although the optimizer sometimes jiggers things).
// This folding through an O2 removes a loop-exit use of a loop-varying
// value and generally lowers register pressure in and around the loop.
!     if( in(1)->in(2)->Opcode() == Opcodes::Op_Opaque2 &&
phase->eqv(in(1)->in(2)->in(1),in(2)) )
return in(1)->in(1);
}

return ( phase->type( in(2) )->higher_equal( zero ) ) ? in(1) : this;
*** 139,155 ****
}
//------------------------------Ideal------------------------------------------
Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){
Node *in1 = in(1);
Node *in2 = in(2);
!   uint op1 = in1->Opcode();
!   uint op2 = in2->Opcode();

#ifdef ASSERT
if( phase->eqv( in1, this ) || phase->eqv( in2, this ) ||
!       ( op1 == Op_AddI || op1 == Op_SubI ) &&
( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) ||
phase->eqv( in1->in(1), in1  ) || phase->eqv( in1->in(2), in1 ) ) )
#endif

--- 139,155 ----
}
//------------------------------Ideal------------------------------------------
Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){
Node *in1 = in(1);
Node *in2 = in(2);
!   Opcodes op1 = in1->Opcode();
!   Opcodes op2 = in2->Opcode();

#ifdef ASSERT
if( phase->eqv( in1, this ) || phase->eqv( in2, this ) ||
!       ( op1 == Opcodes::Op_AddI || op1 == Opcodes::Op_SubI ) &&
( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) ||
phase->eqv( in1->in(1), in1  ) || phase->eqv( in1->in(2), in1 ) ) )
#endif

*** 163,184 ****
}

// Convert "(x+c0) - y" into (x-y) + c0"
// Do not collapse (x+c0)-y if "+" is a loop increment or
// if "y" is a loop induction variable.
!   if( op1 == Op_AddI && ok_to_convert(in1, in2) ) {
const Type *tadd = phase->type( in1->in(2) );
Node *sub2 = phase->transform( new SubINode( in1->in(1), in2 ));
return new AddINode( sub2, in1->in(2) );
}
}

// Convert "x - (y+c0)" into "(x-y) - c0"
// Need the same check as in above optimization but reversed.
!   if (op2 == Op_AddI && ok_to_convert(in2, in1)) {
Node* in21 = in2->in(1);
Node* in22 = in2->in(2);
const TypeInt* tcon = phase->type(in22)->isa_int();
if (tcon != NULL && tcon->is_con()) {
Node* sub2 = phase->transform( new SubINode(in1, in21) );
--- 163,184 ----
}

// Convert "(x+c0) - y" into (x-y) + c0"
// Do not collapse (x+c0)-y if "+" is a loop increment or
// if "y" is a loop induction variable.
!   if( op1 == Opcodes::Op_AddI && ok_to_convert(in1, in2) ) {
const Type *tadd = phase->type( in1->in(2) );
Node *sub2 = phase->transform( new SubINode( in1->in(1), in2 ));
return new AddINode( sub2, in1->in(2) );
}
}

// Convert "x - (y+c0)" into "(x-y) - c0"
// Need the same check as in above optimization but reversed.
!   if (op2 == Opcodes::Op_AddI && ok_to_convert(in2, in1)) {
Node* in21 = in2->in(1);
Node* in22 = in2->in(2);
const TypeInt* tcon = phase->type(in22)->isa_int();
if (tcon != NULL && tcon->is_con()) {
Node* sub2 = phase->transform( new SubINode(in1, in21) );
*** 190,247 ****
const Type *t1 = phase->type( in1 );
if( t1 == Type::TOP ) return NULL;

#ifdef ASSERT
!   if( ( op2 == Op_AddI || op2 == Op_SubI ) &&
( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) ||
phase->eqv( in2->in(1), in2  ) || phase->eqv( in2->in(2), in2  ) ) )
#endif

// Convert "x - (x+y)" into "-y"
!   if( op2 == Op_AddI &&
phase->eqv( in1, in2->in(1) ) )
return new SubINode( phase->intcon(0),in2->in(2));
// Convert "(x-y) - x" into "-y"
!   if( op1 == Op_SubI &&
phase->eqv( in1->in(1), in2 ) )
return new SubINode( phase->intcon(0),in1->in(2));
// Convert "x - (y+x)" into "-y"
!   if( op2 == Op_AddI &&
phase->eqv( in1, in2->in(2) ) )
return new SubINode( phase->intcon(0),in2->in(1));

// Convert "0 - (x-y)" into "y-x"
!   if( t1 == TypeInt::ZERO && op2 == Op_SubI )
return new SubINode( in2->in(2), in2->in(1) );

// Convert "0 - (x+con)" into "-con-x"
jint con;
!   if( t1 == TypeInt::ZERO && op2 == Op_AddI &&
(con = in2->in(2)->find_int_con(0)) != 0 )
return new SubINode( phase->intcon(-con), in2->in(1) );

// Convert "(X+A) - (X+B)" into "A - B"
!   if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) )
return new SubINode( in1->in(2), in2->in(2) );

// Convert "(A+X) - (B+X)" into "A - B"
!   if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) )
return new SubINode( in1->in(1), in2->in(1) );

// Convert "(A+X) - (X+B)" into "A - B"
!   if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(1) )
return new SubINode( in1->in(1), in2->in(2) );

// Convert "(X+A) - (B+X)" into "A - B"
!   if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(2) )
return new SubINode( in1->in(2), in2->in(1) );

// Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally
// nicer to optimize than subtract.
!   if( op2 == Op_SubI && in2->outcnt() == 1) {
return new SubINode( add1, in2->in(1) );
}

return NULL;
--- 190,247 ----
const Type *t1 = phase->type( in1 );
if( t1 == Type::TOP ) return NULL;

#ifdef ASSERT
!   if( ( op2 == Opcodes::Op_AddI || op2 == Opcodes::Op_SubI ) &&
( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) ||
phase->eqv( in2->in(1), in2  ) || phase->eqv( in2->in(2), in2  ) ) )
#endif

// Convert "x - (x+y)" into "-y"
!   if( op2 == Opcodes::Op_AddI &&
phase->eqv( in1, in2->in(1) ) )
return new SubINode( phase->intcon(0),in2->in(2));
// Convert "(x-y) - x" into "-y"
!   if( op1 == Opcodes::Op_SubI &&
phase->eqv( in1->in(1), in2 ) )
return new SubINode( phase->intcon(0),in1->in(2));
// Convert "x - (y+x)" into "-y"
!   if( op2 == Opcodes::Op_AddI &&
phase->eqv( in1, in2->in(2) ) )
return new SubINode( phase->intcon(0),in2->in(1));

// Convert "0 - (x-y)" into "y-x"
!   if( t1 == TypeInt::ZERO && op2 == Opcodes::Op_SubI )
return new SubINode( in2->in(2), in2->in(1) );

// Convert "0 - (x+con)" into "-con-x"
jint con;
!   if( t1 == TypeInt::ZERO && op2 == Opcodes::Op_AddI &&
(con = in2->in(2)->find_int_con(0)) != 0 )
return new SubINode( phase->intcon(-con), in2->in(1) );

// Convert "(X+A) - (X+B)" into "A - B"
!   if( op1 == Opcodes::Op_AddI && op2 == Opcodes::Op_AddI && in1->in(1) == in2->in(1) )
return new SubINode( in1->in(2), in2->in(2) );

// Convert "(A+X) - (B+X)" into "A - B"
!   if( op1 == Opcodes::Op_AddI && op2 == Opcodes::Op_AddI && in1->in(2) == in2->in(2) )
return new SubINode( in1->in(1), in2->in(1) );

// Convert "(A+X) - (X+B)" into "A - B"
!   if( op1 == Opcodes::Op_AddI && op2 == Opcodes::Op_AddI && in1->in(2) == in2->in(1) )
return new SubINode( in1->in(1), in2->in(2) );

// Convert "(X+A) - (B+X)" into "A - B"
!   if( op1 == Opcodes::Op_AddI && op2 == Opcodes::Op_AddI && in1->in(1) == in2->in(2) )
return new SubINode( in1->in(2), in2->in(1) );

// Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally
// nicer to optimize than subtract.
!   if( op2 == Opcodes::Op_SubI && in2->outcnt() == 1) {
return new SubINode( add1, in2->in(1) );
}

return NULL;
*** 269,285 ****
//=============================================================================
//------------------------------Ideal------------------------------------------
Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node *in1 = in(1);
Node *in2 = in(2);
!   uint op1 = in1->Opcode();
!   uint op2 = in2->Opcode();

#ifdef ASSERT
if( phase->eqv( in1, this ) || phase->eqv( in2, this ) ||
!       ( op1 == Op_AddL || op1 == Op_SubL ) &&
( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) ||
phase->eqv( in1->in(1), in1  ) || phase->eqv( in1->in(2), in1  ) ) )
#endif

--- 269,285 ----
//=============================================================================
//------------------------------Ideal------------------------------------------
Node *SubLNode::Ideal(PhaseGVN *phase, bool can_reshape) {
Node *in1 = in(1);
Node *in2 = in(2);
!   Opcodes op1 = in1->Opcode();
!   Opcodes op2 = in2->Opcode();

#ifdef ASSERT
if( phase->eqv( in1, this ) || phase->eqv( in2, this ) ||
!       ( op1 == Opcodes::Op_AddL || op1 == Opcodes::Op_SubL ) &&
( phase->eqv( in1->in(1), this ) || phase->eqv( in1->in(2), this ) ||
phase->eqv( in1->in(1), in1  ) || phase->eqv( in1->in(2), in1  ) ) )
#endif

*** 291,312 ****

// Convert "(x+c0) - y" into (x-y) + c0"
// Do not collapse (x+c0)-y if "+" is a loop increment or
// if "y" is a loop induction variable.
!   if( op1 == Op_AddL && ok_to_convert(in1, in2) ) {
Node *in11 = in1->in(1);
const Type *tadd = phase->type( in1->in(2) );
Node *sub2 = phase->transform( new SubLNode( in11, in2 ));
return new AddLNode( sub2, in1->in(2) );
}
}

// Convert "x - (y+c0)" into "(x-y) - c0"
// Need the same check as in above optimization but reversed.
!   if (op2 == Op_AddL && ok_to_convert(in2, in1)) {
Node* in21 = in2->in(1);
Node* in22 = in2->in(2);
const TypeLong* tcon = phase->type(in22)->isa_long();
if (tcon != NULL && tcon->is_con()) {
Node* sub2 = phase->transform( new SubLNode(in1, in21) );
--- 291,312 ----

// Convert "(x+c0) - y" into (x-y) + c0"
// Do not collapse (x+c0)-y if "+" is a loop increment or
// if "y" is a loop induction variable.
!   if( op1 == Opcodes::Op_AddL && ok_to_convert(in1, in2) ) {
Node *in11 = in1->in(1);
const Type *tadd = phase->type( in1->in(2) );
Node *sub2 = phase->transform( new SubLNode( in11, in2 ));
return new AddLNode( sub2, in1->in(2) );
}
}

// Convert "x - (y+c0)" into "(x-y) - c0"
// Need the same check as in above optimization but reversed.
!   if (op2 == Opcodes::Op_AddL && ok_to_convert(in2, in1)) {
Node* in21 = in2->in(1);
Node* in22 = in2->in(2);
const TypeLong* tcon = phase->type(in22)->isa_long();
if (tcon != NULL && tcon->is_con()) {
Node* sub2 = phase->transform( new SubLNode(in1, in21) );
*** 318,356 ****
const Type *t1 = phase->type( in1 );
if( t1 == Type::TOP ) return NULL;

#ifdef ASSERT
!   if( ( op2 == Op_AddL || op2 == Op_SubL ) &&
( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) ||
phase->eqv( in2->in(1), in2  ) || phase->eqv( in2->in(2), in2  ) ) )
#endif

// Convert "x - (x+y)" into "-y"
!   if( op2 == Op_AddL &&
phase->eqv( in1, in2->in(1) ) )
return new SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2));
// Convert "x - (y+x)" into "-y"
!   if( op2 == Op_AddL &&
phase->eqv( in1, in2->in(2) ) )
return new SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1));

// Convert "0 - (x-y)" into "y-x"
!   if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL )
return new SubLNode( in2->in(2), in2->in(1) );

// Convert "(X+A) - (X+B)" into "A - B"
!   if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) )
return new SubLNode( in1->in(2), in2->in(2) );

// Convert "(A+X) - (B+X)" into "A - B"
!   if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) )
return new SubLNode( in1->in(1), in2->in(1) );

// Convert "A-(B-C)" into (A+C)-B"
!   if( op2 == Op_SubL && in2->outcnt() == 1) {
return new SubLNode( add1, in2->in(1) );
}

return NULL;
--- 318,356 ----
const Type *t1 = phase->type( in1 );
if( t1 == Type::TOP ) return NULL;

#ifdef ASSERT
!   if( ( op2 == Opcodes::Op_AddL || op2 == Opcodes::Op_SubL ) &&
( phase->eqv( in2->in(1), this ) || phase->eqv( in2->in(2), this ) ||
phase->eqv( in2->in(1), in2  ) || phase->eqv( in2->in(2), in2  ) ) )
#endif

// Convert "x - (x+y)" into "-y"
!   if( op2 == Opcodes::Op_AddL &&
phase->eqv( in1, in2->in(1) ) )
return new SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2));
// Convert "x - (y+x)" into "-y"
!   if( op2 == Opcodes::Op_AddL &&
phase->eqv( in1, in2->in(2) ) )
return new SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1));

// Convert "0 - (x-y)" into "y-x"
!   if( phase->type( in1 ) == TypeLong::ZERO && op2 == Opcodes::Op_SubL )
return new SubLNode( in2->in(2), in2->in(1) );

// Convert "(X+A) - (X+B)" into "A - B"
!   if( op1 == Opcodes::Op_AddL && op2 == Opcodes::Op_AddL && in1->in(1) == in2->in(1) )
return new SubLNode( in1->in(2), in2->in(2) );

// Convert "(A+X) - (B+X)" into "A - B"
!   if( op1 == Opcodes::Op_AddL && op2 == Opcodes::Op_AddL && in1->in(2) == in2->in(2) )
return new SubLNode( in1->in(1), in2->in(1) );

// Convert "A-(B-C)" into (A+C)-B"
!   if( op2 == Opcodes::Op_SubL && in2->outcnt() == 1) {
return new SubLNode( add1, in2->in(1) );
}

return NULL;
*** 626,637 ****
const Type* t2 = phase->type(in2);
assert(t1->isa_int(), "CmpU has only Int type inputs");
if (t2 == TypeInt::INT) { // Compare to bottom?
return bottom_type();
}
!   uint in1_op = in1->Opcode();
!   if (in1_op == Op_AddI || in1_op == Op_SubI) {
// The problem rise when result of AddI(SubI) may overflow
// signed integer value. Let say the input type is
// [256, maxint] then +128 will create 2 ranges due to
// overflow: [minint, minint+127] and [384, maxint].
// But C2 type system keep only 1 type range and as result
--- 626,637 ----
const Type* t2 = phase->type(in2);
assert(t1->isa_int(), "CmpU has only Int type inputs");
if (t2 == TypeInt::INT) { // Compare to bottom?
return bottom_type();
}
!   Opcodes in1_op = in1->Opcode();
!   if (in1_op == Opcodes::Op_AddI || in1_op == Opcodes::Op_SubI) {
// The problem rise when result of AddI(SubI) may overflow
// signed integer value. Let say the input type is
// [256, maxint] then +128 will create 2 ranges due to
// overflow: [minint, minint+127] and [384, maxint].
// But C2 type system keep only 1 type range and as result
*** 652,662 ****
const TypeInt *r1 = t12->is_int();
jlong lo_r0 = r0->_lo;
jlong hi_r0 = r0->_hi;
jlong lo_r1 = r1->_lo;
jlong hi_r1 = r1->_hi;
!       if (in1_op == Op_SubI) {
jlong tmp = hi_r1;
hi_r1 = -lo_r1;
lo_r1 = -tmp;
// Note, for substructing [minint,x] type range
// long arithmetic provides correct overflow answer.
--- 652,662 ----
const TypeInt *r1 = t12->is_int();
jlong lo_r0 = r0->_lo;
jlong hi_r0 = r0->_hi;
jlong lo_r1 = r1->_lo;
jlong hi_r1 = r1->_hi;
!       if (in1_op == Opcodes::Op_SubI) {
jlong tmp = hi_r1;
hi_r1 = -lo_r1;
lo_r1 = -tmp;
// Note, for substructing [minint,x] type range
// long arithmetic provides correct overflow answer.
*** 690,712 ****
return sub(t1, t2);            // Local flavor of type subtraction
}

bool CmpUNode::is_index_range_check() const {
// Check for the "(X ModI Y) CmpU Y" shape
!   return (in(1)->Opcode() == Op_ModI &&
in(1)->in(2)->eqv_uncast(in(2)));
}

//------------------------------Idealize---------------------------------------
Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) {
if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) {
switch (in(1)->Opcode()) {
!     case Op_CmpL3:              // Collapse a CmpL3/CmpI into a CmpL
return new CmpLNode(in(1)->in(1),in(1)->in(2));
!     case Op_CmpF3:              // Collapse a CmpF3/CmpI into a CmpF
return new CmpFNode(in(1)->in(1),in(1)->in(2));
!     case Op_CmpD3:              // Collapse a CmpD3/CmpI into a CmpD
return new CmpDNode(in(1)->in(1),in(1)->in(2));
//case Op_SubI:
// If (x - y) cannot overflow, then ((x - y) <?> 0)
// can be turned into (x <?> y).
// This is handled (with more general cases) by Ideal_sub_algebra.
--- 690,712 ----
return sub(t1, t2);            // Local flavor of type subtraction
}

bool CmpUNode::is_index_range_check() const {
// Check for the "(X ModI Y) CmpU Y" shape
!   return (in(1)->Opcode() == Opcodes::Op_ModI &&
in(1)->in(2)->eqv_uncast(in(2)));
}

//------------------------------Idealize---------------------------------------
Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) {
if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) {
switch (in(1)->Opcode()) {
!     case Opcodes::Op_CmpL3:              // Collapse a CmpL3/CmpI into a CmpL
return new CmpLNode(in(1)->in(1),in(1)->in(2));
!     case Opcodes::Op_CmpF3:              // Collapse a CmpF3/CmpI into a CmpF
return new CmpFNode(in(1)->in(1),in(1)->in(2));
!     case Opcodes::Op_CmpD3:              // Collapse a CmpD3/CmpI into a CmpD
return new CmpDNode(in(1)->in(1),in(1)->in(2));
//case Op_SubI:
// If (x - y) cannot overflow, then ((x - y) <?> 0)
// can be turned into (x <?> y).
// This is handled (with more general cases) by Ideal_sub_algebra.
*** 824,834 ****

static inline Node* isa_java_mirror_load(PhaseGVN* phase, Node* n) {
// Return the klass node for
//   or NULL if not matching.
!   if (n->Opcode() != Op_LoadP) return NULL;

const TypeInstPtr* tp = phase->type(n)->isa_instptr();
if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL;

--- 824,834 ----

static inline Node* isa_java_mirror_load(PhaseGVN* phase, Node* n) {
// Return the klass node for
//   or NULL if not matching.
!   if (n->Opcode() != Opcodes::Op_LoadP) return NULL;

const TypeInstPtr* tp = phase->type(n)->isa_instptr();
if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL;

*** 909,921 ****

// Now check for LoadKlass on left.
Node* ldk1 = in(1);
if (ldk1->is_DecodeNKlass()) {
ldk1 = ldk1->in(1);
!     if (ldk1->Opcode() != Op_LoadNKlass )
return NULL;
!   } else if (ldk1->Opcode() != Op_LoadKlass )
return NULL;
intptr_t con2 = 0;
--- 909,921 ----

// Now check for LoadKlass on left.
Node* ldk1 = in(1);
if (ldk1->is_DecodeNKlass()) {
ldk1 = ldk1->in(1);
!     if (ldk1->Opcode() != Opcodes::Op_LoadNKlass )
return NULL;
!   } else if (ldk1->Opcode() != Opcodes::Op_LoadKlass )
return NULL;
intptr_t con2 = 0;
*** 934,946 ****

// Check for a LoadKlass from primary supertype array.
// Any nested loadklass from loadklass+con must be from the p.s. array.
if (ldk2->is_DecodeNKlass()) {
// Keep ldk2 as DecodeN since it could be used in CmpP below.
!     if (ldk2->in(1)->Opcode() != Op_LoadNKlass )
return NULL;
!   } else if (ldk2->Opcode() != Op_LoadKlass)
return NULL;

// Verify that we understand the situation
if (con2 != (intptr_t) superklass->super_check_offset())
--- 934,946 ----

// Check for a LoadKlass from primary supertype array.
// Any nested loadklass from loadklass+con must be from the p.s. array.
if (ldk2->is_DecodeNKlass()) {
// Keep ldk2 as DecodeN since it could be used in CmpP below.
!     if (ldk2->in(1)->Opcode() != Opcodes::Op_LoadNKlass )
return NULL;
!   } else if (ldk2->Opcode() != Opcodes::Op_LoadKlass)
return NULL;

// Verify that we understand the situation
if (con2 != (intptr_t) superklass->super_check_offset())
*** 1121,1137 ****
// Benefits: eliminates conversion, does not require 24-bit mode

// NaNs prevent commuting operands.  This transform works regardless of the
// order of ConD and ConvF2D inputs by preserving the original order.
int idx_f2d = 1;              // ConvF2D on left side?
!   if( in(idx_f2d)->Opcode() != Op_ConvF2D )
idx_f2d = 2;                // No, swap to check for reversed args
int idx_con = 3-idx_f2d;      // Check for the constant on other input

if( ConvertCmpD2CmpF &&
!       in(idx_f2d)->Opcode() == Op_ConvF2D &&
!       in(idx_con)->Opcode() == Op_ConD ) {
const TypeD *t2 = in(idx_con)->bottom_type()->is_double_constant();
double t2_value_as_double = t2->_d;
float  t2_value_as_float  = (float)t2_value_as_double;
if( t2_value_as_double == (double)t2_value_as_float ) {
// Test value can be represented as a float
--- 1121,1137 ----
// Benefits: eliminates conversion, does not require 24-bit mode

// NaNs prevent commuting operands.  This transform works regardless of the
// order of ConD and ConvF2D inputs by preserving the original order.
int idx_f2d = 1;              // ConvF2D on left side?
!   if( in(idx_f2d)->Opcode() != Opcodes::Op_ConvF2D )
idx_f2d = 2;                // No, swap to check for reversed args
int idx_con = 3-idx_f2d;      // Check for the constant on other input

if( ConvertCmpD2CmpF &&
!       in(idx_f2d)->Opcode() == Opcodes::Op_ConvF2D &&
!       in(idx_con)->Opcode() == Opcodes::Op_ConD ) {
const TypeD *t2 = in(idx_con)->bottom_type()->is_double_constant();
double t2_value_as_double = t2->_d;
float  t2_value_as_float  = (float)t2_value_as_double;
if( t2_value_as_double == (double)t2_value_as_float ) {
// Test value can be represented as a float
*** 1141,1151 ****
if( idx_f2d != 1 ) {      // Must flip args to match original order
Node *tmp = new_in1;
new_in1 = new_in2;
new_in2 = tmp;
}
!       CmpFNode *new_cmp = (Opcode() == Op_CmpD3)
? new CmpF3Node( new_in1, new_in2 )
: new CmpFNode ( new_in1, new_in2 ) ;
return new_cmp;           // Changed to CmpFNode
}
// Testing value required the precision of a double
--- 1141,1151 ----
if( idx_f2d != 1 ) {      // Must flip args to match original order
Node *tmp = new_in1;
new_in1 = new_in2;
new_in2 = tmp;
}
!       CmpFNode *new_cmp = (Opcode() == Opcodes::Op_CmpD3)
? new CmpF3Node( new_in1, new_in2 )
: new CmpFNode ( new_in1, new_in2 ) ;
return new_cmp;           // Changed to CmpFNode
}
// Testing value required the precision of a double
*** 1235,1259 ****
}

// Change "bool eq/ne (cmp (add/sub A B) C)" into false/true if add/sub
// overflows and we can prove that C is not in the two resulting ranges.
// This optimization is similar to the one performed by CmpUNode::Value().
! Node* BoolNode::fold_cmpI(PhaseGVN* phase, SubNode* cmp, Node* cmp1, int cmp_op,
!                           int cmp1_op, const TypeInt* cmp2_type) {
// Only optimize eq/ne integer comparison of add/sub
if((_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
!      (cmp_op == Op_CmpI) && (cmp1_op == Op_AddI || cmp1_op == Op_SubI)) {
// Skip cases were inputs of add/sub are not integers or of bottom type
const TypeInt* r0 = phase->type(cmp1->in(1))->isa_int();
const TypeInt* r1 = phase->type(cmp1->in(2))->isa_int();
if ((r0 != NULL) && (r0 != TypeInt::INT) &&
(r1 != NULL) && (r1 != TypeInt::INT) &&
(cmp2_type != TypeInt::INT)) {
// Compute exact (long) type range of add/sub result
jlong lo_long = r0->_lo;
jlong hi_long = r0->_hi;
!       if (cmp1_op == Op_AddI) {
lo_long += r1->_lo;
hi_long += r1->_hi;
} else {
lo_long -= r1->_hi;
hi_long -= r1->_lo;
--- 1235,1259 ----
}

// Change "bool eq/ne (cmp (add/sub A B) C)" into false/true if add/sub
// overflows and we can prove that C is not in the two resulting ranges.
// This optimization is similar to the one performed by CmpUNode::Value().
! Node* BoolNode::fold_cmpI(PhaseGVN* phase, SubNode* cmp, Node* cmp1, Opcodes cmp_op,
!                           Opcodes cmp1_op, const TypeInt* cmp2_type) {
// Only optimize eq/ne integer comparison of add/sub
if((_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
!      (cmp_op == Opcodes::Op_CmpI) && (cmp1_op == Opcodes::Op_AddI || cmp1_op == Opcodes::Op_SubI)) {
// Skip cases were inputs of add/sub are not integers or of bottom type
const TypeInt* r0 = phase->type(cmp1->in(1))->isa_int();
const TypeInt* r1 = phase->type(cmp1->in(2))->isa_int();
if ((r0 != NULL) && (r0 != TypeInt::INT) &&
(r1 != NULL) && (r1 != TypeInt::INT) &&
(cmp2_type != TypeInt::INT)) {
// Compute exact (long) type range of add/sub result
jlong lo_long = r0->_lo;
jlong hi_long = r0->_hi;
!       if (cmp1_op == Opcodes::Op_AddI) {
lo_long += r1->_lo;
hi_long += r1->_hi;
} else {
lo_long -= r1->_hi;
hi_long -= r1->_lo;
*** 1287,1315 ****
Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Change "bool tst (cmp con x)" into "bool ~tst (cmp x con)".
// This moves the constant to the right.  Helps value-numbering.
Node *cmp = in(1);
if( !cmp->is_Sub() ) return NULL;
!   int cop = cmp->Opcode();
!   if( cop == Op_FastLock || cop == Op_FastUnlock) return NULL;
Node *cmp1 = cmp->in(1);
Node *cmp2 = cmp->in(2);
if( !cmp1 ) return NULL;

if (_test._test == BoolTest::overflow || _test._test == BoolTest::no_overflow) {
return NULL;
}

// Constant on left?
Node *con = cmp1;
!   uint op2 = cmp2->Opcode();
// Move constants to the right of compare's to canonicalize.
// Do not muck with Opaque1 nodes, as this indicates a loop
// guard that cannot change shape.
!   if( con->is_Con() && !cmp2->is_Con() && op2 != Op_Opaque1 &&
// Because of NaN's, CmpD and CmpF are not commutative
!       cop != Op_CmpD && cop != Op_CmpF &&
// Protect against swapping inputs to a compare when it is used by a
// counted loop exit, which requires maintaining the loop-limit as in(2)
!is_counted_loop_exit_test() ) {
// Ok, commute the constant to the right of the cmp node.
// Clone the Node, getting a new Node of the same class
--- 1287,1315 ----
Node *BoolNode::Ideal(PhaseGVN *phase, bool can_reshape) {
// Change "bool tst (cmp con x)" into "bool ~tst (cmp x con)".
// This moves the constant to the right.  Helps value-numbering.
Node *cmp = in(1);
if( !cmp->is_Sub() ) return NULL;
!   Opcodes cop = cmp->Opcode();
!   if( cop == Opcodes::Op_FastLock || cop == Opcodes::Op_FastUnlock) return NULL;
Node *cmp1 = cmp->in(1);
Node *cmp2 = cmp->in(2);
if( !cmp1 ) return NULL;

if (_test._test == BoolTest::overflow || _test._test == BoolTest::no_overflow) {
return NULL;
}

// Constant on left?
Node *con = cmp1;
!   Opcodes op2 = cmp2->Opcode();
// Move constants to the right of compare's to canonicalize.
// Do not muck with Opaque1 nodes, as this indicates a loop
// guard that cannot change shape.
!   if( con->is_Con() && !cmp2->is_Con() && op2 != Opcodes::Op_Opaque1 &&
// Because of NaN's, CmpD and CmpF are not commutative
!       cop != Opcodes::Op_CmpD && cop != Opcodes::Op_CmpF &&
// Protect against swapping inputs to a compare when it is used by a
// counted loop exit, which requires maintaining the loop-limit as in(2)
!is_counted_loop_exit_test() ) {
// Ok, commute the constant to the right of the cmp node.
// Clone the Node, getting a new Node of the same class
*** 1321,1336 ****
}

// Change "bool eq/ne (cmp (xor X 1) 0)" into "bool ne/eq (cmp X 0)".
// The XOR-1 is an idiom used to flip the sense of a bool.  We flip the
!   int cmp1_op = cmp1->Opcode();
const TypeInt* cmp2_type = phase->type(cmp2)->isa_int();
if (cmp2_type == NULL)  return NULL;
Node* j_xor = cmp1;
if( cmp2_type == TypeInt::ZERO &&
!       cmp1_op == Op_XorI &&
j_xor->in(1) != j_xor &&          // An xor of itself is dead
phase->type( j_xor->in(1) ) == TypeInt::BOOL &&
phase->type( j_xor->in(2) ) == TypeInt::ONE &&
(_test._test == BoolTest::eq ||
_test._test == BoolTest::ne) ) {
--- 1321,1336 ----
}

// Change "bool eq/ne (cmp (xor X 1) 0)" into "bool ne/eq (cmp X 0)".
// The XOR-1 is an idiom used to flip the sense of a bool.  We flip the
!   Opcodes cmp1_op = cmp1->Opcode();
const TypeInt* cmp2_type = phase->type(cmp2)->isa_int();
if (cmp2_type == NULL)  return NULL;
Node* j_xor = cmp1;
if( cmp2_type == TypeInt::ZERO &&
!       cmp1_op == Opcodes::Op_XorI &&
j_xor->in(1) != j_xor &&          // An xor of itself is dead
phase->type( j_xor->in(1) ) == TypeInt::BOOL &&
phase->type( j_xor->in(2) ) == TypeInt::ONE &&
(_test._test == BoolTest::eq ||
_test._test == BoolTest::ne) ) {
*** 1338,1376 ****
return new BoolNode( ncmp, _test.negate() );
}

// Change ((x & m) u<= m) or ((m & x) u<= m) to always true
// Same with ((x & m) u< m+1) and ((m & x) u< m+1)
!   if (cop == Op_CmpU &&
!       cmp1->Opcode() == Op_AndI) {
Node* bound = NULL;
if (_test._test == BoolTest::le) {
bound = cmp2;
} else if (_test._test == BoolTest::lt &&
cmp2->in(2)->find_int_con(0) == 1) {
bound = cmp2->in(1);
}
if (cmp1->in(2) == bound || cmp1->in(1) == bound) {
return ConINode::make(1);
}
}

// Change ((x & (m - 1)) u< m) into (m > 0)
// This is the off-by-one variant of the above
!   if (cop == Op_CmpU &&
_test._test == BoolTest::lt &&
!       cmp1->Opcode() == Op_AndI) {
Node* l = cmp1->in(1);
Node* r = cmp1->in(2);
for (int repeat = 0; repeat < 2; repeat++) {
!       bool match = r->Opcode() == Op_AddI && r->in(2)->find_int_con(0) == -1 &&
r->in(1) == cmp2;
if (match) {
// arraylength known to be non-negative, so a (arraylength != 0) is sufficient,
// but to be compatible with the array range check pattern, use (arraylength u> 0)
!         Node* ncmp = cmp2->Opcode() == Op_LoadRange
? phase->transform(new CmpUNode(cmp2, phase->intcon(0)))
: phase->transform(new CmpINode(cmp2, phase->intcon(0)));
return new BoolNode(ncmp, BoolTest::gt);
} else {
// commute and try again
--- 1338,1376 ----
return new BoolNode( ncmp, _test.negate() );
}

// Change ((x & m) u<= m) or ((m & x) u<= m) to always true
// Same with ((x & m) u< m+1) and ((m & x) u< m+1)
!   if (cop == Opcodes::Op_CmpU &&
!       cmp1->Opcode() == Opcodes::Op_AndI) {
Node* bound = NULL;
if (_test._test == BoolTest::le) {
bound = cmp2;
} else if (_test._test == BoolTest::lt &&
cmp2->in(2)->find_int_con(0) == 1) {
bound = cmp2->in(1);
}
if (cmp1->in(2) == bound || cmp1->in(1) == bound) {
return ConINode::make(1);
}
}

// Change ((x & (m - 1)) u< m) into (m > 0)
// This is the off-by-one variant of the above
!   if (cop == Opcodes::Op_CmpU &&
_test._test == BoolTest::lt &&
!       cmp1->Opcode() == Opcodes::Op_AndI) {
Node* l = cmp1->in(1);
Node* r = cmp1->in(2);
for (int repeat = 0; repeat < 2; repeat++) {
!       bool match = r->Opcode() == Opcodes::Op_AddI && r->in(2)->find_int_con(0) == -1 &&
r->in(1) == cmp2;
if (match) {
// arraylength known to be non-negative, so a (arraylength != 0) is sufficient,
// but to be compatible with the array range check pattern, use (arraylength u> 0)
!         Node* ncmp = cmp2->Opcode() == Opcodes::Op_LoadRange
? phase->transform(new CmpUNode(cmp2, phase->intcon(0)))
: phase->transform(new CmpINode(cmp2, phase->intcon(0)));
return new BoolNode(ncmp, BoolTest::gt);
} else {
// commute and try again
*** 1383,1394 ****
// Change (arraylength <= 0) or (arraylength == 0)
//   into (arraylength u<= 0)
// Also change (arraylength != 0) into (arraylength u> 0)
// The latter version matches the code pattern generated for
// array range checks, which will more likely be optimized later.
!   if (cop == Op_CmpI &&
cmp2->find_int_con(-1) == 0) {
if (_test._test == BoolTest::le || _test._test == BoolTest::eq) {
Node* ncmp = phase->transform(new CmpUNode(cmp1, cmp2));
return new BoolNode(ncmp, BoolTest::le);
} else if (_test._test == BoolTest::ne) {
--- 1383,1394 ----
// Change (arraylength <= 0) or (arraylength == 0)
//   into (arraylength u<= 0)
// Also change (arraylength != 0) into (arraylength u> 0)
// The latter version matches the code pattern generated for
// array range checks, which will more likely be optimized later.
!   if (cop == Opcodes::Op_CmpI &&
cmp2->find_int_con(-1) == 0) {
if (_test._test == BoolTest::le || _test._test == BoolTest::eq) {
Node* ncmp = phase->transform(new CmpUNode(cmp1, cmp2));
return new BoolNode(ncmp, BoolTest::le);
} else if (_test._test == BoolTest::ne) {
*** 1399,1409 ****

// Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)".
// This is a standard idiom for branching on a boolean value.
Node *c2b = cmp1;
if( cmp2_type == TypeInt::ZERO &&
!       cmp1_op == Op_Conv2B &&
(_test._test == BoolTest::eq ||
_test._test == BoolTest::ne) ) {
Node *ncmp = phase->transform(phase->type(c2b->in(1))->isa_int()
? (Node*)new CmpINode(c2b->in(1),cmp2)
: (Node*)new CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR))
--- 1399,1409 ----

// Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)".
// This is a standard idiom for branching on a boolean value.
Node *c2b = cmp1;
if( cmp2_type == TypeInt::ZERO &&
!       cmp1_op == Opcodes::Op_Conv2B &&
(_test._test == BoolTest::eq ||
_test._test == BoolTest::ne) ) {
Node *ncmp = phase->transform(phase->type(c2b->in(1))->isa_int()
? (Node*)new CmpINode(c2b->in(1),cmp2)
: (Node*)new CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR))
*** 1413,1434 ****

// Comparing a SubI against a zero is equal to comparing the SubI
// arguments directly.  This only works for eq and ne comparisons
// due to possible integer overflow.
if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
!         (cop == Op_CmpI) &&
!         (cmp1->Opcode() == Op_SubI) &&
( cmp2_type == TypeInt::ZERO ) ) {
Node *ncmp = phase->transform( new CmpINode(cmp1->in(1),cmp1->in(2)));
return new BoolNode( ncmp, _test._test );
}

// Change (-A vs 0) into (A vs 0) by commuting the test.  Disallow in the
// most general case because negating 0x80000000 does nothing.  Needed for
// the CmpF3/SubI/CmpI idiom.
!   if( cop == Op_CmpI &&
!       cmp1->Opcode() == Op_SubI &&
cmp2_type == TypeInt::ZERO &&
phase->type( cmp1->in(1) ) == TypeInt::ZERO &&
phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) {
Node *ncmp = phase->transform( new CmpINode(cmp1->in(2),cmp2));
return new BoolNode( ncmp, _test.commute() );
--- 1413,1434 ----

// Comparing a SubI against a zero is equal to comparing the SubI
// arguments directly.  This only works for eq and ne comparisons
// due to possible integer overflow.
if ((_test._test == BoolTest::eq || _test._test == BoolTest::ne) &&
!         (cop == Opcodes::Op_CmpI) &&
!         (cmp1->Opcode() == Opcodes::Op_SubI) &&
( cmp2_type == TypeInt::ZERO ) ) {
Node *ncmp = phase->transform( new CmpINode(cmp1->in(1),cmp1->in(2)));
return new BoolNode( ncmp, _test._test );
}

// Change (-A vs 0) into (A vs 0) by commuting the test.  Disallow in the
// most general case because negating 0x80000000 does nothing.  Needed for
// the CmpF3/SubI/CmpI idiom.
!   if( cop == Opcodes::Op_CmpI &&
!       cmp1->Opcode() == Opcodes::Op_SubI &&
cmp2_type == TypeInt::ZERO &&
phase->type( cmp1->in(1) ) == TypeInt::ZERO &&
phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) {
Node *ncmp = phase->transform( new CmpINode(cmp1->in(2),cmp2));
return new BoolNode( ncmp, _test.commute() );
```
< prev index next >