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

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

Issue 636283009: [turbofan] Use range types to type and lower arithmetic ops. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes and tweaks recommended by the reviewers Created 6 years, 2 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 | Annotate | Revision Log
« 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/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"
11 #include "src/compiler/simplified-operator.h" 11 #include "src/compiler/simplified-operator.h"
12 #include "src/compiler/typer.h" 12 #include "src/compiler/typer.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 namespace compiler { 16 namespace compiler {
17 17
18 class Typer::Decorator : public GraphDecorator { 18 class Typer::Decorator : public GraphDecorator {
19 public: 19 public:
20 explicit Decorator(Typer* typer) : typer_(typer) {} 20 explicit Decorator(Typer* typer) : typer_(typer) {}
21 virtual void Decorate(Node* node); 21 virtual void Decorate(Node* node);
22 22
23 private: 23 private:
24 Typer* typer_; 24 Typer* typer_;
25 }; 25 };
26 26
27 27
28 Typer::Typer(Graph* graph, MaybeHandle<Context> context) 28 Typer::Typer(Graph* graph, MaybeHandle<Context> context)
29 : graph_(graph), context_(context), decorator_(NULL) { 29 : graph_(graph),
30 context_(context),
31 decorator_(NULL),
32 weaken_min_limits_(graph->zone()),
33 weaken_max_limits_(graph->zone()) {
30 Zone* zone = this->zone(); 34 Zone* zone = this->zone();
31 Factory* f = zone->isolate()->factory(); 35 Factory* f = zone->isolate()->factory();
32 36
33 Handle<Object> zero = f->NewNumber(0); 37 Handle<Object> zero = f->NewNumber(0);
34 Handle<Object> one = f->NewNumber(1); 38 Handle<Object> one = f->NewNumber(1);
35 Handle<Object> positive_infinity = f->NewNumber(+V8_INFINITY); 39 Handle<Object> infinity = f->NewNumber(+V8_INFINITY);
36 Handle<Object> negative_infinity = f->NewNumber(-V8_INFINITY); 40 Handle<Object> minusinfinity = f->NewNumber(-V8_INFINITY);
37 41
38 negative_signed32 = Type::Union( 42 negative_signed32 = Type::Union(
39 Type::SignedSmall(), Type::OtherSigned32(), zone); 43 Type::SignedSmall(), Type::OtherSigned32(), zone);
40 non_negative_signed32 = Type::Union( 44 non_negative_signed32 = Type::Union(
41 Type::UnsignedSmall(), Type::OtherUnsigned31(), zone); 45 Type::UnsignedSmall(), Type::OtherUnsigned31(), zone);
42 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone); 46 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone);
43 singleton_false = Type::Constant(f->false_value(), zone); 47 singleton_false = Type::Constant(f->false_value(), zone);
44 singleton_true = Type::Constant(f->true_value(), zone); 48 singleton_true = Type::Constant(f->true_value(), zone);
45 singleton_zero = Type::Range(zero, zero, zone); 49 singleton_zero = Type::Range(zero, zero, zone);
46 singleton_one = Type::Range(one, one, zone); 50 singleton_one = Type::Range(one, one, zone);
47 zero_or_one = Type::Union(singleton_zero, singleton_one, zone); 51 zero_or_one = Type::Union(singleton_zero, singleton_one, zone);
48 zeroish = Type::Union( 52 zeroish = Type::Union(
49 singleton_zero, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone); 53 singleton_zero, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone);
50 falsish = Type::Union(Type::Undetectable(), 54 falsish = Type::Union(Type::Undetectable(),
51 Type::Union(zeroish, undefined_or_null, zone), zone); 55 Type::Union(zeroish, undefined_or_null, zone), zone);
52 integer = Type::Range(negative_infinity, positive_infinity, zone); 56 integer = Type::Range(minusinfinity, infinity, zone);
57 weakint = Type::Union(
58 integer, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone);
53 59
54 Type* number = Type::Number(); 60 Type* number = Type::Number();
55 Type* signed32 = Type::Signed32(); 61 Type* signed32 = Type::Signed32();
56 Type* unsigned32 = Type::Unsigned32(); 62 Type* unsigned32 = Type::Unsigned32();
57 Type* integral32 = Type::Integral32(); 63 Type* integral32 = Type::Integral32();
58 Type* object = Type::Object(); 64 Type* object = Type::Object();
59 Type* undefined = Type::Undefined(); 65 Type* undefined = Type::Undefined();
60 Type* weakint = Type::Union(
61 integer, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone);
62 66
63 number_fun0_ = Type::Function(number, zone); 67 number_fun0_ = Type::Function(number, zone);
64 number_fun1_ = Type::Function(number, number, zone); 68 number_fun1_ = Type::Function(number, number, zone);
65 number_fun2_ = Type::Function(number, number, number, zone); 69 number_fun2_ = Type::Function(number, number, number, zone);
66 weakint_fun1_ = Type::Function(weakint, number, zone); 70 weakint_fun1_ = Type::Function(weakint, number, zone);
67 imul_fun_ = Type::Function(signed32, integral32, integral32, zone); 71 imul_fun_ = Type::Function(signed32, integral32, integral32, zone);
68 clz32_fun_ = Type::Function( 72 clz32_fun_ = Type::Function(
69 Type::Range(zero, f->NewNumber(32), zone), number, zone); 73 Type::Range(zero, f->NewNumber(32), zone), number, zone);
70 random_fun_ = Type::Function(Type::Union( 74 random_fun_ = Type::Function(Type::Union(
71 Type::UnsignedSmall(), Type::OtherNumber(), zone), zone); 75 Type::UnsignedSmall(), Type::OtherNumber(), zone), zone);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 array_buffer_fun_ = Type::Function(buffer, unsigned32, zone); 110 array_buffer_fun_ = Type::Function(buffer, unsigned32, zone);
107 int8_array_fun_ = Type::Function(int8_array, arg1, arg2, arg3, zone); 111 int8_array_fun_ = Type::Function(int8_array, arg1, arg2, arg3, zone);
108 int16_array_fun_ = Type::Function(int16_array, arg1, arg2, arg3, zone); 112 int16_array_fun_ = Type::Function(int16_array, arg1, arg2, arg3, zone);
109 int32_array_fun_ = Type::Function(int32_array, arg1, arg2, arg3, zone); 113 int32_array_fun_ = Type::Function(int32_array, arg1, arg2, arg3, zone);
110 uint8_array_fun_ = Type::Function(uint8_array, arg1, arg2, arg3, zone); 114 uint8_array_fun_ = Type::Function(uint8_array, arg1, arg2, arg3, zone);
111 uint16_array_fun_ = Type::Function(uint16_array, arg1, arg2, arg3, zone); 115 uint16_array_fun_ = Type::Function(uint16_array, arg1, arg2, arg3, zone);
112 uint32_array_fun_ = Type::Function(uint32_array, arg1, arg2, arg3, zone); 116 uint32_array_fun_ = Type::Function(uint32_array, arg1, arg2, arg3, zone);
113 float32_array_fun_ = Type::Function(float32_array, arg1, arg2, arg3, zone); 117 float32_array_fun_ = Type::Function(float32_array, arg1, arg2, arg3, zone);
114 float64_array_fun_ = Type::Function(float64_array, arg1, arg2, arg3, zone); 118 float64_array_fun_ = Type::Function(float64_array, arg1, arg2, arg3, zone);
115 119
120 const int limits_count = 20;
121
122 weaken_min_limits_.reserve(limits_count + 1);
123 weaken_max_limits_.reserve(limits_count + 1);
124
125 double limit = 1 << 30;
126 weaken_min_limits_.push_back(f->NewNumber(0));
127 weaken_max_limits_.push_back(f->NewNumber(0));
128 for (int i = 0; i < limits_count; i++) {
129 weaken_min_limits_.push_back(f->NewNumber(-limit));
130 weaken_max_limits_.push_back(f->NewNumber(limit - 1));
131 limit *= 2;
132 }
133
116 decorator_ = new (zone) Decorator(this); 134 decorator_ = new (zone) Decorator(this);
117 graph_->AddDecorator(decorator_); 135 graph_->AddDecorator(decorator_);
118 } 136 }
119 137
120 138
121 Typer::~Typer() { 139 Typer::~Typer() {
122 graph_->RemoveDecorator(decorator_); 140 graph_->RemoveDecorator(decorator_);
123 } 141 }
124 142
125 143
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 176
159 Type* TypeConstant(Handle<Object> value); 177 Type* TypeConstant(Handle<Object> value);
160 178
161 protected: 179 protected:
162 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node); 180 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node);
163 DECLARE_METHOD(Start) 181 DECLARE_METHOD(Start)
164 VALUE_OP_LIST(DECLARE_METHOD) 182 VALUE_OP_LIST(DECLARE_METHOD)
165 #undef DECLARE_METHOD 183 #undef DECLARE_METHOD
166 184
167 Bounds BoundsOrNone(Node* node) { 185 Bounds BoundsOrNone(Node* node) {
168 return NodeProperties::IsTyped(node) 186 return NodeProperties::IsTyped(node) ? NodeProperties::GetBounds(node)
169 ? NodeProperties::GetBounds(node) : Bounds(Type::None(zone())); 187 : Bounds(Type::None());
170 } 188 }
171 189
172 Bounds Operand(Node* node, int i) { 190 Bounds Operand(Node* node, int i) {
173 Node* operand_node = NodeProperties::GetValueInput(node, i); 191 Node* operand_node = NodeProperties::GetValueInput(node, i);
174 return BoundsOrNone(operand_node); 192 return BoundsOrNone(operand_node);
175 } 193 }
176 194
177 Bounds ContextOperand(Node* node) { 195 Bounds ContextOperand(Node* node) {
178 Bounds result = BoundsOrNone(NodeProperties::GetContextInput(node)); 196 Bounds result = BoundsOrNone(NodeProperties::GetContextInput(node));
179 DCHECK(result.upper->Maybe(Type::Internal())); 197 DCHECK(result.upper->Maybe(Type::Internal()));
180 // TODO(rossberg): More precisely, instead of the above assertion, we should 198 // TODO(rossberg): More precisely, instead of the above assertion, we should
181 // back-propagate the constraint that it has to be a subtype of Internal. 199 // back-propagate the constraint that it has to be a subtype of Internal.
182 return result; 200 return result;
183 } 201 }
184 202
203 Type* MaybeWeaken(Type* current, Type* previous);
204
185 Zone* zone() { return typer_->zone(); } 205 Zone* zone() { return typer_->zone(); }
186 Isolate* isolate() { return typer_->isolate(); } 206 Isolate* isolate() { return typer_->isolate(); }
187 Graph* graph() { return typer_->graph(); } 207 Graph* graph() { return typer_->graph(); }
188 MaybeHandle<Context> context() { return typer_->context(); } 208 MaybeHandle<Context> context() { return typer_->context(); }
189 209
190 private: 210 private:
191 Typer* typer_; 211 Typer* typer_;
192 MaybeHandle<Context> context_; 212 MaybeHandle<Context> context_;
193 213
194 typedef Type* (*UnaryTyperFun)(Type*, Typer* t); 214 typedef Type* (*UnaryTyperFun)(Type*, Typer* t);
195 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t); 215 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t);
196 216
197 Bounds TypeUnaryOp(Node* node, UnaryTyperFun); 217 Bounds TypeUnaryOp(Node* node, UnaryTyperFun);
198 Bounds TypeBinaryOp(Node* node, BinaryTyperFun); 218 Bounds TypeBinaryOp(Node* node, BinaryTyperFun);
199 219
220 Type* Weaken(Type::RangeType* previous, Type::RangeType* current);
221
200 static Type* Invert(Type*, Typer*); 222 static Type* Invert(Type*, Typer*);
201 static Type* FalsifyUndefined(Type*, Typer*); 223 static Type* FalsifyUndefined(Type*, Typer*);
224 static Type* Rangify(Type*, Typer*);
202 225
203 static Type* ToPrimitive(Type*, Typer*); 226 static Type* ToPrimitive(Type*, Typer*);
204 static Type* ToBoolean(Type*, Typer*); 227 static Type* ToBoolean(Type*, Typer*);
205 static Type* ToNumber(Type*, Typer*); 228 static Type* ToNumber(Type*, Typer*);
206 static Type* ToString(Type*, Typer*); 229 static Type* ToString(Type*, Typer*);
207 static Type* NumberToInt32(Type*, Typer*); 230 static Type* NumberToInt32(Type*, Typer*);
208 static Type* NumberToUint32(Type*, Typer*); 231 static Type* NumberToUint32(Type*, Typer*);
209 232
210 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*); 233 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*);
211 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*); 234 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 }; 268 };
246 269
247 270
248 class Typer::NarrowVisitor : public Typer::Visitor { 271 class Typer::NarrowVisitor : public Typer::Visitor {
249 public: 272 public:
250 explicit NarrowVisitor(Typer* typer) : Visitor(typer) {} 273 explicit NarrowVisitor(Typer* typer) : Visitor(typer) {}
251 274
252 GenericGraphVisit::Control Pre(Node* node) { 275 GenericGraphVisit::Control Pre(Node* node) {
253 if (OperatorProperties::HasValueOutput(node->op())) { 276 if (OperatorProperties::HasValueOutput(node->op())) {
254 Bounds previous = NodeProperties::GetBounds(node); 277 Bounds previous = NodeProperties::GetBounds(node);
255 Bounds bounds = TypeNode(node); 278 Bounds current = TypeNode(node);
256 NodeProperties::SetBounds(node, Bounds::Both(bounds, previous, zone())); 279 NodeProperties::SetBounds(node, Bounds::Both(current, previous, zone()));
257 DCHECK(bounds.Narrows(previous)); 280 DCHECK(current.Narrows(previous));
258 // Stop when nothing changed (but allow re-entry in case it does later). 281 // Stop when nothing changed (but allow re-entry in case it does later).
259 return previous.Narrows(bounds) 282 return previous.Narrows(current) ? GenericGraphVisit::DEFER
260 ? GenericGraphVisit::DEFER : GenericGraphVisit::REENTER; 283 : GenericGraphVisit::REENTER;
261 } else { 284 } else {
262 return GenericGraphVisit::SKIP; 285 return GenericGraphVisit::SKIP;
263 } 286 }
264 } 287 }
265 288
266 GenericGraphVisit::Control Post(Node* node) { 289 GenericGraphVisit::Control Post(Node* node) {
267 return GenericGraphVisit::REENTER; 290 return GenericGraphVisit::REENTER;
268 } 291 }
269 }; 292 };
270 293
271 294
272 class Typer::WidenVisitor : public Typer::Visitor { 295 class Typer::WidenVisitor : public Typer::Visitor {
273 public: 296 public:
274 explicit WidenVisitor(Typer* typer) : Visitor(typer) {} 297 explicit WidenVisitor(Typer* typer) : Visitor(typer) {}
275 298
276 GenericGraphVisit::Control Pre(Node* node) { 299 GenericGraphVisit::Control Pre(Node* node) {
277 if (OperatorProperties::HasValueOutput(node->op())) { 300 if (OperatorProperties::HasValueOutput(node->op())) {
278 Bounds previous = BoundsOrNone(node); 301 Bounds previous = BoundsOrNone(node);
279 Bounds bounds = TypeNode(node); 302 Bounds current = TypeNode(node);
280 DCHECK(previous.lower->Is(bounds.lower)); 303
281 DCHECK(previous.upper->Is(bounds.upper)); 304 // Speed up termination in the presence of range types:
282 NodeProperties::SetBounds(node, bounds); 305 current.upper = MaybeWeaken(current.upper, previous.upper);
306 current.lower = MaybeWeaken(current.lower, previous.lower);
307
308 DCHECK(previous.lower->Is(current.lower));
309 DCHECK(previous.upper->Is(current.upper));
310
311 NodeProperties::SetBounds(node, current);
283 // Stop when nothing changed (but allow re-entry in case it does later). 312 // Stop when nothing changed (but allow re-entry in case it does later).
284 return bounds.Narrows(previous) 313 return previous.Narrows(current) && current.Narrows(previous)
285 ? GenericGraphVisit::DEFER : GenericGraphVisit::REENTER; 314 ? GenericGraphVisit::DEFER
315 : GenericGraphVisit::REENTER;
286 } else { 316 } else {
287 return GenericGraphVisit::SKIP; 317 return GenericGraphVisit::SKIP;
288 } 318 }
289 } 319 }
290 320
291 GenericGraphVisit::Control Post(Node* node) { 321 GenericGraphVisit::Control Post(Node* node) {
292 return GenericGraphVisit::REENTER; 322 return GenericGraphVisit::REENTER;
293 } 323 }
294 }; 324 };
295 325
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 return type; 404 return type;
375 } 405 }
376 406
377 407
378 Type* Typer::Visitor::FalsifyUndefined(Type* type, Typer* t) { 408 Type* Typer::Visitor::FalsifyUndefined(Type* type, Typer* t) {
379 if (type->Is(Type::Undefined())) return t->singleton_false; 409 if (type->Is(Type::Undefined())) return t->singleton_false;
380 return type; 410 return type;
381 } 411 }
382 412
383 413
414 Type* Typer::Visitor::Rangify(Type* type, Typer* t) {
415 if (type->IsRange()) return type; // Shortcut.
416 if (!type->Is(t->integer)) return type; // Give up.
417 Factory* f = t->isolate()->factory();
418 return Type::Range(f->NewNumber(type->Min()), f->NewNumber(type->Max()),
419 t->zone());
420 }
421
422
384 // Type conversion. 423 // Type conversion.
385 424
386 425
387 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) { 426 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) {
388 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) { 427 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
389 return type; 428 return type;
390 } 429 }
391 return Type::Primitive(); 430 return Type::Primitive();
392 } 431 }
393 432
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
448 487
449 // Common operators. 488 // Common operators.
450 489
451 490
452 Bounds Typer::Visitor::TypeParameter(Node* node) { 491 Bounds Typer::Visitor::TypeParameter(Node* node) {
453 return Bounds::Unbounded(zone()); 492 return Bounds::Unbounded(zone());
454 } 493 }
455 494
456 495
457 Bounds Typer::Visitor::TypeInt32Constant(Node* node) { 496 Bounds Typer::Visitor::TypeInt32Constant(Node* node) {
458 Factory* f = zone()->isolate()->factory(); 497 Factory* f = isolate()->factory();
459 Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node)); 498 Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node));
460 return Bounds(Type::Intersect( 499 return Bounds(Type::Intersect(
461 Type::Range(number, number, zone()), Type::UntaggedInt32(), zone())); 500 Type::Range(number, number, zone()), Type::UntaggedInt32(), zone()));
462 } 501 }
463 502
464 503
465 Bounds Typer::Visitor::TypeInt64Constant(Node* node) { 504 Bounds Typer::Visitor::TypeInt64Constant(Node* node) {
466 return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type? 505 return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type?
467 } 506 }
468 507
469 508
470 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) { 509 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) {
471 return Bounds(Type::Intersect( 510 return Bounds(Type::Intersect(
472 Type::Of(OpParameter<float>(node), zone()), 511 Type::Of(OpParameter<float>(node), zone()),
473 Type::UntaggedFloat32(), zone())); 512 Type::UntaggedFloat32(), zone()));
474 } 513 }
475 514
476 515
477 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) { 516 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) {
478 return Bounds(Type::Intersect( 517 return Bounds(Type::Intersect(
479 Type::Of(OpParameter<double>(node), zone()), 518 Type::Of(OpParameter<double>(node), zone()),
480 Type::UntaggedFloat64(), zone())); 519 Type::UntaggedFloat64(), zone()));
481 } 520 }
482 521
483 522
484 Bounds Typer::Visitor::TypeNumberConstant(Node* node) { 523 Bounds Typer::Visitor::TypeNumberConstant(Node* node) {
485 Factory* f = zone()->isolate()->factory(); 524 Factory* f = isolate()->factory();
486 return Bounds(Type::Constant( 525 return Bounds(Type::Constant(
487 f->NewNumber(OpParameter<double>(node)), zone())); 526 f->NewNumber(OpParameter<double>(node)), zone()));
488 } 527 }
489 528
490 529
491 Bounds Typer::Visitor::TypeHeapConstant(Node* node) { 530 Bounds Typer::Visitor::TypeHeapConstant(Node* node) {
492 return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle())); 531 return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle()));
493 } 532 }
494 533
495 534
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after
652 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( 691 Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
653 Type* lhs, Type* rhs, Typer* t) { 692 Type* lhs, Type* rhs, Typer* t) {
654 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); 693 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
655 } 694 }
656 695
657 696
658 // JS bitwise operators. 697 // JS bitwise operators.
659 698
660 699
661 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { 700 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
662 Factory* f = t->zone()->isolate()->factory(); 701 Factory* f = t->isolate()->factory();
663 lhs = NumberToInt32(ToNumber(lhs, t), t); 702 lhs = NumberToInt32(ToNumber(lhs, t), t);
664 rhs = NumberToInt32(ToNumber(rhs, t), t); 703 rhs = NumberToInt32(ToNumber(rhs, t), t);
665 double lmin = lhs->Min(); 704 double lmin = lhs->Min();
666 double rmin = rhs->Min(); 705 double rmin = rhs->Min();
667 double lmax = lhs->Max(); 706 double lmax = lhs->Max();
668 double rmax = rhs->Max(); 707 double rmax = rhs->Max();
669 // Or-ing any two values results in a value no smaller than their minimum. 708 // Or-ing any two values results in a value no smaller than their minimum.
670 // Even no smaller than their maximum if both values are non-negative. 709 // Even no smaller than their maximum if both values are non-negative.
671 Handle<Object> min = f->NewNumber( 710 Handle<Object> min = f->NewNumber(
672 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin)); 711 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin));
673 if (lmax < 0 || rmax < 0) { 712 if (lmax < 0 || rmax < 0) {
674 // Or-ing two values of which at least one is negative results in a negative 713 // Or-ing two values of which at least one is negative results in a negative
675 // value. 714 // value.
676 Handle<Object> max = f->NewNumber(-1); 715 Handle<Object> max = f->NewNumber(-1);
677 return Type::Range(min, max, t->zone()); 716 return Type::Range(min, max, t->zone());
678 } 717 }
679 Handle<Object> max = f->NewNumber(Type::Signed32()->Max()); 718 Handle<Object> max = f->NewNumber(Type::Signed32()->Max());
680 return Type::Range(min, max, t->zone()); 719 return Type::Range(min, max, t->zone());
681 // TODO(neis): Be precise for singleton inputs, here and elsewhere. 720 // TODO(neis): Be precise for singleton inputs, here and elsewhere.
682 } 721 }
683 722
684 723
685 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { 724 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
686 Factory* f = t->zone()->isolate()->factory(); 725 Factory* f = t->isolate()->factory();
687 lhs = NumberToInt32(ToNumber(lhs, t), t); 726 lhs = NumberToInt32(ToNumber(lhs, t), t);
688 rhs = NumberToInt32(ToNumber(rhs, t), t); 727 rhs = NumberToInt32(ToNumber(rhs, t), t);
689 double lmin = lhs->Min(); 728 double lmin = lhs->Min();
690 double rmin = rhs->Min(); 729 double rmin = rhs->Min();
691 double lmax = lhs->Max(); 730 double lmax = lhs->Max();
692 double rmax = rhs->Max(); 731 double rmax = rhs->Max();
693 // And-ing any two values results in a value no larger than their maximum. 732 // And-ing any two values results in a value no larger than their maximum.
694 // Even no larger than their minimum if both values are non-negative. 733 // Even no larger than their minimum if both values are non-negative.
695 Handle<Object> max = f->NewNumber( 734 Handle<Object> max = f->NewNumber(
696 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax)); 735 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax));
(...skipping 27 matching lines...) Expand all
724 } 763 }
725 764
726 765
727 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { 766 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
728 return Type::Signed32(); 767 return Type::Signed32();
729 } 768 }
730 769
731 770
732 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { 771 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
733 lhs = NumberToInt32(ToNumber(lhs, t), t); 772 lhs = NumberToInt32(ToNumber(lhs, t), t);
734 Factory* f = t->zone()->isolate()->factory(); 773 Factory* f = t->isolate()->factory();
735 if (lhs->Min() >= 0) { 774 if (lhs->Min() >= 0) {
736 // Right-shifting a non-negative value cannot make it negative, nor larger. 775 // Right-shifting a non-negative value cannot make it negative, nor larger.
737 Handle<Object> min = f->NewNumber(0); 776 Handle<Object> min = f->NewNumber(0);
738 Handle<Object> max = f->NewNumber(lhs->Max()); 777 Handle<Object> max = f->NewNumber(lhs->Max());
739 return Type::Range(min, max, t->zone()); 778 return Type::Range(min, max, t->zone());
740 } 779 }
741 if (lhs->Max() < 0) { 780 if (lhs->Max() < 0) {
742 // Right-shifting a negative value cannot make it non-negative, nor smaller. 781 // Right-shifting a negative value cannot make it non-negative, nor smaller.
743 Handle<Object> min = f->NewNumber(lhs->Min()); 782 Handle<Object> min = f->NewNumber(lhs->Min());
744 Handle<Object> max = f->NewNumber(-1); 783 Handle<Object> max = f->NewNumber(-1);
745 return Type::Range(min, max, t->zone()); 784 return Type::Range(min, max, t->zone());
746 } 785 }
747 return Type::Signed32(); 786 return Type::Signed32();
748 } 787 }
749 788
750 789
751 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { 790 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
752 lhs = NumberToUint32(ToNumber(lhs, t), t); 791 lhs = NumberToUint32(ToNumber(lhs, t), t);
753 Factory* f = t->zone()->isolate()->factory(); 792 Factory* f = t->isolate()->factory();
754 // Logical right-shifting any value cannot make it larger. 793 // Logical right-shifting any value cannot make it larger.
755 Handle<Object> min = f->NewNumber(0); 794 Handle<Object> min = f->NewNumber(0);
756 Handle<Object> max = f->NewNumber(lhs->Max()); 795 Handle<Object> max = f->NewNumber(lhs->Max());
757 return Type::Range(min, max, t->zone()); 796 return Type::Range(min, max, t->zone());
758 } 797 }
759 798
760 799
761 // JS arithmetic operators. 800 // JS arithmetic operators.
762 801
763 802
803 // Returns the array's least element, ignoring NaN.
804 // There must be at least one non-NaN element.
805 // Any -0 is converted to 0.
806 static double array_min(double a[], size_t n) {
807 DCHECK(n != 0);
808 double x = +V8_INFINITY;
809 for (size_t i = 0; i < n; ++i) {
810 if (!std::isnan(a[i])) {
811 x = std::min(a[i], x);
812 }
813 }
814 DCHECK(!std::isnan(x));
815 return x == 0 ? 0 : x; // -0 -> 0
816 }
817
818
819 // Returns the array's greatest element, ignoring NaN.
820 // There must be at least one non-NaN element.
821 // Any -0 is converted to 0.
822 static double array_max(double a[], size_t n) {
823 DCHECK(n != 0);
824 double x = -V8_INFINITY;
825 for (size_t i = 0; i < n; ++i) {
826 if (!std::isnan(a[i])) {
827 x = std::max(a[i], x);
828 }
829 }
830 DCHECK(!std::isnan(x));
831 return x == 0 ? 0 : x; // -0 -> 0
832 }
833
834
835 Type* Typer::Visitor::JSAddRanger(Type::RangeType* lhs, Type::RangeType* rhs,
836 Typer* t) {
837 double results[4];
838 results[0] = lhs->Min()->Number() + rhs->Min()->Number();
839 results[1] = lhs->Min()->Number() + rhs->Max()->Number();
840 results[2] = lhs->Max()->Number() + rhs->Min()->Number();
841 results[3] = lhs->Max()->Number() + rhs->Max()->Number();
842 // Since none of the inputs can be -0, the result cannot be -0 either.
843 // However, it can be nan (the sum of two infinities of opposite sign).
844 // On the other hand, if none of the "results" above is nan, then the actual
845 // result cannot be nan either.
846 int nans = 0;
847 for (int i = 0; i < 4; ++i) {
848 if (std::isnan(results[i])) ++nans;
849 }
850 if (nans == 4) return Type::NaN(); // [-inf..-inf] + [inf..inf] or vice versa
851 Factory* f = t->isolate()->factory();
852 Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
853 f->NewNumber(array_max(results, 4)), t->zone());
854 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
855 // Examples:
856 // [-inf, -inf] + [+inf, +inf] = NaN
857 // [-inf, -inf] + [n, +inf] = [-inf, -inf] \/ NaN
858 // [-inf, +inf] + [n, +inf] = [-inf, +inf] \/ NaN
859 // [-inf, m] + [n, +inf] = [-inf, +inf] \/ NaN
860 }
861
862
764 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { 863 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
765 lhs = ToPrimitive(lhs, t); 864 lhs = ToPrimitive(lhs, t);
766 rhs = ToPrimitive(rhs, t); 865 rhs = ToPrimitive(rhs, t);
767 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { 866 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
768 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { 867 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
769 return Type::String(); 868 return Type::String();
770 } else { 869 } else {
771 return Type::NumberOrString(); 870 return Type::NumberOrString();
772 } 871 }
773 } 872 }
774 lhs = ToNumber(lhs, t); 873 lhs = Rangify(ToNumber(lhs, t), t);
775 rhs = ToNumber(rhs, t); 874 rhs = Rangify(ToNumber(rhs, t), t);
776 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 875 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
777 // TODO(neis): Do some analysis. 876 if (lhs->IsRange() && rhs->IsRange()) {
877 return JSAddRanger(lhs->AsRange(), rhs->AsRange(), t);
878 }
778 // TODO(neis): Deal with numeric bitsets here and elsewhere. 879 // TODO(neis): Deal with numeric bitsets here and elsewhere.
779 return Type::Number(); 880 return Type::Number();
780 } 881 }
781 882
782 883
884 Type* Typer::Visitor::JSSubtractRanger(Type::RangeType* lhs,
885 Type::RangeType* rhs, Typer* t) {
886 double results[4];
887 results[0] = lhs->Min()->Number() - rhs->Min()->Number();
888 results[1] = lhs->Min()->Number() - rhs->Max()->Number();
889 results[2] = lhs->Max()->Number() - rhs->Min()->Number();
890 results[3] = lhs->Max()->Number() - rhs->Max()->Number();
891 // Since none of the inputs can be -0, the result cannot be -0.
892 // However, it can be nan (the subtraction of two infinities of same sign).
893 // On the other hand, if none of the "results" above is nan, then the actual
894 // result cannot be nan either.
895 int nans = 0;
896 for (int i = 0; i < 4; ++i) {
897 if (std::isnan(results[i])) ++nans;
898 }
899 if (nans == 4) return Type::NaN(); // [inf..inf] - [inf..inf] (all same sign)
900 Factory* f = t->isolate()->factory();
901 Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
902 f->NewNumber(array_max(results, 4)), t->zone());
903 return nans == 0 ? range : Type::Union(range, Type::NaN(), t->zone());
904 // Examples:
905 // [-inf, +inf] - [-inf, +inf] = [-inf, +inf] \/ NaN
906 // [-inf, -inf] - [-inf, -inf] = NaN
907 // [-inf, -inf] - [n, +inf] = [-inf, -inf] \/ NaN
908 // [m, +inf] - [-inf, n] = [-inf, +inf] \/ NaN
909 }
910
911
783 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { 912 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
784 lhs = ToNumber(lhs, t); 913 lhs = Rangify(ToNumber(lhs, t), t);
785 rhs = ToNumber(rhs, t); 914 rhs = Rangify(ToNumber(rhs, t), t);
786 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 915 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
787 // TODO(neis): Do some analysis. 916 if (lhs->IsRange() && rhs->IsRange()) {
917 return JSSubtractRanger(lhs->AsRange(), rhs->AsRange(), t);
918 }
788 return Type::Number(); 919 return Type::Number();
789 } 920 }
790 921
791 922
923 Type* Typer::Visitor::JSMultiplyRanger(Type::RangeType* lhs,
924 Type::RangeType* rhs, Typer* t) {
925 double results[4];
926 double lmin = lhs->Min()->Number();
927 double lmax = lhs->Max()->Number();
928 double rmin = rhs->Min()->Number();
929 double rmax = rhs->Max()->Number();
930 results[0] = lmin * rmin;
931 results[1] = lmin * rmax;
932 results[2] = lmax * rmin;
933 results[3] = lmax * rmax;
934 // If the result may be nan, we give up on calculating a precise type, because
935 // the discontinuity makes it too complicated. Note that even if none of the
936 // "results" above is nan, the actual result may still be, so we have to do a
937 // different check:
938 bool maybe_nan = (lhs->Maybe(t->singleton_zero) &&
939 (rmin == -V8_INFINITY || rmax == +V8_INFINITY)) ||
940 (rhs->Maybe(t->singleton_zero) &&
941 (lmin == -V8_INFINITY || lmax == +V8_INFINITY));
942 if (maybe_nan) return t->weakint; // Giving up.
943 bool maybe_minuszero = (lhs->Maybe(t->singleton_zero) && rmin < 0) ||
944 (rhs->Maybe(t->singleton_zero) && lmin < 0);
945 Factory* f = t->isolate()->factory();
946 Type* range = Type::Range(f->NewNumber(array_min(results, 4)),
947 f->NewNumber(array_max(results, 4)), t->zone());
948 return maybe_minuszero ? Type::Union(range, Type::MinusZero(), t->zone())
949 : range;
950 }
951
952
792 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { 953 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
793 lhs = ToNumber(lhs, t); 954 lhs = Rangify(ToNumber(lhs, t), t);
794 rhs = ToNumber(rhs, t); 955 rhs = Rangify(ToNumber(rhs, t), t);
795 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 956 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
796 // TODO(neis): Do some analysis. 957 if (lhs->IsRange() && rhs->IsRange()) {
958 return JSMultiplyRanger(lhs->AsRange(), rhs->AsRange(), t);
959 }
797 return Type::Number(); 960 return Type::Number();
798 } 961 }
799 962
800 963
801 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { 964 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
802 lhs = ToNumber(lhs, t); 965 lhs = ToNumber(lhs, t);
803 rhs = ToNumber(rhs, t); 966 rhs = ToNumber(rhs, t);
804 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 967 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
805 // TODO(neis): Do some analysis. 968 // Division is tricky, so all we do is try ruling out nan.
806 return Type::Number(); 969 // TODO(neis): try ruling out -0 as well?
970 bool maybe_nan =
971 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
972 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
973 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
974 return maybe_nan ? Type::Number() : Type::OrderedNumber();
807 } 975 }
808 976
809 977
810 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { 978 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
811 lhs = ToNumber(lhs, t); 979 lhs = ToNumber(lhs, t);
812 rhs = ToNumber(rhs, t); 980 rhs = ToNumber(rhs, t);
813 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); 981 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
814 // TODO(neis): Do some analysis. 982 // Division is tricky, so all we do is try ruling out nan.
815 return Type::Number(); 983 // TODO(neis): try ruling out -0 as well?
984 bool maybe_nan =
985 lhs->Maybe(Type::NaN()) || rhs->Maybe(t->zeroish) ||
986 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) &&
987 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY));
988 return maybe_nan ? Type::Number() : Type::OrderedNumber();
816 } 989 }
817 990
818 991
819 // JS unary operators. 992 // JS unary operators.
820 993
821 994
822 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) { 995 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) {
823 return Invert(ToBoolean(type, t), t); 996 return Invert(ToBoolean(type, t), t);
824 } 997 }
825 998
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
883 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) { 1056 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) {
884 return TypeBinaryOp(node, JSLoadPropertyTyper); 1057 return TypeBinaryOp(node, JSLoadPropertyTyper);
885 } 1058 }
886 1059
887 1060
888 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { 1061 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) {
889 return Bounds::Unbounded(zone()); 1062 return Bounds::Unbounded(zone());
890 } 1063 }
891 1064
892 1065
1066 Type* Typer::Visitor::MaybeWeaken(Type* current, Type* previous) {
rossberg 2014/10/23 13:44:27 Is there any reason left not to merge the Weaken f
Jarin 2014/10/23 13:54:59 Done.
1067 if (current->IsRange() && previous->IsRange()) {
1068 return Weaken(previous->AsRange(), current->AsRange());
1069 }
1070 return current;
1071 }
1072
1073
1074 // Returns a somewhat larger range. This is used to speed up
1075 // the fixpoint calculation in case there appears to be a loop
1076 // in the graph. In the current implementation, we are
1077 // increasing the limits to the closest power of two.
1078 Type* Typer::Visitor::Weaken(Type::RangeType* previous,
1079 Type::RangeType* current) {
1080 double current_min = current->Min()->Number();
1081 double current_max = current->Max()->Number();
1082
1083 Handle<Object> new_min = current->Min();
1084 Handle<Object> new_max = current->Max();
1085
1086 // Find the closest lower entry in the list of allowed
1087 // minima (or negative infinity if there is no such entry).
1088 if (current_min != previous->Min()->Number()) {
1089 new_min = typer_->integer->AsRange()->Min();
1090 for (const auto val : typer_->weaken_min_limits_) {
1091 if (val->Number() <= current_min) {
1092 new_min = val;
1093 break;
1094 }
1095 }
1096 }
1097
1098 // Find the closest greater entry in the list of allowed
1099 // maxima (or infinity if there is no such entry).
1100 if (current_max != previous->Max()->Number()) {
1101 new_max = typer_->integer->AsRange()->Max();
1102 for (const auto val : typer_->weaken_max_limits_) {
1103 if (val->Number() >= current_max) {
1104 new_max = val;
1105 break;
1106 }
1107 }
1108 }
1109
1110 return Type::Range(new_min, new_max, typer_->zone());
1111 }
1112
1113
893 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) { 1114 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) {
894 UNREACHABLE(); 1115 UNREACHABLE();
895 return Bounds(); 1116 return Bounds();
896 } 1117 }
897 1118
898 1119
899 Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) { 1120 Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) {
900 UNREACHABLE(); 1121 UNREACHABLE();
901 return Bounds(); 1122 return Bounds();
902 } 1123 }
(...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after
1635 return typer_->float64_array_fun_; 1856 return typer_->float64_array_fun_;
1636 } 1857 }
1637 } 1858 }
1638 } 1859 }
1639 return Type::Constant(value, zone()); 1860 return Type::Constant(value, zone());
1640 } 1861 }
1641 1862
1642 } 1863 }
1643 } 1864 }
1644 } // namespace v8::internal::compiler 1865 } // namespace v8::internal::compiler
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