Mercurial > hg > truffle
comparison src/share/vm/opto/subnode.cpp @ 17936:968a17f18337
8042786: Proper fix for 8032566
Summary: Check for overflow cases in range checks and collapse it if we can.
Reviewed-by: jrose, iveresov
author | kvn |
---|---|
date | Fri, 16 May 2014 12:05:14 -0700 |
parents | 085b304a1cc5 |
children | 1555c0843770 |
comparison
equal
deleted
inserted
replaced
17935:7384f6a12fc1 | 17936:968a17f18337 |
---|---|
78 return ( phase->type( in(2) )->higher_equal( zero ) ) ? in(1) : this; | 78 return ( phase->type( in(2) )->higher_equal( zero ) ) ? in(1) : this; |
79 } | 79 } |
80 | 80 |
81 //------------------------------Value------------------------------------------ | 81 //------------------------------Value------------------------------------------ |
82 // A subtract node differences it's two inputs. | 82 // A subtract node differences it's two inputs. |
83 const Type *SubNode::Value( PhaseTransform *phase ) const { | 83 const Type* SubNode::Value_common(PhaseTransform *phase) const { |
84 const Node* in1 = in(1); | 84 const Node* in1 = in(1); |
85 const Node* in2 = in(2); | 85 const Node* in2 = in(2); |
86 // Either input is TOP ==> the result is TOP | 86 // Either input is TOP ==> the result is TOP |
87 const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1); | 87 const Type* t1 = (in1 == this) ? Type::TOP : phase->type(in1); |
88 if( t1 == Type::TOP ) return Type::TOP; | 88 if( t1 == Type::TOP ) return Type::TOP; |
95 | 95 |
96 // Either input is BOTTOM ==> the result is the local BOTTOM | 96 // Either input is BOTTOM ==> the result is the local BOTTOM |
97 if( t1 == Type::BOTTOM || t2 == Type::BOTTOM ) | 97 if( t1 == Type::BOTTOM || t2 == Type::BOTTOM ) |
98 return bottom_type(); | 98 return bottom_type(); |
99 | 99 |
100 return NULL; | |
101 } | |
102 | |
103 const Type* SubNode::Value(PhaseTransform *phase) const { | |
104 const Type* t = Value_common(phase); | |
105 if (t != NULL) { | |
106 return t; | |
107 } | |
108 const Type* t1 = phase->type(in(1)); | |
109 const Type* t2 = phase->type(in(2)); | |
100 return sub(t1,t2); // Local flavor of type subtraction | 110 return sub(t1,t2); // Local flavor of type subtraction |
101 | 111 |
102 } | 112 } |
103 | 113 |
104 //============================================================================= | 114 //============================================================================= |
566 // (This is a gross hack, since the sub method never | 576 // (This is a gross hack, since the sub method never |
567 // looks at the structure of the node in any other case.) | 577 // looks at the structure of the node in any other case.) |
568 if ((jint)lo0 >= 0 && (jint)lo1 >= 0 && is_index_range_check()) | 578 if ((jint)lo0 >= 0 && (jint)lo1 >= 0 && is_index_range_check()) |
569 return TypeInt::CC_LT; | 579 return TypeInt::CC_LT; |
570 return TypeInt::CC; // else use worst case results | 580 return TypeInt::CC; // else use worst case results |
581 } | |
582 | |
583 const Type* CmpUNode::Value(PhaseTransform *phase) const { | |
584 const Type* t = SubNode::Value_common(phase); | |
585 if (t != NULL) { | |
586 return t; | |
587 } | |
588 const Node* in1 = in(1); | |
589 const Node* in2 = in(2); | |
590 const Type* t1 = phase->type(in1); | |
591 const Type* t2 = phase->type(in2); | |
592 assert(t1->isa_int(), "CmpU has only Int type inputs"); | |
593 if (t2 == TypeInt::INT) { // Compare to bottom? | |
594 return bottom_type(); | |
595 } | |
596 uint in1_op = in1->Opcode(); | |
597 if (in1_op == Op_AddI || in1_op == Op_SubI) { | |
598 // The problem rise when result of AddI(SubI) may overflow | |
599 // signed integer value. Let say the input type is | |
600 // [256, maxint] then +128 will create 2 ranges due to | |
601 // overflow: [minint, minint+127] and [384, maxint]. | |
602 // But C2 type system keep only 1 type range and as result | |
603 // it use general [minint, maxint] for this case which we | |
604 // can't optimize. | |
605 // | |
606 // Make 2 separate type ranges based on types of AddI(SubI) inputs | |
607 // and compare results of their compare. If results are the same | |
608 // CmpU node can be optimized. | |
609 const Node* in11 = in1->in(1); | |
610 const Node* in12 = in1->in(2); | |
611 const Type* t11 = (in11 == in1) ? Type::TOP : phase->type(in11); | |
612 const Type* t12 = (in12 == in1) ? Type::TOP : phase->type(in12); | |
613 // Skip cases when input types are top or bottom. | |
614 if ((t11 != Type::TOP) && (t11 != TypeInt::INT) && | |
615 (t12 != Type::TOP) && (t12 != TypeInt::INT)) { | |
616 const TypeInt *r0 = t11->is_int(); | |
617 const TypeInt *r1 = t12->is_int(); | |
618 jlong lo_r0 = r0->_lo; | |
619 jlong hi_r0 = r0->_hi; | |
620 jlong lo_r1 = r1->_lo; | |
621 jlong hi_r1 = r1->_hi; | |
622 if (in1_op == Op_SubI) { | |
623 jlong tmp = hi_r1; | |
624 hi_r1 = -lo_r1; | |
625 lo_r1 = -tmp; | |
626 // Note, for substructing [minint,x] type range | |
627 // long arithmetic provides correct overflow answer. | |
628 // The confusion come from the fact that in 32-bit | |
629 // -minint == minint but in 64-bit -minint == maxint+1. | |
630 } | |
631 jlong lo_long = lo_r0 + lo_r1; | |
632 jlong hi_long = hi_r0 + hi_r1; | |
633 int lo_tr1 = min_jint; | |
634 int hi_tr1 = (int)hi_long; | |
635 int lo_tr2 = (int)lo_long; | |
636 int hi_tr2 = max_jint; | |
637 bool underflow = lo_long != (jlong)lo_tr2; | |
638 bool overflow = hi_long != (jlong)hi_tr1; | |
639 // Use sub(t1, t2) when there is no overflow (one type range) | |
640 // or when both overflow and underflow (too complex). | |
641 if ((underflow != overflow) && (hi_tr1 < lo_tr2)) { | |
642 // Overflow only on one boundary, compare 2 separate type ranges. | |
643 int w = MAX2(r0->_widen, r1->_widen); // _widen does not matter here | |
644 const TypeInt* tr1 = TypeInt::make(lo_tr1, hi_tr1, w); | |
645 const TypeInt* tr2 = TypeInt::make(lo_tr2, hi_tr2, w); | |
646 const Type* cmp1 = sub(tr1, t2); | |
647 const Type* cmp2 = sub(tr2, t2); | |
648 if (cmp1 == cmp2) { | |
649 return cmp1; // Hit! | |
650 } | |
651 } | |
652 } | |
653 } | |
654 | |
655 return sub(t1, t2); // Local flavor of type subtraction | |
571 } | 656 } |
572 | 657 |
573 bool CmpUNode::is_index_range_check() const { | 658 bool CmpUNode::is_index_range_check() const { |
574 // Check for the "(X ModI Y) CmpU Y" shape | 659 // Check for the "(X ModI Y) CmpU Y" shape |
575 return (in(1)->Opcode() == Op_ModI && | 660 return (in(1)->Opcode() == Op_ModI && |