OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/bootstrapper.h" | 5 #include "src/bootstrapper.h" |
6 #include "src/compiler/graph-inl.h" | 6 #include "src/compiler/graph-inl.h" |
7 #include "src/compiler/js-operator.h" | 7 #include "src/compiler/js-operator.h" |
8 #include "src/compiler/node.h" | 8 #include "src/compiler/node.h" |
9 #include "src/compiler/node-properties-inl.h" | 9 #include "src/compiler/node-properties-inl.h" |
10 #include "src/compiler/node-properties.h" | 10 #include "src/compiler/node-properties.h" |
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
710 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { | 710 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { |
711 Factory* f = t->isolate()->factory(); | 711 Factory* f = t->isolate()->factory(); |
712 lhs = NumberToInt32(ToNumber(lhs, t), t); | 712 lhs = NumberToInt32(ToNumber(lhs, t), t); |
713 rhs = NumberToInt32(ToNumber(rhs, t), t); | 713 rhs = NumberToInt32(ToNumber(rhs, t), t); |
714 double lmin = lhs->Min(); | 714 double lmin = lhs->Min(); |
715 double rmin = rhs->Min(); | 715 double rmin = rhs->Min(); |
716 double lmax = lhs->Max(); | 716 double lmax = lhs->Max(); |
717 double rmax = rhs->Max(); | 717 double rmax = rhs->Max(); |
718 // Or-ing any two values results in a value no smaller than their minimum. | 718 // Or-ing any two values results in a value no smaller than their minimum. |
719 // Even no smaller than their maximum if both values are non-negative. | 719 // Even no smaller than their maximum if both values are non-negative. |
720 Handle<Object> min = f->NewNumber( | 720 double min = |
721 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin)); | 721 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin); |
| 722 double max = Type::Signed32()->Max(); |
| 723 |
| 724 // Or-ing with 0 is essentially a conversion to int32. |
| 725 if (rmin == 0 && rmax == 0) { |
| 726 min = lmin; |
| 727 max = lmax; |
| 728 } |
| 729 if (lmin == 0 && lmax == 0) { |
| 730 min = rmin; |
| 731 max = rmax; |
| 732 } |
| 733 |
722 if (lmax < 0 || rmax < 0) { | 734 if (lmax < 0 || rmax < 0) { |
723 // Or-ing two values of which at least one is negative results in a negative | 735 // Or-ing two values of which at least one is negative results in a negative |
724 // value. | 736 // value. |
725 Handle<Object> max = f->NewNumber(-1); | 737 max = std::min(max, -1.0); |
726 return Type::Range(min, max, t->zone()); | |
727 } | 738 } |
728 Handle<Object> max = f->NewNumber(Type::Signed32()->Max()); | 739 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone()); |
729 return Type::Range(min, max, t->zone()); | |
730 // TODO(neis): Be precise for singleton inputs, here and elsewhere. | 740 // TODO(neis): Be precise for singleton inputs, here and elsewhere. |
731 } | 741 } |
732 | 742 |
733 | 743 |
734 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { | 744 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { |
735 Factory* f = t->isolate()->factory(); | 745 Factory* f = t->isolate()->factory(); |
736 lhs = NumberToInt32(ToNumber(lhs, t), t); | 746 lhs = NumberToInt32(ToNumber(lhs, t), t); |
737 rhs = NumberToInt32(ToNumber(rhs, t), t); | 747 rhs = NumberToInt32(ToNumber(rhs, t), t); |
738 double lmin = lhs->Min(); | 748 double lmin = lhs->Min(); |
739 double rmin = rhs->Min(); | 749 double rmin = rhs->Min(); |
740 double lmax = lhs->Max(); | 750 double lmax = lhs->Max(); |
741 double rmax = rhs->Max(); | 751 double rmax = rhs->Max(); |
| 752 double min = Type::Signed32()->Min(); |
742 // And-ing any two values results in a value no larger than their maximum. | 753 // And-ing any two values results in a value no larger than their maximum. |
743 // Even no larger than their minimum if both values are non-negative. | 754 // Even no larger than their minimum if both values are non-negative. |
744 Handle<Object> max = f->NewNumber( | 755 double max = |
745 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax)); | 756 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax); |
746 if (lmin >= 0 || rmin >= 0) { | 757 // And-ing with a non-negative value x causes the result to be between |
747 // And-ing two values of which at least one is non-negative results in a | 758 // zero and x. |
748 // non-negative value. | 759 if (lmin >= 0) { |
749 Handle<Object> min = f->NewNumber(0); | 760 min = 0; |
750 return Type::Range(min, max, t->zone()); | 761 max = std::min(max, lmax); |
751 } | 762 } |
752 Handle<Object> min = f->NewNumber(Type::Signed32()->Min()); | 763 if (rmin >= 0) { |
753 return Type::Range(min, max, t->zone()); | 764 min = 0; |
| 765 max = std::min(max, rmax); |
| 766 } |
| 767 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone()); |
754 } | 768 } |
755 | 769 |
756 | 770 |
757 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { | 771 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { |
758 lhs = NumberToInt32(ToNumber(lhs, t), t); | 772 lhs = NumberToInt32(ToNumber(lhs, t), t); |
759 rhs = NumberToInt32(ToNumber(rhs, t), t); | 773 rhs = NumberToInt32(ToNumber(rhs, t), t); |
760 double lmin = lhs->Min(); | 774 double lmin = lhs->Min(); |
761 double rmin = rhs->Min(); | 775 double rmin = rhs->Min(); |
762 double lmax = lhs->Max(); | 776 double lmax = lhs->Max(); |
763 double rmax = rhs->Max(); | 777 double rmax = rhs->Max(); |
764 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) { | 778 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) { |
765 // Xor-ing negative or non-negative values results in a non-negative value. | 779 // Xor-ing negative or non-negative values results in a non-negative value. |
766 return t->non_negative_signed32; | 780 return t->non_negative_signed32; |
767 } | 781 } |
768 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) { | 782 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) { |
769 // Xor-ing a negative and a non-negative value results in a negative value. | 783 // Xor-ing a negative and a non-negative value results in a negative value. |
770 return t->negative_signed32; | 784 return t->negative_signed32; |
771 } | 785 } |
772 return Type::Signed32(); | 786 return Type::Signed32(); |
773 } | 787 } |
774 | 788 |
775 | 789 |
776 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { | 790 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { |
777 return Type::Signed32(); | 791 return Type::Signed32(); |
778 } | 792 } |
779 | 793 |
780 | 794 |
781 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { | 795 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { |
782 lhs = NumberToInt32(ToNumber(lhs, t), t); | 796 lhs = NumberToInt32(ToNumber(lhs, t), t); |
783 Factory* f = t->isolate()->factory(); | 797 rhs = NumberToUint32(ToNumber(rhs, t), t); |
| 798 double min = kMinInt; |
| 799 double max = kMaxInt; |
784 if (lhs->Min() >= 0) { | 800 if (lhs->Min() >= 0) { |
785 // Right-shifting a non-negative value cannot make it negative, nor larger. | 801 // Right-shifting a non-negative value cannot make it negative, nor larger. |
786 Handle<Object> min = f->NewNumber(0); | 802 min = std::max(min, 0.0); |
787 Handle<Object> max = f->NewNumber(lhs->Max()); | 803 max = std::min(max, lhs->Max()); |
788 return Type::Range(min, max, t->zone()); | |
789 } | 804 } |
790 if (lhs->Max() < 0) { | 805 if (lhs->Max() < 0) { |
791 // Right-shifting a negative value cannot make it non-negative, nor smaller. | 806 // Right-shifting a negative value cannot make it non-negative, nor smaller. |
792 Handle<Object> min = f->NewNumber(lhs->Min()); | 807 min = std::max(min, lhs->Min()); |
793 Handle<Object> max = f->NewNumber(-1); | 808 max = std::min(max, -1.0); |
794 return Type::Range(min, max, t->zone()); | 809 } |
| 810 if (rhs->Min() > 0 && rhs->Max() <= 31) { |
| 811 // Right-shifting by a positive value yields a small integer value. |
| 812 double shift_min = kMinInt >> static_cast<int>(rhs->Min()); |
| 813 double shift_max = kMaxInt >> static_cast<int>(rhs->Min()); |
| 814 min = std::max(min, shift_min); |
| 815 max = std::min(max, shift_max); |
| 816 } |
| 817 // TODO(jarin) Ideally, the following micro-optimization should be performed |
| 818 // by the type constructor. |
| 819 if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) { |
| 820 Factory* f = t->isolate()->factory(); |
| 821 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone()); |
795 } | 822 } |
796 return Type::Signed32(); | 823 return Type::Signed32(); |
797 } | 824 } |
798 | 825 |
799 | 826 |
800 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { | 827 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { |
801 lhs = NumberToUint32(ToNumber(lhs, t), t); | 828 lhs = NumberToUint32(ToNumber(lhs, t), t); |
802 Factory* f = t->isolate()->factory(); | 829 Factory* f = t->isolate()->factory(); |
803 // Logical right-shifting any value cannot make it larger. | 830 // Logical right-shifting any value cannot make it larger. |
804 Handle<Object> min = f->NewNumber(0); | 831 Handle<Object> min = f->NewNumber(0); |
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1933 return typer_->float64_array_fun_; | 1960 return typer_->float64_array_fun_; |
1934 } | 1961 } |
1935 } | 1962 } |
1936 } | 1963 } |
1937 return Type::Constant(value, zone()); | 1964 return Type::Constant(value, zone()); |
1938 } | 1965 } |
1939 | 1966 |
1940 } | 1967 } |
1941 } | 1968 } |
1942 } // namespace v8::internal::compiler | 1969 } // namespace v8::internal::compiler |
OLD | NEW |