< prev index next >

src/share/vm/opto/subnode.cpp

Print this page

        

*** 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 // Check for dead loop 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 ) ) ) assert(false, "dead loop in SubINode::Ideal"); #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 // Check for dead loop 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 ) ) ) assert(false, "dead loop in SubINode::Ideal"); #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) ); if( tadd->singleton() && tadd != Type::TOP ) { 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) ); if( tadd->singleton() && tadd != Type::TOP ) { 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 // Check for dead loop ! 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 ) ) ) assert(false, "dead loop in SubINode::Ideal"); #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) { Node *add1 = phase->transform( new AddINode( in1, in2->in(2) ) ); 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 // Check for dead loop ! 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 ) ) ) assert(false, "dead loop in SubINode::Ideal"); #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) { Node *add1 = phase->transform( new AddINode( in1, in2->in(2) ) ); 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 // Check for dead loop 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 ) ) ) assert(false, "dead loop in SubLNode::Ideal"); #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 // Check for dead loop 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 ) ) ) assert(false, "dead loop in SubLNode::Ideal"); #endif
*** 291,312 **** return new AddLNode(in1, phase->longcon(-i->get_con())); // 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) ); if( tadd->singleton() && tadd != Type::TOP ) { 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 ---- return new AddLNode(in1, phase->longcon(-i->get_con())); // 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) ); if( tadd->singleton() && tadd != Type::TOP ) { 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 // Check for dead loop ! 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 ) ) ) assert(false, "dead loop in SubLNode::Ideal"); #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) { Node *add1 = phase->transform( new AddLNode( in1, in2->in(2) ) ); 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 // Check for dead loop ! 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 ) ) ) assert(false, "dead loop in SubLNode::Ideal"); #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) { Node *add1 = phase->transform( new AddLNode( in1, in2->in(2) ) ); 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 // LoadP(AddP(foo:Klass, #java_mirror)) // 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; Node* adr = n->in(MemNode::Address); --- 824,834 ---- static inline Node* isa_java_mirror_load(PhaseGVN* phase, Node* n) { // Return the klass node for // LoadP(AddP(foo:Klass, #java_mirror)) // 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; Node* adr = n->in(MemNode::Address);
*** 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; // Take apart the address of the LoadKlass: Node* adr1 = ldk1->in(MemNode::Address); intptr_t con2 = 0; Node* ldk2 = AddPNode::Ideal_base_and_offset(adr1, phase, con2); --- 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; // Take apart the address of the LoadKlass: Node* adr1 = ldk1->in(MemNode::Address); intptr_t con2 = 0; Node* ldk2 = AddPNode::Ideal_base_and_offset(adr1, phase, con2);
*** 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()) return NULL; // Might be element-klass loading from array klass --- 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()) return NULL; // Might be element-klass loading from array klass
*** 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 // test instead. ! 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 // test instead. ! 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->Opcode() == Op_AddI && 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->Opcode() == Opcodes::Op_AddI && 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 && ! cmp1->Opcode() == Op_LoadRange && 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 && ! cmp1->Opcode() == Opcodes::Op_LoadRange && 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 >