| 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 |