--- old/src/share/vm/opto/castnode.cpp 2015-12-14 17:16:56.322408101 +0100 +++ new/src/share/vm/opto/castnode.cpp 2015-12-14 17:16:56.056572283 +0100 @@ -215,6 +215,63 @@ return res; } +Node *CastIINode::Ideal(PhaseGVN *phase, bool can_reshape) { + // transform: + // (CastII (AddI x const)) -> (AddI (CastII x) const) + // So the AddI has a chance to be optimized out + if (in(1)->Opcode() == Op_AddI) { + Node* in2 = in(1)->in(2); + const TypeInt* in2_t = phase->type(in2)->isa_int(); + if (in2_t != NULL && in2_t->singleton()) { + int in2_const = in2_t->_lo; + const TypeInt* current_type = _type->is_int(); + jlong new_lo_long = ((jlong)current_type->_lo) - in2_const; + jlong new_hi_long = ((jlong)current_type->_hi) - in2_const; + int new_lo = (int)new_lo_long; + int new_hi = (int)new_hi_long; + if (((jlong)new_lo) == new_lo_long && ((jlong)new_hi) == new_hi_long) { + Node* in1 = in(1)->in(1); + CastIINode* new_cast = (CastIINode*)clone(); + AddINode* new_add = (AddINode*)in(1)->clone(); + new_cast->set_type(TypeInt::make(new_lo, new_hi, current_type->_widen)); + new_cast->set_req(1, in1); + new_add->set_req(1, phase->transform(new_cast)); + return new_add; + } + } + } + // Similar to ConvI2LNode::Ideal() for the same reasons + if (can_reshape && !phase->C->major_progress()) { + const TypeInt* this_type = this->type()->is_int(); + const TypeInt* in_type = phase->type(in(1))->isa_int(); + if (in_type != NULL && this_type != NULL && + (in_type->_lo != this_type->_lo || + in_type->_hi != this_type->_hi)) { + int lo1 = this_type->_lo; + int hi1 = this_type->_hi; + int w1 = this_type->_widen; + + if (lo1 >= 0) { + // Keep a range assertion of >=0. + lo1 = 0; hi1 = max_jint; + } else if (hi1 < 0) { + // Keep a range assertion of <0. + lo1 = min_jint; hi1 = -1; + } else { + lo1 = min_jint; hi1 = max_jint; + } + const TypeInt* wtype = TypeInt::make(MAX2(in_type->_lo, lo1), + MIN2(in_type->_hi, hi1), + MAX2((int)in_type->_widen, w1)); + if (wtype != type()) { + set_type(wtype); + return this; + } + } + } + return NULL; +} + //============================================================================= //------------------------------Identity--------------------------------------- // If input is already higher or equal to cast type, then this is an identity. --- old/src/share/vm/opto/castnode.hpp 2015-12-14 17:16:56.393073225 +0100 +++ new/src/share/vm/opto/castnode.hpp 2015-12-14 17:16:56.121064011 +0100 @@ -68,6 +68,7 @@ virtual int Opcode() const; virtual uint ideal_reg() const { return Op_RegI; } virtual const Type *Value( PhaseTransform *phase ) const; + virtual Node *Ideal(PhaseGVN *phase, bool can_reshape); }; //------------------------------CastPPNode------------------------------------- --- old/src/share/vm/opto/superword.cpp 2015-12-14 17:16:56.439488718 +0100 +++ new/src/share/vm/opto/superword.cpp 2015-12-14 17:16:56.085731056 +0100 @@ -3438,10 +3438,12 @@ if (opc == Op_ConvI2L) { n = n->in(1); } - _negate_invar = negate; - _invar = n; - NOT_PRODUCT(_tracer.offset_plus_k_10(n, _invar, _negate_invar, _offset);) - return true; + if (n->bottom_type()->isa_int()) { + _negate_invar = negate; + _invar = n; + NOT_PRODUCT(_tracer.offset_plus_k_10(n, _invar, _negate_invar, _offset);) + return true; + } } NOT_PRODUCT(_tracer.offset_plus_k_11(n);) --- old/src/share/vm/opto/loopnode.cpp 2015-12-14 17:16:56.587029375 +0100 +++ new/src/share/vm/opto/loopnode.cpp 2015-12-14 17:16:56.144270565 +0100 @@ -815,6 +815,11 @@ C->print_method(PHASE_AFTER_CLOOPS, 3); + // Capture bounds of the loop in the induction variable Phi before + // subsequent transformation (iteration splitting) obscures the + // bounds + l->phi()->as_Phi()->set_type(l->phi()->Value(&_igvn)); + return true; } @@ -3478,7 +3483,7 @@ // Second pass finds latest legal placement, and ideal loop placement. void PhaseIdealLoop::build_loop_late_post( Node *n ) { - if (n->req() == 2 && n->Opcode() == Op_ConvI2L && !C->major_progress() && !_verify_only) { + if (n->req() == 2 && (n->Opcode() == Op_ConvI2L || n->Opcode() == Op_CastII) && !C->major_progress() && !_verify_only) { _igvn._worklist.push(n); // Maybe we'll normalize it, if no more loops. } --- old/src/cpu/x86/vm/x86_64.ad 2015-12-14 17:16:56.677059738 +0100 +++ new/src/cpu/x86/vm/x86_64.ad 2015-12-14 17:16:56.305515181 +0100 @@ -1074,6 +1074,7 @@ __ vmovdqu(xmm0, Address(rsp, src_offset)); __ vmovdqu(Address(rsp, dst_offset), xmm0); __ vmovdqu(xmm0, Address(rsp, -32)); + break; case Op_VecZ: __ evmovdqul(Address(rsp, -64), xmm0, 2); __ evmovdqul(xmm0, Address(rsp, src_offset), 2); --- old/src/share/vm/opto/cfgnode.cpp 2015-12-14 17:16:56.740008031 +0100 +++ new/src/share/vm/opto/cfgnode.cpp 2015-12-14 17:16:56.344644379 +0100 @@ -903,23 +903,25 @@ return Type::TOP; // Check for trip-counted loop. If so, be smarter. - CountedLoopNode *l = r->is_CountedLoop() ? r->as_CountedLoop() : NULL; - if( l && l->can_be_counted_loop(phase) && - ((const Node*)l->phi() == this) ) { // Trip counted loop! + CountedLoopNode* l = r->is_CountedLoop() ? r->as_CountedLoop() : NULL; + if (l && l->can_be_counted_loop(phase) && + ((const Node*)l->phi() == this)) { // Trip counted loop! // protect against init_trip() or limit() returning NULL const Node *init = l->init_trip(); const Node *limit = l->limit(); - if( init != NULL && limit != NULL && l->stride_is_con() ) { - const TypeInt *lo = init ->bottom_type()->isa_int(); - const TypeInt *hi = limit->bottom_type()->isa_int(); - if( lo && hi ) { // Dying loops might have TOP here - int stride = l->stride_con(); - if( stride < 0 ) { // Down-counter loop - const TypeInt *tmp = lo; lo = hi; hi = tmp; - stride = -stride; + const Node* stride = l->stride(); + if (init != NULL && limit != NULL && stride != NULL) { + const TypeInt* lo = phase->type(init)->isa_int(); + const TypeInt* hi = phase->type(limit)->isa_int(); + const TypeInt* stride_t = phase->type(stride)->isa_int(); + if (lo != NULL && hi != NULL && stride_t != NULL) { // Dying loops might have TOP here + assert(stride_t->_hi >= stride_t->_lo, "bad stride type"); + if (stride_t->_hi < 0) { // Down-counter loop + swap(lo, hi); + return TypeInt::make(MIN2(lo->_lo, hi->_lo) , hi->_hi, 3); + } else if (stride_t->_lo >= 0) { + return TypeInt::make(lo->_lo, MAX2(lo->_hi, hi->_hi), 3); } - if( lo->_hi < hi->_lo ) // Reversed endpoints are well defined :-( - return TypeInt::make(lo->_lo,hi->_hi,3); } } }