Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/compiler/typer.cc

Issue 882063002: [turbofan] Use unboxed doubles in range types. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Make tests less fragile. Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/typer.h ('k') | src/types.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/graph-reducer.h" 7 #include "src/compiler/graph-reducer.h"
8 #include "src/compiler/js-operator.h" 8 #include "src/compiler/js-operator.h"
9 #include "src/compiler/node.h" 9 #include "src/compiler/node.h"
10 #include "src/compiler/node-properties-inl.h" 10 #include "src/compiler/node-properties-inl.h"
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
122 return Type::Intersect(semantic, representation, zone()); 122 return Type::Intersect(semantic, representation, zone());
123 } 123 }
124 124
125 template <typename T> 125 template <typename T>
126 Type* CreateRange() const { 126 Type* CreateRange() const {
127 return CreateRange(std::numeric_limits<T>::min(), 127 return CreateRange(std::numeric_limits<T>::min(),
128 std::numeric_limits<T>::max()); 128 std::numeric_limits<T>::max());
129 } 129 }
130 130
131 Type* CreateRange(double min, double max) const { 131 Type* CreateRange(double min, double max) const {
132 return Type::Range(factory()->NewNumber(min), factory()->NewNumber(max), 132 return Type::Range(min, max, zone());
133 zone());
134 } 133 }
135 134
136 Factory* factory() const { return isolate()->factory(); } 135 Factory* factory() const { return isolate()->factory(); }
137 Isolate* isolate() const { return isolate_; } 136 Isolate* isolate() const { return isolate_; }
138 Zone* zone() const { return zone_; } 137 Zone* zone() const { return zone_; }
139 138
140 Type* cache_[kNumLazyCachedTypes]; 139 Type* cache_[kNumLazyCachedTypes];
141 Isolate* isolate_; 140 Isolate* isolate_;
142 Zone* zone_; 141 Zone* zone_;
143 }; 142 };
(...skipping 13 matching lines...) Expand all
157 : isolate_(isolate), 156 : isolate_(isolate),
158 graph_(graph), 157 graph_(graph),
159 context_(context), 158 context_(context),
160 decorator_(NULL), 159 decorator_(NULL),
161 cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())), 160 cache_(new (graph->zone()) LazyTypeCache(isolate, graph->zone())),
162 weaken_min_limits_(graph->zone()), 161 weaken_min_limits_(graph->zone()),
163 weaken_max_limits_(graph->zone()) { 162 weaken_max_limits_(graph->zone()) {
164 Zone* zone = this->zone(); 163 Zone* zone = this->zone();
165 Factory* f = isolate->factory(); 164 Factory* f = isolate->factory();
166 165
167 Handle<Object> zero = f->NewNumber(0);
168 Handle<Object> one = f->NewNumber(1);
169 Handle<Object> infinity = f->NewNumber(+V8_INFINITY); 166 Handle<Object> infinity = f->NewNumber(+V8_INFINITY);
170 Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY); 167 Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY);
171 168
172 Type* number = Type::Number(); 169 Type* number = Type::Number();
173 Type* signed32 = Type::Signed32(); 170 Type* signed32 = Type::Signed32();
174 Type* unsigned32 = Type::Unsigned32(); 171 Type* unsigned32 = Type::Unsigned32();
175 Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone); 172 Type* nan_or_minuszero = Type::Union(Type::NaN(), Type::MinusZero(), zone);
176 Type* truncating_to_zero = 173 Type* truncating_to_zero =
177 Type::Union(Type::Union(Type::Constant(infinity, zone), 174 Type::Union(Type::Union(Type::Constant(infinity, zone),
178 Type::Constant(minusinfinity, zone), zone), 175 Type::Constant(minusinfinity, zone), zone),
179 nan_or_minuszero, zone); 176 nan_or_minuszero, zone);
180 177
181 boolean_or_number = Type::Union(Type::Boolean(), Type::Number(), zone); 178 boolean_or_number = Type::Union(Type::Boolean(), Type::Number(), zone);
182 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone); 179 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone);
183 undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone); 180 undefined_or_number = Type::Union(Type::Undefined(), Type::Number(), zone);
184 singleton_false = Type::Constant(f->false_value(), zone); 181 singleton_false = Type::Constant(f->false_value(), zone);
185 singleton_true = Type::Constant(f->true_value(), zone); 182 singleton_true = Type::Constant(f->true_value(), zone);
186 singleton_zero = Type::Range(zero, zero, zone); 183 singleton_zero = Type::Range(0.0, 0.0, zone);
187 singleton_one = Type::Range(one, one, zone); 184 singleton_one = Type::Range(1.0, 1.0, zone);
188 zero_or_one = Type::Union(singleton_zero, singleton_one, zone); 185 zero_or_one = Type::Union(singleton_zero, singleton_one, zone);
189 zeroish = Type::Union(singleton_zero, nan_or_minuszero, zone); 186 zeroish = Type::Union(singleton_zero, nan_or_minuszero, zone);
190 signed32ish = Type::Union(signed32, truncating_to_zero, zone); 187 signed32ish = Type::Union(signed32, truncating_to_zero, zone);
191 unsigned32ish = Type::Union(unsigned32, truncating_to_zero, zone); 188 unsigned32ish = Type::Union(unsigned32, truncating_to_zero, zone);
192 falsish = Type::Union(Type::Undetectable(), 189 falsish = Type::Union(Type::Undetectable(),
193 Type::Union(Type::Union(singleton_false, zeroish, zone), 190 Type::Union(Type::Union(singleton_false, zeroish, zone),
194 undefined_or_null, zone), 191 undefined_or_null, zone),
195 zone); 192 zone);
196 truish = Type::Union( 193 truish = Type::Union(
197 singleton_true, 194 singleton_true,
198 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); 195 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
199 integer = Type::Range(minusinfinity, infinity, zone); 196 integer = Type::Range(-V8_INFINITY, V8_INFINITY, zone);
200 weakint = Type::Union(integer, nan_or_minuszero, zone); 197 weakint = Type::Union(integer, nan_or_minuszero, zone);
201 198
202 number_fun0_ = Type::Function(number, zone); 199 number_fun0_ = Type::Function(number, zone);
203 number_fun1_ = Type::Function(number, number, zone); 200 number_fun1_ = Type::Function(number, number, zone);
204 number_fun2_ = Type::Function(number, number, number, zone); 201 number_fun2_ = Type::Function(number, number, number, zone);
205 202
206 weakint_fun1_ = Type::Function(weakint, number, zone); 203 weakint_fun1_ = Type::Function(weakint, number, zone);
207 random_fun_ = Type::Function(Type::OrderedNumber(), zone); 204 random_fun_ = Type::Function(Type::OrderedNumber(), zone);
208 205
209 const int limits_count = 20; 206 const int limits_count = 20;
210 207
211 weaken_min_limits_.reserve(limits_count + 1); 208 weaken_min_limits_.reserve(limits_count + 1);
212 weaken_max_limits_.reserve(limits_count + 1); 209 weaken_max_limits_.reserve(limits_count + 1);
213 210
214 double limit = 1 << 30; 211 double limit = 1 << 30;
215 weaken_min_limits_.push_back(f->NewNumber(0)); 212 weaken_min_limits_.push_back(0);
216 weaken_max_limits_.push_back(f->NewNumber(0)); 213 weaken_max_limits_.push_back(0);
217 for (int i = 0; i < limits_count; i++) { 214 for (int i = 0; i < limits_count; i++) {
218 weaken_min_limits_.push_back(f->NewNumber(-limit)); 215 weaken_min_limits_.push_back(-limit);
219 weaken_max_limits_.push_back(f->NewNumber(limit - 1)); 216 weaken_max_limits_.push_back(limit - 1);
220 limit *= 2; 217 limit *= 2;
221 } 218 }
222 219
223 decorator_ = new (zone) Decorator(this); 220 decorator_ = new (zone) Decorator(this);
224 graph_->AddDecorator(decorator_); 221 graph_->AddDecorator(decorator_);
225 } 222 }
226 223
227 224
228 Typer::~Typer() { 225 Typer::~Typer() {
229 graph_->RemoveDecorator(decorator_); 226 graph_->RemoveDecorator(decorator_);
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 return type; // Give up on non-integer types. 486 return type; // Give up on non-integer types.
490 } 487 }
491 double min = type->Min(); 488 double min = type->Min();
492 double max = type->Max(); 489 double max = type->Max();
493 // Handle the degenerate case of empty bitset types (such as 490 // Handle the degenerate case of empty bitset types (such as
494 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures). 491 // OtherUnsigned31 and OtherSigned32 on 64-bit architectures).
495 if (std::isnan(min)) { 492 if (std::isnan(min)) {
496 DCHECK(std::isnan(max)); 493 DCHECK(std::isnan(max));
497 return type; 494 return type;
498 } 495 }
499 Factory* f = t->isolate()->factory(); 496 return Type::Range(min, max, t->zone());
500 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
501 } 497 }
502 498
503 499
504 // Type conversion. 500 // Type conversion.
505 501
506 502
507 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { 503 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) {
508 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { 504 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
509 return type; 505 return type;
510 } 506 }
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
603 // OSR values explicitly have type {None} before OSR form is deconstructed. 599 // OSR values explicitly have type {None} before OSR form is deconstructed.
604 if (node->InputAt(0)->opcode() == IrOpcode::kOsrLoopEntry) { 600 if (node->InputAt(0)->opcode() == IrOpcode::kOsrLoopEntry) {
605 return Bounds(Type::None(), Type::None()); 601 return Bounds(Type::None(), Type::None());
606 } 602 }
607 // TODO(turbofan): preserve the type of OSR values after deconstruction. 603 // TODO(turbofan): preserve the type of OSR values after deconstruction.
608 return Bounds::Unbounded(zone()); 604 return Bounds::Unbounded(zone());
609 } 605 }
610 606
611 607
612 Bounds Typer::Visitor::TypeInt32Constant(Node* node) { 608 Bounds Typer::Visitor::TypeInt32Constant(Node* node) {
613 Factory* f = isolate()->factory(); 609 double number = OpParameter<int32_t>(node);
614 Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node));
615 return Bounds(Type::Intersect( 610 return Bounds(Type::Intersect(
616 Type::Range(number, number, zone()), Type::UntaggedSigned32(), zone())); 611 Type::Range(number, number, zone()), Type::UntaggedSigned32(), zone()));
617 } 612 }
618 613
619 614
620 Bounds Typer::Visitor::TypeInt64Constant(Node* node) { 615 Bounds Typer::Visitor::TypeInt64Constant(Node* node) {
621 // TODO(rossberg): This actually seems to be a PointerConstant so far... 616 // TODO(rossberg): This actually seems to be a PointerConstant so far...
622 return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type? 617 return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type?
623 } 618 }
624 619
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
819 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( 814 Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
820 Type* lhs, Type* rhs, Typer* t) { 815 Type* lhs, Type* rhs, Typer* t) {
821 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); 816 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
822 } 817 }
823 818
824 819
825 // JS bitwise operators. 820 // JS bitwise operators.
826 821
827 822
828 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { 823 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
829 Factory* f = t->isolate()->factory();
830 lhs = NumberToInt32(ToNumber(lhs, t), t); 824 lhs = NumberToInt32(ToNumber(lhs, t), t);
831 rhs = NumberToInt32(ToNumber(rhs, t), t); 825 rhs = NumberToInt32(ToNumber(rhs, t), t);
832 double lmin = lhs->Min(); 826 double lmin = lhs->Min();
833 double rmin = rhs->Min(); 827 double rmin = rhs->Min();
834 double lmax = lhs->Max(); 828 double lmax = lhs->Max();
835 double rmax = rhs->Max(); 829 double rmax = rhs->Max();
836 // Or-ing any two values results in a value no smaller than their minimum. 830 // Or-ing any two values results in a value no smaller than their minimum.
837 // Even no smaller than their maximum if both values are non-negative. 831 // Even no smaller than their maximum if both values are non-negative.
838 double min = 832 double min =
839 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin); 833 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin);
840 double max = Type::Signed32()->Max(); 834 double max = Type::Signed32()->Max();
841 835
842 // Or-ing with 0 is essentially a conversion to int32. 836 // Or-ing with 0 is essentially a conversion to int32.
843 if (rmin == 0 && rmax == 0) { 837 if (rmin == 0 && rmax == 0) {
844 min = lmin; 838 min = lmin;
845 max = lmax; 839 max = lmax;
846 } 840 }
847 if (lmin == 0 && lmax == 0) { 841 if (lmin == 0 && lmax == 0) {
848 min = rmin; 842 min = rmin;
849 max = rmax; 843 max = rmax;
850 } 844 }
851 845
852 if (lmax < 0 || rmax < 0) { 846 if (lmax < 0 || rmax < 0) {
853 // Or-ing two values of which at least one is negative results in a negative 847 // Or-ing two values of which at least one is negative results in a negative
854 // value. 848 // value.
855 max = std::min(max, -1.0); 849 max = std::min(max, -1.0);
856 } 850 }
857 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone()); 851 return Type::Range(min, max, t->zone());
858 // TODO(neis): Be precise for singleton inputs, here and elsewhere. 852 // TODO(neis): Be precise for singleton inputs, here and elsewhere.
859 } 853 }
860 854
861 855
862 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { 856 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
863 Factory* f = t->isolate()->factory();
864 lhs = NumberToInt32(ToNumber(lhs, t), t); 857 lhs = NumberToInt32(ToNumber(lhs, t), t);
865 rhs = NumberToInt32(ToNumber(rhs, t), t); 858 rhs = NumberToInt32(ToNumber(rhs, t), t);
866 double lmin = lhs->Min(); 859 double lmin = lhs->Min();
867 double rmin = rhs->Min(); 860 double rmin = rhs->Min();
868 double lmax = lhs->Max(); 861 double lmax = lhs->Max();
869 double rmax = rhs->Max(); 862 double rmax = rhs->Max();
870 double min = Type::Signed32()->Min(); 863 double min = Type::Signed32()->Min();
871 // And-ing any two values results in a value no larger than their maximum. 864 // And-ing any two values results in a value no larger than their maximum.
872 // Even no larger than their minimum if both values are non-negative. 865 // Even no larger than their minimum if both values are non-negative.
873 double max = 866 double max =
874 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax); 867 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax);
875 // And-ing with a non-negative value x causes the result to be between 868 // And-ing with a non-negative value x causes the result to be between
876 // zero and x. 869 // zero and x.
877 if (lmin >= 0) { 870 if (lmin >= 0) {
878 min = 0; 871 min = 0;
879 max = std::min(max, lmax); 872 max = std::min(max, lmax);
880 } 873 }
881 if (rmin >= 0) { 874 if (rmin >= 0) {
882 min = 0; 875 min = 0;
883 max = std::min(max, rmax); 876 max = std::min(max, rmax);
884 } 877 }
885 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone()); 878 return Type::Range(min, max, t->zone());
886 } 879 }
887 880
888 881
889 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { 882 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) {
890 lhs = NumberToInt32(ToNumber(lhs, t), t); 883 lhs = NumberToInt32(ToNumber(lhs, t), t);
891 rhs = NumberToInt32(ToNumber(rhs, t), t); 884 rhs = NumberToInt32(ToNumber(rhs, t), t);
892 double lmin = lhs->Min(); 885 double lmin = lhs->Min();
893 double rmin = rhs->Min(); 886 double rmin = rhs->Min();
894 double lmax = lhs->Max(); 887 double lmax = lhs->Max();
895 double rmax = rhs->Max(); 888 double rmax = rhs->Max();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 if (rhs->Min() > 0 && rhs->Max() <= 31) { 928 if (rhs->Min() > 0 && rhs->Max() <= 31) {
936 // Right-shifting by a positive value yields a small integer value. 929 // Right-shifting by a positive value yields a small integer value.
937 double shift_min = kMinInt >> static_cast<int>(rhs->Min()); 930 double shift_min = kMinInt >> static_cast<int>(rhs->Min());
938 double shift_max = kMaxInt >> static_cast<int>(rhs->Min()); 931 double shift_max = kMaxInt >> static_cast<int>(rhs->Min());
939 min = std::max(min, shift_min); 932 min = std::max(min, shift_min);
940 max = std::min(max, shift_max); 933 max = std::min(max, shift_max);
941 } 934 }
942 // TODO(jarin) Ideally, the following micro-optimization should be performed 935 // TODO(jarin) Ideally, the following micro-optimization should be performed
943 // by the type constructor. 936 // by the type constructor.
944 if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) { 937 if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) {
945 Factory* f = t->isolate()->factory(); 938 return Type::Range(min, max, t->zone());
946 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
947 } 939 }
948 return Type::Signed32(); 940 return Type::Signed32();
949 } 941 }
950 942
951 943
952 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { 944 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
953 lhs = NumberToUint32(ToNumber(lhs, t), t); 945 lhs = NumberToUint32(ToNumber(lhs, t), t);
954 Factory* f = t->isolate()->factory();
955 // Logical right-shifting any value cannot make it larger. 946 // Logical right-shifting any value cannot make it larger.
956 Handle<Object> min = f->NewNumber(0); 947 return Type::Range(0.0, lhs->Max(), t->zone());
957 Handle<Object> max = f->NewNumber(lhs->Max());
958 return Type::Range(min, max, t->zone());
959 } 948 }
960 949
961 950
962 // JS arithmetic operators. 951 // JS arithmetic operators.
963 952
964 953
965 // Returns the array's least element, ignoring NaN. 954 // Returns the array's least element, ignoring NaN.
966 // There must be at least one non-NaN element. 955 // There must be at least one non-NaN element.
967 // Any -0 is converted to 0. 956 // Any -0 is converted to 0.
968 static double array_min(double a[], size_t n) { 957 static double array_min(double a[], size_t n) {
(...skipping 21 matching lines...) Expand all
990 } 979 }
991 } 980 }
992 DCHECK(!std::isnan(x)); 981 DCHECK(!std::isnan(x));
993 return x == 0 ? 0 : x; // -0 -> 0 982 return x == 0 ? 0 : x; // -0 -> 0
994 } 983 }
995 984
996 985
997 Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs, 986 Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs,
998 Typer* t) { 987 Typer* t) {
999 double results[4]; 988 double results[4];
1000 results[0] = lhs->Min()->Number() + rhs->Min()->Number(); 989 results[0] = lhs->Min() + rhs->Min();
1001 results[1] = lhs->Min()->Number() + rhs->Max()->Number(); 990 results[1] = lhs->Min() + rhs->Max();
1002 results[2] = lhs->Max()->Number() + rhs->Min()->Number(); 991 results[2] = lhs->Max() + rhs->Min();
1003 results[3] = lhs->Max()->Number() + rhs->Max()->Number(); 992 results[3] = lhs->Max() + rhs->Max();
1004 // Since none of the inputs can be -0, the result cannot be -0 either. 993 // Since none of the inputs can be -0, the result cannot be -0 either.
1005 // However, it can be nan (the sum of two infinities of opposite sign). 994 // However, it can be nan (the sum of two infinities of opposite sign).
1006 // On the other hand, if none of the "results" above is nan, then the actual 995 // On the other hand, if none of the "results" above is nan, then the actual
1007 // result cannot be nan either. 996 // result cannot be nan either.
1008 int nans = 0; 997 int nans = 0;
1009 for (int i = 0; i < 4; ++i) { 998 for (int i = 0; i < 4; ++i) {
1010 if (std::isnan(results[i])) ++nans; 999 if (std::isnan(results[i])) ++nans;
1011 } 1000 }
1012 if (nans == 4) return Type::NaN(); // [-inf..-inf] + [inf..inf] or vice versa 1001 if (nans == 4) return Type::NaN(); // [-inf..-inf] + [inf..inf] or vice versa
1013 Factory* f = t->isolate()->factory(); 1002 Type* range =
1014 Type* range = Type::Range(f->NewNumber(array_min(results, 4)), 1003 Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
1015 f->NewNumber(array_max(results, 4)), t->zone());
1016 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone()); 1004 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
1017 // Examples: 1005 // Examples:
1018 // [-inf, -inf] + [+inf, +inf] = NaN 1006 // [-inf, -inf] + [+inf, +inf] = NaN
1019 // [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN 1007 // [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN
1020 // [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN 1008 // [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN
1021 // [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN 1009 // [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN
1022 } 1010 }
1023 1011
1024 1012
1025 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { 1013 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
(...skipping 13 matching lines...) Expand all
1039 return JSAddRanger(lhs->AsRange(), rhs->AsRange(), t); 1027 return JSAddRanger(lhs->AsRange(), rhs->AsRange(), t);
1040 } 1028 }
1041 // TODO(neis): Deal with numeric bitsets here and elsewhere. 1029 // TODO(neis): Deal with numeric bitsets here and elsewhere.
1042 return Type::Number(); 1030 return Type::Number();
1043 } 1031 }
1044 1032
1045 1033
1046 Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs, 1034 Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs,
1047 Type::RangeType* rhs, Typer* t) { 1035 Type::RangeType* rhs, Typer* t) {
1048 double results[4]; 1036 double results[4];
1049 results[0] = lhs->Min()->Number() - rhs->Min()->Number(); 1037 results[0] = lhs->Min() - rhs->Min();
1050 results[1] = lhs->Min()->Number() - rhs->Max()->Number(); 1038 results[1] = lhs->Min() - rhs->Max();
1051 results[2] = lhs->Max()->Number() - rhs->Min()->Number(); 1039 results[2] = lhs->Max() - rhs->Min();
1052 results[3] = lhs->Max()->Number() - rhs->Max()->Number(); 1040 results[3] = lhs->Max() - rhs->Max();
1053 // Since none of the inputs can be -0, the result cannot be -0. 1041 // Since none of the inputs can be -0, the result cannot be -0.
1054 // However, it can be nan (the subtraction of two infinities of same sign). 1042 // However, it can be nan (the subtraction of two infinities of same sign).
1055 // On the other hand, if none of the "results" above is nan, then the actual 1043 // On the other hand, if none of the "results" above is nan, then the actual
1056 // result cannot be nan either. 1044 // result cannot be nan either.
1057 int nans = 0; 1045 int nans = 0;
1058 for (int i = 0; i < 4; ++i) { 1046 for (int i = 0; i < 4; ++i) {
1059 if (std::isnan(results[i])) ++nans; 1047 if (std::isnan(results[i])) ++nans;
1060 } 1048 }
1061 if (nans == 4) return Type::NaN(); // [inf..inf] - [inf..inf] (all same sign) 1049 if (nans == 4) return Type::NaN(); // [inf..inf] - [inf..inf] (all same sign)
1062 Factory* f = t->isolate()->factory(); 1050 Type* range =
1063 Type* range = Type::Range(f->NewNumber(array_min(results, 4)), 1051 Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
1064 f->NewNumber(array_max(results, 4)), t->zone());
1065 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone()); 1052 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
1066 // Examples: 1053 // Examples:
1067 // [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN 1054 // [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN
1068 // [-inf, -inf] - [-inf, -inf] = NaN 1055 // [-inf, -inf] - [-inf, -inf] = NaN
1069 // [-inf, -inf] - [n, +inf] = [-inf, -inf] \/ NaN 1056 // [-inf, -inf] - [n, +inf] = [-inf, -inf] \/ NaN
1070 // [m, +inf] - [-inf, n] = [-inf, +inf] \/ NaN 1057 // [m, +inf] - [-inf, n] = [-inf, +inf] \/ NaN
1071 } 1058 }
1072 1059
1073 1060
1074 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { 1061 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
1075 lhs = Rangify(ToNumber(lhs, t), t); 1062 lhs = Rangify(ToNumber(lhs, t), t);
1076 rhs = Rangify(ToNumber(rhs, t), t); 1063 rhs = Rangify(ToNumber(rhs, t), t);
1077 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 1064 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
1078 if (lhs->IsRange() && rhs->IsRange()) { 1065 if (lhs->IsRange() && rhs->IsRange()) {
1079 return JSSubtractRanger(lhs->AsRange(), rhs->AsRange(), t); 1066 return JSSubtractRanger(lhs->AsRange(), rhs->AsRange(), t);
1080 } 1067 }
1081 return Type::Number(); 1068 return Type::Number();
1082 } 1069 }
1083 1070
1084 1071
1085 Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs, 1072 Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs,
1086 Type::RangeType* rhs, Typer* t) { 1073 Type::RangeType* rhs, Typer* t) {
1087 double results[4]; 1074 double results[4];
1088 double lmin = lhs->Min()->Number(); 1075 double lmin = lhs->Min();
1089 double lmax = lhs->Max()->Number(); 1076 double lmax = lhs->Max();
1090 double rmin = rhs->Min()->Number(); 1077 double rmin = rhs->Min();
1091 double rmax = rhs->Max()->Number(); 1078 double rmax = rhs->Max();
1092 results[0] = lmin * rmin; 1079 results[0] = lmin * rmin;
1093 results[1] = lmin * rmax; 1080 results[1] = lmin * rmax;
1094 results[2] = lmax * rmin; 1081 results[2] = lmax * rmin;
1095 results[3] = lmax * rmax; 1082 results[3] = lmax * rmax;
1096 // If the result may be nan, we give up on calculating a precise type, because 1083 // If the result may be nan, we give up on calculating a precise type, because
1097 // the discontinuity makes it too complicated. Note that even if none of the 1084 // the discontinuity makes it too complicated. Note that even if none of the
1098 // "results" above is nan, the actual result may still be, so we have to do a 1085 // "results" above is nan, the actual result may still be, so we have to do a
1099 // different check: 1086 // different check:
1100 bool maybe_nan = (lhs->Maybe(t->singleton_zero) && 1087 bool maybe_nan = (lhs->Maybe(t->singleton_zero) &&
1101 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) || 1088 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
1102 (rhs->Maybe(t->singleton_zero) && 1089 (rhs->Maybe(t->singleton_zero) &&
1103 (lmin == -V8_INFINITY || lmax == +V8_INFINITY)); 1090 (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
1104 if (maybe_nan) return t->weakint; // Giving up. 1091 if (maybe_nan) return t->weakint; // Giving up.
1105 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) || 1092 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) ||
1106 (rhs->Maybe(t->singleton_zero) && lmin < 0); 1093 (rhs->Maybe(t->singleton_zero) && lmin < 0);
1107 Factory* f = t->isolate()->factory(); 1094 Type* range =
1108 Type* range = Type::Range(f->NewNumber(array_min(results, 4)), 1095 Type::Range(array_min(results, 4), array_max(results, 4), t->zone());
1109 f->NewNumber(array_max(results, 4)), t->zone());
1110 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone()) 1096 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
1111 : range; 1097 : range;
1112 } 1098 }
1113 1099
1114 1100
1115 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { 1101 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
1116 lhs = Rangify(ToNumber(lhs, t), t); 1102 lhs = Rangify(ToNumber(lhs, t), t);
1117 rhs = Rangify(ToNumber(rhs, t), t); 1103 rhs = Rangify(ToNumber(rhs, t), t);
1118 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 1104 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
1119 if (lhs->IsRange() && rhs->IsRange()) { 1105 if (lhs->IsRange() && rhs->IsRange()) {
(...skipping 12 matching lines...) Expand all
1132 bool maybe_nan = 1118 bool maybe_nan =
1133 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) || 1119 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
1134 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && 1120 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
1135 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); 1121 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
1136 return maybe_nan ? Type::Number() : Type::OrderedNumber(); 1122 return maybe_nan ? Type::Number() : Type::OrderedNumber();
1137 } 1123 }
1138 1124
1139 1125
1140 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs, 1126 Type* Typer::Visitor::JSModulusRanger(Type::RangeType* lhs,
1141 Type::RangeType* rhs, Typer* t) { 1127 Type::RangeType* rhs, Typer* t) {
1142 double lmin = lhs->Min()->Number(); 1128 double lmin = lhs->Min();
1143 double lmax = lhs->Max()->Number(); 1129 double lmax = lhs->Max();
1144 double rmin = rhs->Min()->Number(); 1130 double rmin = rhs->Min();
1145 double rmax = rhs->Max()->Number(); 1131 double rmax = rhs->Max();
1146 1132
1147 double labs = std::max(std::abs(lmin), std::abs(lmax)); 1133 double labs = std::max(std::abs(lmin), std::abs(lmax));
1148 double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1; 1134 double rabs = std::max(std::abs(rmin), std::abs(rmax)) - 1;
1149 double abs = std::min(labs, rabs); 1135 double abs = std::min(labs, rabs);
1150 bool maybe_minus_zero = false; 1136 bool maybe_minus_zero = false;
1151 double omin = 0; 1137 double omin = 0;
1152 double omax = 0; 1138 double omax = 0;
1153 if (lmin >= 0) { // {lhs} positive. 1139 if (lmin >= 0) { // {lhs} positive.
1154 omin = 0; 1140 omin = 0;
1155 omax = abs; 1141 omax = abs;
1156 } else if (lmax <= 0) { // {lhs} negative. 1142 } else if (lmax <= 0) { // {lhs} negative.
1157 omin = 0 - abs; 1143 omin = 0 - abs;
1158 omax = 0; 1144 omax = 0;
1159 maybe_minus_zero = true; 1145 maybe_minus_zero = true;
1160 } else { 1146 } else {
1161 omin = 0 - abs; 1147 omin = 0 - abs;
1162 omax = abs; 1148 omax = abs;
1163 maybe_minus_zero = true; 1149 maybe_minus_zero = true;
1164 } 1150 }
1165 1151
1166 Factory* f = t->isolate()->factory(); 1152 Type* result = Type::Range(omin, omax, t->zone());
1167 Type* result = Type::Range(f->NewNumber(omin), f->NewNumber(omax), t->zone());
1168 if (maybe_minus_zero) 1153 if (maybe_minus_zero)
1169 result = Type::Union(result, Type::MinusZero(), t->zone()); 1154 result = Type::Union(result, Type::MinusZero(), t->zone());
1170 return result; 1155 return result;
1171 } 1156 }
1172 1157
1173 1158
1174 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { 1159 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
1175 lhs = ToNumber(lhs, t); 1160 lhs = ToNumber(lhs, t);
1176 rhs = ToNumber(rhs, t); 1161 rhs = ToNumber(rhs, t);
1177 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 1162 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1280 Type* previous_number = 1265 Type* previous_number =
1281 Type::Intersect(previous_type, typer_->integer, zone()); 1266 Type::Intersect(previous_type, typer_->integer, zone());
1282 Type* current_number = Type::Intersect(current_type, typer_->integer, zone()); 1267 Type* current_number = Type::Intersect(current_type, typer_->integer, zone());
1283 if (!current_number->IsRange() || !previous_number->IsRange()) { 1268 if (!current_number->IsRange() || !previous_number->IsRange()) {
1284 return current_type; 1269 return current_type;
1285 } 1270 }
1286 1271
1287 Type::RangeType* previous = previous_number->AsRange(); 1272 Type::RangeType* previous = previous_number->AsRange();
1288 Type::RangeType* current = current_number->AsRange(); 1273 Type::RangeType* current = current_number->AsRange();
1289 1274
1290 double current_min = current->Min()->Number(); 1275 double current_min = current->Min();
1291 Handle<Object> new_min = current->Min(); 1276 double new_min = current_min;
1292
1293 // Find the closest lower entry in the list of allowed 1277 // Find the closest lower entry in the list of allowed
1294 // minima (or negative infinity if there is no such entry). 1278 // minima (or negative infinity if there is no such entry).
1295 if (current_min != previous->Min()->Number()) { 1279 if (current_min != previous->Min()) {
1296 new_min = typer_->integer->AsRange()->Min(); 1280 new_min = typer_->integer->AsRange()->Min();
1297 for (const auto val : typer_->weaken_min_limits_) { 1281 for (const auto val : typer_->weaken_min_limits_) {
1298 if (val->Number() <= current_min) { 1282 if (val <= current_min) {
1299 new_min = val; 1283 new_min = val;
1300 break; 1284 break;
1301 } 1285 }
1302 } 1286 }
1303 } 1287 }
1304 1288
1305 double current_max = current->Max()->Number(); 1289 double current_max = current->Max();
1306 Handle<Object> new_max = current->Max(); 1290 double new_max = current_max;
1307 // Find the closest greater entry in the list of allowed 1291 // Find the closest greater entry in the list of allowed
1308 // maxima (or infinity if there is no such entry). 1292 // maxima (or infinity if there is no such entry).
1309 if (current_max != previous->Max()->Number()) { 1293 if (current_max != previous->Max()) {
1310 new_max = typer_->integer->AsRange()->Max(); 1294 new_max = typer_->integer->AsRange()->Max();
1311 for (const auto val : typer_->weaken_max_limits_) { 1295 for (const auto val : typer_->weaken_max_limits_) {
1312 if (val->Number() >= current_max) { 1296 if (val >= current_max) {
1313 new_max = val; 1297 new_max = val;
1314 break; 1298 break;
1315 } 1299 }
1316 } 1300 }
1317 } 1301 }
1318 1302
1319 return Type::Union(current_type, 1303 return Type::Union(current_type,
1320 Type::Range(new_min, new_max, typer_->zone()), 1304 Type::Range(new_min, new_max, typer_->zone()),
1321 typer_->zone()); 1305 typer_->zone());
1322 } 1306 }
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after
2153 TYPED_ARRAYS(TYPED_ARRAY_CASE) 2137 TYPED_ARRAYS(TYPED_ARRAY_CASE)
2154 #undef TYPED_ARRAY_CASE 2138 #undef TYPED_ARRAY_CASE
2155 } 2139 }
2156 } 2140 }
2157 return Type::Constant(value, zone()); 2141 return Type::Constant(value, zone());
2158 } 2142 }
2159 2143
2160 } // namespace compiler 2144 } // namespace compiler
2161 } // namespace internal 2145 } // namespace internal
2162 } // namespace v8 2146 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/typer.h ('k') | src/types.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698