1.1 --- a/src/share/vm/opto/subnode.cpp Thu May 15 18:23:26 2014 -0400 1.2 +++ b/src/share/vm/opto/subnode.cpp Fri May 16 12:05:14 2014 -0700 1.3 @@ -80,7 +80,7 @@ 1.4 1.5 //------------------------------Value------------------------------------------ 1.6 // A subtract node differences it's two inputs. 1.7 -const Type *SubNode::Value( PhaseTransform *phase ) const { 1.8 +const Type* SubNode::Value_common(PhaseTransform *phase) const { 1.9 const Node* in1 = in(1); 1.10 const Node* in2 = in(2); 1.11 // Either input is TOP ==> the result is TOP 1.12 @@ -97,6 +97,16 @@ 1.13 if( t1 == Type::BOTTOM || t2 == Type::BOTTOM ) 1.14 return bottom_type(); 1.15 1.16 + return NULL; 1.17 +} 1.18 + 1.19 +const Type* SubNode::Value(PhaseTransform *phase) const { 1.20 + const Type* t = Value_common(phase); 1.21 + if (t != NULL) { 1.22 + return t; 1.23 + } 1.24 + const Type* t1 = phase->type(in(1)); 1.25 + const Type* t2 = phase->type(in(2)); 1.26 return sub(t1,t2); // Local flavor of type subtraction 1.27 1.28 } 1.29 @@ -570,6 +580,81 @@ 1.30 return TypeInt::CC; // else use worst case results 1.31 } 1.32 1.33 +const Type* CmpUNode::Value(PhaseTransform *phase) const { 1.34 + const Type* t = SubNode::Value_common(phase); 1.35 + if (t != NULL) { 1.36 + return t; 1.37 + } 1.38 + const Node* in1 = in(1); 1.39 + const Node* in2 = in(2); 1.40 + const Type* t1 = phase->type(in1); 1.41 + const Type* t2 = phase->type(in2); 1.42 + assert(t1->isa_int(), "CmpU has only Int type inputs"); 1.43 + if (t2 == TypeInt::INT) { // Compare to bottom? 1.44 + return bottom_type(); 1.45 + } 1.46 + uint in1_op = in1->Opcode(); 1.47 + if (in1_op == Op_AddI || in1_op == Op_SubI) { 1.48 + // The problem rise when result of AddI(SubI) may overflow 1.49 + // signed integer value. Let say the input type is 1.50 + // [256, maxint] then +128 will create 2 ranges due to 1.51 + // overflow: [minint, minint+127] and [384, maxint]. 1.52 + // But C2 type system keep only 1 type range and as result 1.53 + // it use general [minint, maxint] for this case which we 1.54 + // can't optimize. 1.55 + // 1.56 + // Make 2 separate type ranges based on types of AddI(SubI) inputs 1.57 + // and compare results of their compare. If results are the same 1.58 + // CmpU node can be optimized. 1.59 + const Node* in11 = in1->in(1); 1.60 + const Node* in12 = in1->in(2); 1.61 + const Type* t11 = (in11 == in1) ? Type::TOP : phase->type(in11); 1.62 + const Type* t12 = (in12 == in1) ? Type::TOP : phase->type(in12); 1.63 + // Skip cases when input types are top or bottom. 1.64 + if ((t11 != Type::TOP) && (t11 != TypeInt::INT) && 1.65 + (t12 != Type::TOP) && (t12 != TypeInt::INT)) { 1.66 + const TypeInt *r0 = t11->is_int(); 1.67 + const TypeInt *r1 = t12->is_int(); 1.68 + jlong lo_r0 = r0->_lo; 1.69 + jlong hi_r0 = r0->_hi; 1.70 + jlong lo_r1 = r1->_lo; 1.71 + jlong hi_r1 = r1->_hi; 1.72 + if (in1_op == Op_SubI) { 1.73 + jlong tmp = hi_r1; 1.74 + hi_r1 = -lo_r1; 1.75 + lo_r1 = -tmp; 1.76 + // Note, for substructing [minint,x] type range 1.77 + // long arithmetic provides correct overflow answer. 1.78 + // The confusion come from the fact that in 32-bit 1.79 + // -minint == minint but in 64-bit -minint == maxint+1. 1.80 + } 1.81 + jlong lo_long = lo_r0 + lo_r1; 1.82 + jlong hi_long = hi_r0 + hi_r1; 1.83 + int lo_tr1 = min_jint; 1.84 + int hi_tr1 = (int)hi_long; 1.85 + int lo_tr2 = (int)lo_long; 1.86 + int hi_tr2 = max_jint; 1.87 + bool underflow = lo_long != (jlong)lo_tr2; 1.88 + bool overflow = hi_long != (jlong)hi_tr1; 1.89 + // Use sub(t1, t2) when there is no overflow (one type range) 1.90 + // or when both overflow and underflow (too complex). 1.91 + if ((underflow != overflow) && (hi_tr1 < lo_tr2)) { 1.92 + // Overflow only on one boundary, compare 2 separate type ranges. 1.93 + int w = MAX2(r0->_widen, r1->_widen); // _widen does not matter here 1.94 + const TypeInt* tr1 = TypeInt::make(lo_tr1, hi_tr1, w); 1.95 + const TypeInt* tr2 = TypeInt::make(lo_tr2, hi_tr2, w); 1.96 + const Type* cmp1 = sub(tr1, t2); 1.97 + const Type* cmp2 = sub(tr2, t2); 1.98 + if (cmp1 == cmp2) { 1.99 + return cmp1; // Hit! 1.100 + } 1.101 + } 1.102 + } 1.103 + } 1.104 + 1.105 + return sub(t1, t2); // Local flavor of type subtraction 1.106 +} 1.107 + 1.108 bool CmpUNode::is_index_range_check() const { 1.109 // Check for the "(X ModI Y) CmpU Y" shape 1.110 return (in(1)->Opcode() == Op_ModI &&