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

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

Issue 653693002: Reland "Refine expression typing, esp. by propagating range information." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: The actual changes since reverting. 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/compiler/graph-inl.h" 5 #include "src/compiler/graph-inl.h"
6 #include "src/compiler/js-operator.h" 6 #include "src/compiler/js-operator.h"
7 #include "src/compiler/node.h" 7 #include "src/compiler/node.h"
8 #include "src/compiler/node-properties-inl.h" 8 #include "src/compiler/node-properties-inl.h"
9 #include "src/compiler/node-properties.h" 9 #include "src/compiler/node-properties.h"
10 #include "src/compiler/simplified-operator.h" 10 #include "src/compiler/simplified-operator.h"
11 #include "src/compiler/typer.h" 11 #include "src/compiler/typer.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 namespace compiler { 15 namespace compiler {
16 16
17 Typer::Typer(Zone* zone) : zone_(zone) { 17 Typer::Typer(Zone* zone) : zone_(zone) {
18 Factory* f = zone->isolate()->factory(); 18 Factory* f = zone->isolate()->factory();
19 19
20 Handle<Object> zero = f->NewNumber(0);
21 Handle<Object> one = f->NewNumber(1);
22 Handle<Object> positive_infinity = f->NewNumber(+V8_INFINITY);
23 Handle<Object> negative_infinity = f->NewNumber(-V8_INFINITY);
24
25 negative_signed32 = Type::Union(
26 Type::SignedSmall(), Type::OtherSigned32(), zone);
27 non_negative_signed32 = Type::Union(
28 Type::UnsignedSmall(), Type::OtherUnsigned31(), zone);
29 undefined_or_null = Type::Union(Type::Undefined(), Type::Null(), zone);
30 singleton_false = Type::Constant(f->false_value(), zone);
31 singleton_true = Type::Constant(f->true_value(), zone);
32 singleton_zero = Type::Range(zero, zero, zone);
33 singleton_one = Type::Range(one, one, zone);
34 zero_or_one = Type::Union(singleton_zero, singleton_one, zone);
35 zeroish = Type::Union(
36 singleton_zero, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone);
37 falsish = Type::Union(Type::Undetectable(),
38 Type::Union(zeroish, undefined_or_null, zone), zone);
39 integer = Type::Range(negative_infinity, positive_infinity, zone);
40
20 Type* number = Type::Number(); 41 Type* number = Type::Number();
21 Type* signed32 = Type::Signed32(); 42 Type* signed32 = Type::Signed32();
22 Type* unsigned32 = Type::Unsigned32(); 43 Type* unsigned32 = Type::Unsigned32();
23 Type* integral32 = Type::Integral32(); 44 Type* integral32 = Type::Integral32();
24 Type* object = Type::Object(); 45 Type* object = Type::Object();
25 Type* undefined = Type::Undefined(); 46 Type* undefined = Type::Undefined();
26 Type* weakint = Type::Union( 47 Type* weakint = Type::Union(
27 Type::Range(f->NewNumber(-V8_INFINITY), f->NewNumber(+V8_INFINITY), zone), 48 integer, Type::Union(Type::NaN(), Type::MinusZero(), zone), zone);
28 Type::Union(Type::NaN(), Type::MinusZero(), zone), zone);
29 49
30 number_fun0_ = Type::Function(number, zone); 50 number_fun0_ = Type::Function(number, zone);
31 number_fun1_ = Type::Function(number, number, zone); 51 number_fun1_ = Type::Function(number, number, zone);
32 number_fun2_ = Type::Function(number, number, number, zone); 52 number_fun2_ = Type::Function(number, number, number, zone);
33 weakint_fun1_ = Type::Function(weakint, number, zone); 53 weakint_fun1_ = Type::Function(weakint, number, zone);
34 imul_fun_ = Type::Function(signed32, integral32, integral32, zone); 54 imul_fun_ = Type::Function(signed32, integral32, integral32, zone);
35 random_fun_ = Type::Function(Type::Union( 55 random_fun_ = Type::Function(Type::Union(
36 Type::UnsignedSmall(), Type::OtherNumber(), zone), zone); 56 Type::UnsignedSmall(), Type::OtherNumber(), zone), zone);
37 57
58 Type* int8 = Type::Intersect(
59 Type::Range(f->NewNumber(-0x7F), f->NewNumber(0x7F-1), zone),
60 Type::UntaggedInt8(), zone);
61 Type* int16 = Type::Intersect(
62 Type::Range(f->NewNumber(-0x7FFF), f->NewNumber(0x7FFF-1), zone),
63 Type::UntaggedInt16(), zone);
64 Type* uint8 = Type::Intersect(
65 Type::Range(zero, f->NewNumber(0xFF-1), zone),
66 Type::UntaggedInt8(), zone);
67 Type* uint16 = Type::Intersect(
68 Type::Range(zero, f->NewNumber(0xFFFF-1), zone),
69 Type::UntaggedInt16(), zone);
38 70
39 #define NATIVE_TYPE(sem, rep) \ 71 #define NATIVE_TYPE(sem, rep) \
40 Type::Intersect(Type::sem(zone), Type::rep(zone), zone) 72 Type::Intersect(Type::sem(), Type::rep(), zone)
41 // TODO(rossberg): Use range types for more precision, once we have them.
42 Type* int8 = NATIVE_TYPE(SignedSmall, UntaggedInt8);
43 Type* int16 = NATIVE_TYPE(SignedSmall, UntaggedInt16);
44 Type* int32 = NATIVE_TYPE(Signed32, UntaggedInt32); 73 Type* int32 = NATIVE_TYPE(Signed32, UntaggedInt32);
45 Type* uint8 = NATIVE_TYPE(UnsignedSmall, UntaggedInt8);
46 Type* uint16 = NATIVE_TYPE(UnsignedSmall, UntaggedInt16);
47 Type* uint32 = NATIVE_TYPE(Unsigned32, UntaggedInt32); 74 Type* uint32 = NATIVE_TYPE(Unsigned32, UntaggedInt32);
48 Type* float32 = NATIVE_TYPE(Number, UntaggedFloat32); 75 Type* float32 = NATIVE_TYPE(Number, UntaggedFloat32);
49 Type* float64 = NATIVE_TYPE(Number, UntaggedFloat64); 76 Type* float64 = NATIVE_TYPE(Number, UntaggedFloat64);
50 #undef NATIVE_TYPE 77 #undef NATIVE_TYPE
78
51 Type* buffer = Type::Buffer(zone); 79 Type* buffer = Type::Buffer(zone);
52 Type* int8_array = Type::Array(int8, zone); 80 Type* int8_array = Type::Array(int8, zone);
53 Type* int16_array = Type::Array(int16, zone); 81 Type* int16_array = Type::Array(int16, zone);
54 Type* int32_array = Type::Array(int32, zone); 82 Type* int32_array = Type::Array(int32, zone);
55 Type* uint8_array = Type::Array(uint8, zone); 83 Type* uint8_array = Type::Array(uint8, zone);
56 Type* uint16_array = Type::Array(uint16, zone); 84 Type* uint16_array = Type::Array(uint16, zone);
57 Type* uint32_array = Type::Array(uint32, zone); 85 Type* uint32_array = Type::Array(uint32, zone);
58 Type* float32_array = Type::Array(float32, zone); 86 Type* float32_array = Type::Array(float32, zone);
59 Type* float64_array = Type::Array(float64, zone); 87 Type* float64_array = Type::Array(float64, zone);
60 Type* arg1 = Type::Union(unsigned32, object, zone); 88 Type* arg1 = Type::Union(unsigned32, object, zone);
(...skipping 11 matching lines...) Expand all
72 } 100 }
73 101
74 102
75 class Typer::Visitor : public NullNodeVisitor { 103 class Typer::Visitor : public NullNodeVisitor {
76 public: 104 public:
77 Visitor(Typer* typer, MaybeHandle<Context> context) 105 Visitor(Typer* typer, MaybeHandle<Context> context)
78 : typer_(typer), context_(context) {} 106 : typer_(typer), context_(context) {}
79 107
80 Bounds TypeNode(Node* node) { 108 Bounds TypeNode(Node* node) {
81 switch (node->opcode()) { 109 switch (node->opcode()) {
110 #define DECLARE_CASE(x) \
111 case IrOpcode::k##x: return TypeBinaryOp(node, x##Typer);
112 JS_SIMPLE_BINOP_LIST(DECLARE_CASE)
113 #undef DECLARE_CASE
114
82 #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node); 115 #define DECLARE_CASE(x) case IrOpcode::k##x: return Type##x(node);
83 DECLARE_CASE(Start) 116 DECLARE_CASE(Start)
84 VALUE_OP_LIST(DECLARE_CASE) 117 // VALUE_OP_LIST without JS_SIMPLE_BINOP_LIST:
118 COMMON_OP_LIST(DECLARE_CASE)
119 SIMPLIFIED_OP_LIST(DECLARE_CASE)
120 MACHINE_OP_LIST(DECLARE_CASE)
121 JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
122 JS_OBJECT_OP_LIST(DECLARE_CASE)
123 JS_CONTEXT_OP_LIST(DECLARE_CASE)
124 JS_OTHER_OP_LIST(DECLARE_CASE)
85 #undef DECLARE_CASE 125 #undef DECLARE_CASE
86 126
87 #define DECLARE_CASE(x) case IrOpcode::k##x: 127 #define DECLARE_CASE(x) case IrOpcode::k##x:
88 DECLARE_CASE(End) 128 DECLARE_CASE(End)
89 INNER_CONTROL_OP_LIST(DECLARE_CASE) 129 INNER_CONTROL_OP_LIST(DECLARE_CASE)
90 #undef DECLARE_CASE 130 #undef DECLARE_CASE
91 break; 131 break;
92 } 132 }
93 UNREACHABLE(); 133 UNREACHABLE();
94 return Bounds(); 134 return Bounds();
95 } 135 }
96 136
97 Type* TypeConstant(Handle<Object> value); 137 Type* TypeConstant(Handle<Object> value);
98 138
99 protected: 139 protected:
100 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node); 140 #define DECLARE_METHOD(x) inline Bounds Type##x(Node* node);
101 DECLARE_METHOD(Start) 141 DECLARE_METHOD(Start)
102 VALUE_OP_LIST(DECLARE_METHOD) 142 VALUE_OP_LIST(DECLARE_METHOD)
103 #undef DECLARE_METHOD 143 #undef DECLARE_METHOD
104 144
105 Bounds OperandType(Node* node, int i) { 145 static Bounds OperandType(Node* node, int i) {
106 return NodeProperties::GetBounds(NodeProperties::GetValueInput(node, i)); 146 return NodeProperties::GetBounds(NodeProperties::GetValueInput(node, i));
107 } 147 }
108 148
109 Type* ContextType(Node* node) { 149 static Type* ContextType(Node* node) {
110 Bounds result = 150 Bounds result =
111 NodeProperties::GetBounds(NodeProperties::GetContextInput(node)); 151 NodeProperties::GetBounds(NodeProperties::GetContextInput(node));
112 DCHECK(result.upper->Maybe(Type::Internal())); 152 DCHECK(result.upper->Maybe(Type::Internal()));
113 // TODO(rossberg): More precisely, instead of the above assertion, we should 153 // TODO(rossberg): More precisely, instead of the above assertion, we should
114 // back-propagate the constraint that it has to be a subtype of Internal. 154 // back-propagate the constraint that it has to be a subtype of Internal.
115 return result.upper; 155 return result.upper;
116 } 156 }
117 157
118 Zone* zone() { return typer_->zone(); } 158 Zone* zone() { return typer_->zone(); }
119 Isolate* isolate() { return typer_->isolate(); } 159 Isolate* isolate() { return typer_->isolate(); }
120 MaybeHandle<Context> context() { return context_; } 160 MaybeHandle<Context> context() { return context_; }
121 161
122 private: 162 private:
123 Typer* typer_; 163 Typer* typer_;
124 MaybeHandle<Context> context_; 164 MaybeHandle<Context> context_;
165
166 typedef Type* (*UnaryTyperFun)(Type*, Typer* t);
167 typedef Type* (*BinaryTyperFun)(Type*, Type*, Typer* t);
168
169 Bounds TypeUnaryOp(Node* node, UnaryTyperFun);
170 Bounds TypeBinaryOp(Node* node, BinaryTyperFun);
171
172 static Type* Invert(Type*, Typer*);
173 static Type* FalsifyUndefined(Type*, Typer*);
174
175 static Type* ToPrimitive(Type*, Typer*);
176 static Type* ToBoolean(Type*, Typer*);
177 static Type* ToNumber(Type*, Typer*);
178 static Type* ToString(Type*, Typer*);
179 static Type* NumberToInt32(Type*, Typer*);
180 static Type* NumberToUint32(Type*, Typer*);
181
182 static Type* JSAddRanger(Type::RangeType*, Type::RangeType*, Typer*);
183 static Type* JSSubtractRanger(Type::RangeType*, Type::RangeType*, Typer*);
184 static Type* JSMultiplyRanger(Type::RangeType*, Type::RangeType*, Typer*);
185 static Type* JSDivideRanger(Type::RangeType*, Type::RangeType*, Typer*);
186
187 static Type* JSCompareTyper(Type*, Type*, Typer*);
188
189 #define DECLARE_METHOD(x) static Type* x##Typer(Type*, Type*, Typer*);
190 JS_SIMPLE_BINOP_LIST(DECLARE_METHOD)
191 #undef DECLARE_METHOD
192
193 static Type* JSUnaryNotTyper(Type*, Typer*);
194 static Type* JSLoadPropertyTyper(Type*, Type*, Typer*);
195 static Type* JSCallFunctionTyper(Type*, Typer*);
125 }; 196 };
126 197
127 198
128 class Typer::RunVisitor : public Typer::Visitor { 199 class Typer::RunVisitor : public Typer::Visitor {
129 public: 200 public:
130 RunVisitor(Typer* typer, MaybeHandle<Context> context) 201 RunVisitor(Typer* typer, MaybeHandle<Context> context)
131 : Visitor(typer, context), 202 : Visitor(typer, context),
132 redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {} 203 redo(NodeSet::key_compare(), NodeSet::allocator_type(typer->zone())) {}
133 204
134 GenericGraphVisit::Control Post(Node* node) { 205 GenericGraphVisit::Control Post(Node* node) {
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 if (OperatorProperties::HasValueOutput(node->op())) { 301 if (OperatorProperties::HasValueOutput(node->op())) {
231 Visitor typing(this, MaybeHandle<Context>()); 302 Visitor typing(this, MaybeHandle<Context>());
232 Bounds bounds = typing.TypeNode(node); 303 Bounds bounds = typing.TypeNode(node);
233 NodeProperties::SetBounds(node, bounds); 304 NodeProperties::SetBounds(node, bounds);
234 } 305 }
235 } 306 }
236 307
237 308
238 // ----------------------------------------------------------------------------- 309 // -----------------------------------------------------------------------------
239 310
311 // Helper functions that lift a function f on types to a function on bounds,
312 // and uses that to type the given node. Note that f is never called with None
313 // as an argument.
314
315
316 Bounds Typer::Visitor::TypeUnaryOp(Node* node, UnaryTyperFun f) {
317 Bounds input = OperandType(node, 0);
318 Type* upper = input.upper->Is(Type::None())
319 ? Type::None()
320 : f(input.upper, typer_);
321 Type* lower = input.lower->Is(Type::None())
322 ? Type::None()
323 : (input.lower == input.upper || upper->IsConstant())
324 ? upper // TODO(neis): Extend this to Range(x,x), NaN, MinusZero, ...?
325 : f(input.lower, typer_);
326 // TODO(neis): Figure out what to do with lower bound.
327 return Bounds(lower, upper);
328 }
329
330
331 Bounds Typer::Visitor::TypeBinaryOp(Node* node, BinaryTyperFun f) {
332 Bounds left = OperandType(node, 0);
333 Bounds right = OperandType(node, 1);
334 Type* upper = left.upper->Is(Type::None()) || right.upper->Is(Type::None())
335 ? Type::None()
336 : f(left.upper, right.upper, typer_);
337 Type* lower = left.lower->Is(Type::None()) || right.lower->Is(Type::None())
338 ? Type::None()
339 : ((left.lower == left.upper && right.lower == right.upper) ||
340 upper->IsConstant())
341 ? upper
342 : f(left.lower, right.lower, typer_);
343 // TODO(neis): Figure out what to do with lower bound.
344 return Bounds(lower, upper);
345 }
346
347
348 Type* Typer::Visitor::Invert(Type* type, Typer* t) {
349 if (type->Is(t->singleton_false)) return t->singleton_true;
350 if (type->Is(t->singleton_true)) return t->singleton_false;
351 return type;
352 }
353
354
355 Type* Typer::Visitor::FalsifyUndefined(Type* type, Typer* t) {
356 if (type->Is(Type::Undefined())) return t->singleton_false;
357 return type;
358 }
359
360
361 // Type conversion.
362
363
364 Type* Typer::Visitor::ToPrimitive(Type* type, Typer* t) {
365 if (type->Is(Type::Primitive()) && !type->Maybe(Type::Receiver())) {
366 return type;
367 }
368 return Type::Primitive();
369 }
370
371
372 Type* Typer::Visitor::ToBoolean(Type* type, Typer* t) {
373 if (type->Is(Type::Boolean())) return type;
374 if (type->Is(t->falsish)) return t->singleton_false;
375 if (type->Is(Type::DetectableReceiver())) return t->singleton_true;
376 if (type->Is(Type::OrderedNumber()) && (type->Max() < 0 || 0 < type->Min())) {
377 return t->singleton_true; // Ruled out nan, -0 and +0.
378 }
379 return Type::Boolean();
380 }
381
382
383 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) {
384 if (type->Is(Type::Number())) return type;
385 if (type->Is(Type::Undefined())) return Type::NaN();
386 if (type->Is(t->singleton_false)) return t->singleton_zero;
387 if (type->Is(t->singleton_true)) return t->singleton_one;
388 if (type->Is(Type::Boolean())) return t->zero_or_one;
389 return Type::Number();
390 }
391
392
393 Type* Typer::Visitor::ToString(Type* type, Typer* t) {
394 if (type->Is(Type::String())) return type;
395 return Type::String();
396 }
397
398
399 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
400 // TODO(neis): DCHECK(type->Is(Type::Number()));
401 if (type->Is(Type::Signed32())) return type;
402 if (type->Is(t->zeroish)) return t->singleton_zero;
403 return Type::Signed32();
404 }
405
406
407 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
408 // TODO(neis): DCHECK(type->Is(Type::Number()));
409 if (type->Is(Type::Unsigned32())) return type;
410 if (type->Is(t->zeroish)) return t->singleton_zero;
411 return Type::Unsigned32();
412 }
413
414
415 // -----------------------------------------------------------------------------
416
240 417
241 // Control operators. 418 // Control operators.
242 419
420
243 Bounds Typer::Visitor::TypeStart(Node* node) { 421 Bounds Typer::Visitor::TypeStart(Node* node) {
244 return Bounds(Type::Internal(zone())); 422 return Bounds(Type::Internal());
245 } 423 }
246 424
247 425
248 // Common operators. 426 // Common operators.
249 427
428
250 Bounds Typer::Visitor::TypeParameter(Node* node) { 429 Bounds Typer::Visitor::TypeParameter(Node* node) {
251 return Bounds::Unbounded(zone()); 430 return Bounds::Unbounded(zone());
252 } 431 }
253 432
254 433
255 Bounds Typer::Visitor::TypeInt32Constant(Node* node) { 434 Bounds Typer::Visitor::TypeInt32Constant(Node* node) {
256 // TODO(titzer): only call Type::Of() if the type is not already known. 435 Factory* f = zone()->isolate()->factory();
257 return Bounds(Type::Of(OpParameter<int32_t>(node), zone())); 436 Handle<Object> number = f->NewNumber(OpParameter<int32_t>(node));
437 return Bounds(Type::Intersect(
438 Type::Range(number, number, zone()), Type::UntaggedInt32(), zone()));
258 } 439 }
259 440
260 441
261 Bounds Typer::Visitor::TypeInt64Constant(Node* node) { 442 Bounds Typer::Visitor::TypeInt64Constant(Node* node) {
262 // TODO(titzer): only call Type::Of() if the type is not already known. 443 return Bounds(Type::Internal()); // TODO(rossberg): Add int64 bitset type?
263 return Bounds(
264 Type::Of(static_cast<double>(OpParameter<int64_t>(node)), zone()));
265 } 444 }
266 445
267 446
268 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) { 447 Bounds Typer::Visitor::TypeFloat32Constant(Node* node) {
269 // TODO(titzer): only call Type::Of() if the type is not already known. 448 return Bounds(Type::Intersect(
270 return Bounds(Type::Of(OpParameter<float>(node), zone())); 449 Type::Of(OpParameter<float>(node), zone()),
450 Type::UntaggedFloat32(), zone()));
271 } 451 }
272 452
273 453
274 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) { 454 Bounds Typer::Visitor::TypeFloat64Constant(Node* node) {
275 // TODO(titzer): only call Type::Of() if the type is not already known. 455 return Bounds(Type::Intersect(
276 return Bounds(Type::Of(OpParameter<double>(node), zone())); 456 Type::Of(OpParameter<double>(node), zone()),
457 Type::UntaggedFloat64(), zone()));
277 } 458 }
278 459
279 460
280 Bounds Typer::Visitor::TypeNumberConstant(Node* node) { 461 Bounds Typer::Visitor::TypeNumberConstant(Node* node) {
281 // TODO(titzer): only call Type::Of() if the type is not already known. 462 Factory* f = zone()->isolate()->factory();
282 return Bounds(Type::Of(OpParameter<double>(node), zone())); 463 return Bounds(Type::Constant(
464 f->NewNumber(OpParameter<double>(node)), zone()));
283 } 465 }
284 466
285 467
286 Bounds Typer::Visitor::TypeHeapConstant(Node* node) { 468 Bounds Typer::Visitor::TypeHeapConstant(Node* node) {
287 return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle())); 469 return Bounds(TypeConstant(OpParameter<Unique<Object> >(node).handle()));
288 } 470 }
289 471
290 472
291 Bounds Typer::Visitor::TypeExternalConstant(Node* node) { 473 Bounds Typer::Visitor::TypeExternalConstant(Node* node) {
292 return Bounds(Type::Internal(zone())); 474 return Bounds(Type::Internal());
293 } 475 }
294 476
295 477
296 Bounds Typer::Visitor::TypePhi(Node* node) { 478 Bounds Typer::Visitor::TypePhi(Node* node) {
297 int arity = OperatorProperties::GetValueInputCount(node->op()); 479 int arity = OperatorProperties::GetValueInputCount(node->op());
298 Bounds bounds = OperandType(node, 0); 480 Bounds bounds = OperandType(node, 0);
299 for (int i = 1; i < arity; ++i) { 481 for (int i = 1; i < arity; ++i) {
300 bounds = Bounds::Either(bounds, OperandType(node, i), zone()); 482 bounds = Bounds::Either(bounds, OperandType(node, i), zone());
301 } 483 }
302 return bounds; 484 return bounds;
(...skipping 12 matching lines...) Expand all
315 } 497 }
316 498
317 499
318 Bounds Typer::Visitor::TypeFinish(Node* node) { 500 Bounds Typer::Visitor::TypeFinish(Node* node) {
319 return OperandType(node, 0); 501 return OperandType(node, 0);
320 } 502 }
321 503
322 504
323 Bounds Typer::Visitor::TypeFrameState(Node* node) { 505 Bounds Typer::Visitor::TypeFrameState(Node* node) {
324 // TODO(rossberg): Ideally FrameState wouldn't have a value output. 506 // TODO(rossberg): Ideally FrameState wouldn't have a value output.
325 return Bounds(Type::Internal(zone())); 507 return Bounds(Type::Internal());
326 } 508 }
327 509
328 510
329 Bounds Typer::Visitor::TypeStateValues(Node* node) { 511 Bounds Typer::Visitor::TypeStateValues(Node* node) {
330 return Bounds(Type::Internal(zone())); 512 return Bounds(Type::Internal());
331 } 513 }
332 514
333 515
334 Bounds Typer::Visitor::TypeCall(Node* node) { 516 Bounds Typer::Visitor::TypeCall(Node* node) {
335 return Bounds::Unbounded(zone()); 517 return Bounds::Unbounded(zone());
336 } 518 }
337 519
338 520
339 Bounds Typer::Visitor::TypeProjection(Node* node) { 521 Bounds Typer::Visitor::TypeProjection(Node* node) {
340 // TODO(titzer): use the output type of the input to determine the bounds. 522 // TODO(titzer): use the output type of the input to determine the bounds.
341 return Bounds::Unbounded(zone()); 523 return Bounds::Unbounded(zone());
342 } 524 }
343 525
344 526
345 // JS comparison operators. 527 // JS comparison operators.
346 528
347 #define DEFINE_METHOD(x) \ 529
348 Bounds Typer::Visitor::Type##x(Node* node) { \ 530 Type* Typer::Visitor::JSEqualTyper(Type* lhs, Type* rhs, Typer* t) {
349 return Bounds(Type::Boolean(zone())); \ 531 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false;
350 } 532 if (lhs->Is(t->undefined_or_null) && rhs->Is(t->undefined_or_null)) {
351 JS_COMPARE_BINOP_LIST(DEFINE_METHOD) 533 return t->singleton_true;
352 #undef DEFINE_METHOD 534 }
535 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
536 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
537 return t->singleton_false;
538 }
539 if (lhs->IsConstant() && rhs->Is(lhs)) {
540 // Types are equal and are inhabited only by a single semantic value,
541 // which is not nan due to the earlier check.
542 // TODO(neis): Extend this to Range(x,x), MinusZero, ...?
543 return t->singleton_true;
544 }
545 return Type::Boolean();
546 }
547
548
549 Type* Typer::Visitor::JSNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
550 return Invert(JSEqualTyper(lhs, rhs, t), t);
551 }
552
553
554 static Type* JSType(Type* type) {
555 if (type->Is(Type::Boolean())) return Type::Boolean();
556 if (type->Is(Type::String())) return Type::String();
557 if (type->Is(Type::Number())) return Type::Number();
558 if (type->Is(Type::Undefined())) return Type::Undefined();
559 if (type->Is(Type::Null())) return Type::Null();
560 if (type->Is(Type::Symbol())) return Type::Symbol();
561 if (type->Is(Type::Receiver())) return Type::Receiver(); // JS "Object"
562 return Type::Any();
563 }
564
565
566 Type* Typer::Visitor::JSStrictEqualTyper(Type* lhs, Type* rhs, Typer* t) {
567 if (!JSType(lhs)->Maybe(JSType(rhs))) return t->singleton_false;
568 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return t->singleton_false;
569 if (lhs->Is(Type::Number()) && rhs->Is(Type::Number()) &&
570 (lhs->Max() < rhs->Min() || lhs->Min() > rhs->Max())) {
571 return t->singleton_false;
572 }
573 if (lhs->IsConstant() && rhs->Is(lhs)) {
574 // Types are equal and are inhabited only by a single semantic value,
575 // which is not nan due to the earlier check.
576 return t->singleton_true;
577 }
578 return Type::Boolean();
579 }
580
581
582 Type* Typer::Visitor::JSStrictNotEqualTyper(Type* lhs, Type* rhs, Typer* t) {
583 return Invert(JSStrictEqualTyper(lhs, rhs, t), t);
584 }
585
586
587 // The EcmaScript specification defines the four relational comparison operators
588 // (<, <=, >=, >) with the help of a single abstract one. It behaves like <
589 // but returns undefined when the inputs cannot be compared.
590 // We implement the typing analogously.
591 Type* Typer::Visitor::JSCompareTyper(Type* lhs, Type* rhs, Typer* t) {
592 lhs = ToPrimitive(lhs, t);
593 rhs = ToPrimitive(rhs, t);
594 if (lhs->Maybe(Type::String()) && rhs->Maybe(Type::String())) {
595 return Type::Boolean();
596 }
597 lhs = ToNumber(lhs, t);
598 rhs = ToNumber(rhs, t);
599 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::Undefined();
600 if (lhs->IsConstant() && rhs->Is(lhs)) {
601 // Types are equal and are inhabited only by a single semantic value,
602 // which is not NaN due to the previous check.
603 return t->singleton_false;
604 }
605 if (lhs->Min() >= rhs->Max()) return t->singleton_false;
606 if (lhs->Max() < rhs->Min() &&
607 !lhs->Maybe(Type::NaN()) && !rhs->Maybe(Type::NaN())) {
608 return t->singleton_true;
609 }
610 return Type::Boolean();
611 }
612
613
614 Type* Typer::Visitor::JSLessThanTyper(Type* lhs, Type* rhs, Typer* t) {
615 return FalsifyUndefined(JSCompareTyper(lhs, rhs, t), t);
616 }
617
618
619 Type* Typer::Visitor::JSGreaterThanTyper(Type* lhs, Type* rhs, Typer* t) {
620 return FalsifyUndefined(JSCompareTyper(rhs, lhs, t), t);
621 }
622
623
624 Type* Typer::Visitor::JSLessThanOrEqualTyper(Type* lhs, Type* rhs, Typer* t) {
625 return FalsifyUndefined(Invert(JSCompareTyper(rhs, lhs, t), t), t);
626 }
627
628
629 Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
630 Type* lhs, Type* rhs, Typer* t) {
631 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
632 }
353 633
354 634
355 // JS bitwise operators. 635 // JS bitwise operators.
356 636
357 Bounds Typer::Visitor::TypeJSBitwiseOr(Node* node) { 637
358 Bounds left = OperandType(node, 0); 638 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
359 Bounds right = OperandType(node, 1); 639 Factory* f = t->zone()->isolate()->factory();
360 Type* upper = Type::Union(left.upper, right.upper, zone()); 640 lhs = NumberToInt32(ToNumber(lhs, t), t);
361 if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone()); 641 rhs = NumberToInt32(ToNumber(rhs, t), t);
362 Type* lower = Type::Intersect(Type::SignedSmall(zone()), upper, zone()); 642 double lmin = lhs->Min();
363 return Bounds(lower, upper); 643 double rmin = rhs->Min();
364 } 644 double lmax = lhs->Max();
365 645 double rmax = rhs->Max();
366 646 // Or-ing any two values results in a value no smaller than their minimum.
367 Bounds Typer::Visitor::TypeJSBitwiseAnd(Node* node) { 647 // Even no smaller than their maximum if both values are non-negative.
368 Bounds left = OperandType(node, 0); 648 Handle<Object> min = f->NewNumber(
369 Bounds right = OperandType(node, 1); 649 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin));
370 Type* upper = Type::Union(left.upper, right.upper, zone()); 650 if (lmax < 0 || rmax < 0) {
371 if (!upper->Is(Type::Signed32())) upper = Type::Signed32(zone()); 651 // Or-ing two values of which at least one is negative results in a negative
372 Type* lower = Type::Intersect(Type::SignedSmall(zone()), upper, zone()); 652 // value.
373 return Bounds(lower, upper); 653 Handle<Object> max = f->NewNumber(-1);
374 } 654 return Type::Range(min, max, t->zone());
375 655 }
376 656 Handle<Object> max = f->NewNumber(Type::Signed32()->Max());
377 Bounds Typer::Visitor::TypeJSBitwiseXor(Node* node) { 657 return Type::Range(min, max, t->zone());
378 return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone())); 658 // TODO(neis): Be precise for singleton inputs, here and elsewhere.
379 } 659 }
380 660
381 661
382 Bounds Typer::Visitor::TypeJSShiftLeft(Node* node) { 662 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
383 return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone())); 663 Factory* f = t->zone()->isolate()->factory();
384 } 664 lhs = NumberToInt32(ToNumber(lhs, t), t);
385 665 rhs = NumberToInt32(ToNumber(rhs, t), t);
386 666 double lmin = lhs->Min();
387 Bounds Typer::Visitor::TypeJSShiftRight(Node* node) { 667 double rmin = rhs->Min();
388 return Bounds(Type::SignedSmall(zone()), Type::Signed32(zone())); 668 double lmax = lhs->Max();
389 } 669 double rmax = rhs->Max();
390 670 // And-ing any two values results in a value no larger than their maximum.
391 671 // Even no larger than their minimum if both values are non-negative.
392 Bounds Typer::Visitor::TypeJSShiftRightLogical(Node* node) { 672 Handle<Object> max = f->NewNumber(
393 return Bounds(Type::UnsignedSmall(zone()), Type::Unsigned32(zone())); 673 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax));
674 if (lmin >= 0 || rmin >= 0) {
675 // And-ing two values of which at least one is non-negative results in a
676 // non-negative value.
677 Handle<Object> min = f->NewNumber(0);
678 return Type::Range(min, max, t->zone());
679 }
680 Handle<Object> min = f->NewNumber(Type::Signed32()->Min());
681 return Type::Range(min, max, t->zone());
682 }
683
684
685 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) {
686 lhs = NumberToInt32(ToNumber(lhs, t), t);
687 rhs = NumberToInt32(ToNumber(rhs, t), t);
688 double lmin = lhs->Min();
689 double rmin = rhs->Min();
690 double lmax = lhs->Max();
691 double rmax = rhs->Max();
692 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) {
693 // Xor-ing negative or non-negative values results in a non-negative value.
694 return t->non_negative_signed32;
695 }
696 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) {
697 // Xor-ing a negative and a non-negative value results in a negative value.
698 return t->negative_signed32;
699 }
700 return Type::Signed32();
701 }
702
703
704 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
705 return Type::Signed32();
706 }
707
708
709 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
710 lhs = NumberToInt32(ToNumber(lhs, t), t);
711 Factory* f = t->zone()->isolate()->factory();
712 if (lhs->Min() >= 0) {
713 // Right-shifting a non-negative value cannot make it negative, nor larger.
714 Handle<Object> min = f->NewNumber(0);
715 Handle<Object> max = f->NewNumber(lhs->Max());
716 return Type::Range(min, max, t->zone());
717 }
718 if (lhs->Max() < 0) {
719 // Right-shifting a negative value cannot make it non-negative, nor smaller.
720 Handle<Object> min = f->NewNumber(lhs->Min());
721 Handle<Object> max = f->NewNumber(-1);
722 return Type::Range(min, max, t->zone());
723 }
724 return Type::Signed32();
725 }
726
727
728 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
729 lhs = NumberToUint32(ToNumber(lhs, t), t);
730 Factory* f = t->zone()->isolate()->factory();
731 // Logical right-shifting any value cannot make it larger.
732 Handle<Object> min = f->NewNumber(0);
733 Handle<Object> max = f->NewNumber(lhs->Max());
734 return Type::Range(min, max, t->zone());
394 } 735 }
395 736
396 737
397 // JS arithmetic operators. 738 // JS arithmetic operators.
398 739
399 Bounds Typer::Visitor::TypeJSAdd(Node* node) { 740
400 Bounds left = OperandType(node, 0); 741 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
401 Bounds right = OperandType(node, 1); 742 lhs = ToPrimitive(lhs, t);
402 Type* lower = 743 rhs = ToPrimitive(rhs, t);
403 left.lower->Is(Type::None()) || right.lower->Is(Type::None()) ? 744 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
404 Type::None(zone()) : 745 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
405 left.lower->Is(Type::Number()) && right.lower->Is(Type::Number()) ? 746 return Type::String();
406 Type::SignedSmall(zone()) : 747 } else {
407 left.lower->Is(Type::String()) || right.lower->Is(Type::String()) ? 748 return Type::NumberOrString();
408 Type::String(zone()) : Type::None(zone()); 749 }
409 Type* upper = 750 }
410 left.upper->Is(Type::None()) && right.upper->Is(Type::None()) ? 751 lhs = ToNumber(lhs, t);
411 Type::None(zone()) : 752 rhs = ToNumber(rhs, t);
412 left.upper->Is(Type::Number()) && right.upper->Is(Type::Number()) ? 753 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
413 Type::Number(zone()) : 754 // TODO(neis): Do some analysis.
414 left.upper->Is(Type::String()) || right.upper->Is(Type::String()) ? 755 // TODO(neis): Deal with numeric bitsets here and elsewhere.
415 Type::String(zone()) : Type::NumberOrString(zone()); 756 return Type::Number();
416 return Bounds(lower, upper); 757 }
417 } 758
418 759
419 760 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
420 Bounds Typer::Visitor::TypeJSSubtract(Node* node) { 761 lhs = ToNumber(lhs, t);
421 return Bounds(Type::SignedSmall(zone()), Type::Number(zone())); 762 rhs = ToNumber(rhs, t);
422 } 763 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
423 764 // TODO(neis): Do some analysis.
424 765 return Type::Number();
425 Bounds Typer::Visitor::TypeJSMultiply(Node* node) { 766 }
426 return Bounds(Type::SignedSmall(zone()), Type::Number(zone())); 767
427 } 768
428 769 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
429 770 lhs = ToNumber(lhs, t);
430 Bounds Typer::Visitor::TypeJSDivide(Node* node) { 771 rhs = ToNumber(rhs, t);
431 return Bounds(Type::SignedSmall(zone()), Type::Number(zone())); 772 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
432 } 773 // TODO(neis): Do some analysis.
433 774 return Type::Number();
434 775 }
435 Bounds Typer::Visitor::TypeJSModulus(Node* node) { 776
436 return Bounds(Type::SignedSmall(zone()), Type::Number(zone())); 777
778 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
779 lhs = ToNumber(lhs, t);
780 rhs = ToNumber(rhs, t);
781 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
782 // TODO(neis): Do some analysis.
783 return Type::Number();
784 }
785
786
787 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
788 lhs = ToNumber(lhs, t);
789 rhs = ToNumber(rhs, t);
790 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN();
791 // TODO(neis): Do some analysis.
792 return Type::Number();
437 } 793 }
438 794
439 795
440 // JS unary operators. 796 // JS unary operators.
441 797
798
799 Type* Typer::Visitor::JSUnaryNotTyper(Type* type, Typer* t) {
800 return Invert(ToBoolean(type, t), t);
801 }
802
803
442 Bounds Typer::Visitor::TypeJSUnaryNot(Node* node) { 804 Bounds Typer::Visitor::TypeJSUnaryNot(Node* node) {
443 return Bounds(Type::Boolean(zone())); 805 return TypeUnaryOp(node, JSUnaryNotTyper);
444 } 806 }
445 807
446 808
447 Bounds Typer::Visitor::TypeJSTypeOf(Node* node) { 809 Bounds Typer::Visitor::TypeJSTypeOf(Node* node) {
448 return Bounds(Type::InternalizedString(zone())); 810 return Bounds(Type::InternalizedString());
449 } 811 }
450 812
451 813
452 // JS conversion operators. 814 // JS conversion operators.
453 815
816
454 Bounds Typer::Visitor::TypeJSToBoolean(Node* node) { 817 Bounds Typer::Visitor::TypeJSToBoolean(Node* node) {
455 return Bounds(Type::Boolean(zone())); 818 return TypeUnaryOp(node, ToBoolean);
456 } 819 }
457 820
458 821
459 Bounds Typer::Visitor::TypeJSToNumber(Node* node) { 822 Bounds Typer::Visitor::TypeJSToNumber(Node* node) {
460 return Bounds(Type::SignedSmall(zone()), Type::Number(zone())); 823 return TypeUnaryOp(node, ToNumber);
461 } 824 }
462 825
463 826
464 Bounds Typer::Visitor::TypeJSToString(Node* node) { 827 Bounds Typer::Visitor::TypeJSToString(Node* node) {
465 return Bounds(Type::None(zone()), Type::String(zone())); 828 return TypeUnaryOp(node, ToString);
466 } 829 }
467 830
468 831
469 Bounds Typer::Visitor::TypeJSToName(Node* node) { 832 Bounds Typer::Visitor::TypeJSToName(Node* node) {
470 return Bounds(Type::None(zone()), Type::Name(zone())); 833 return Bounds(Type::None(), Type::Name());
471 } 834 }
472 835
473 836
474 Bounds Typer::Visitor::TypeJSToObject(Node* node) { 837 Bounds Typer::Visitor::TypeJSToObject(Node* node) {
475 return Bounds(Type::None(zone()), Type::Receiver(zone())); 838 return Bounds(Type::None(), Type::Receiver());
476 } 839 }
477 840
478 841
479 // JS object operators. 842 // JS object operators.
480 843
844
481 Bounds Typer::Visitor::TypeJSCreate(Node* node) { 845 Bounds Typer::Visitor::TypeJSCreate(Node* node) {
482 return Bounds(Type::None(zone()), Type::Object(zone())); 846 return Bounds(Type::None(), Type::Object());
847 }
848
849
850 Type* Typer::Visitor::JSLoadPropertyTyper(Type* object, Type* name, Typer* t) {
851 // TODO(rossberg): Use range types and sized array types to filter undefined.
852 if (object->IsArray() && name->Is(Type::Integral32())) {
853 return Type::Union(
854 object->AsArray()->Element(), Type::Undefined(), t->zone());
855 }
856 return Type::Any();
483 } 857 }
484 858
485 859
486 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) { 860 Bounds Typer::Visitor::TypeJSLoadProperty(Node* node) {
487 Bounds object = OperandType(node, 0); 861 return TypeBinaryOp(node, JSLoadPropertyTyper);
488 Bounds name = OperandType(node, 1); 862 }
489 Bounds result = Bounds::Unbounded(zone()); 863
490 // TODO(rossberg): Use range types and sized array types to filter undefined. 864
491 if (object.lower->IsArray() && name.lower->Is(Type::Integral32())) {
492 result.lower = Type::Union(
493 object.lower->AsArray()->Element(), Type::Undefined(zone()), zone());
494 }
495 if (object.upper->IsArray() && name.upper->Is(Type::Integral32())) {
496 result.upper = Type::Union(
497 object.upper->AsArray()->Element(), Type::Undefined(zone()), zone());
498 }
499 return result;
500 }
501
502
503 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) { 865 Bounds Typer::Visitor::TypeJSLoadNamed(Node* node) {
504 return Bounds::Unbounded(zone()); 866 return Bounds::Unbounded(zone());
505 } 867 }
506 868
507 869
508 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) { 870 Bounds Typer::Visitor::TypeJSStoreProperty(Node* node) {
509 UNREACHABLE(); 871 UNREACHABLE();
510 return Bounds(); 872 return Bounds();
511 } 873 }
512 874
513 875
514 Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) { 876 Bounds Typer::Visitor::TypeJSStoreNamed(Node* node) {
515 UNREACHABLE(); 877 UNREACHABLE();
516 return Bounds(); 878 return Bounds();
517 } 879 }
518 880
519 881
520 Bounds Typer::Visitor::TypeJSDeleteProperty(Node* node) { 882 Bounds Typer::Visitor::TypeJSDeleteProperty(Node* node) {
521 return Bounds(Type::Boolean(zone())); 883 return Bounds(Type::Boolean());
522 } 884 }
523 885
524 886
525 Bounds Typer::Visitor::TypeJSHasProperty(Node* node) { 887 Bounds Typer::Visitor::TypeJSHasProperty(Node* node) {
526 return Bounds(Type::Boolean(zone())); 888 return Bounds(Type::Boolean());
527 } 889 }
528 890
529 891
530 Bounds Typer::Visitor::TypeJSInstanceOf(Node* node) { 892 Bounds Typer::Visitor::TypeJSInstanceOf(Node* node) {
531 return Bounds(Type::Boolean(zone())); 893 return Bounds(Type::Boolean());
532 } 894 }
533 895
534 896
535 // JS context operators. 897 // JS context operators.
536 898
899
537 Bounds Typer::Visitor::TypeJSLoadContext(Node* node) { 900 Bounds Typer::Visitor::TypeJSLoadContext(Node* node) {
538 Bounds outer = OperandType(node, 0); 901 Bounds outer = OperandType(node, 0);
539 DCHECK(outer.upper->Maybe(Type::Internal())); 902 DCHECK(outer.upper->Maybe(Type::Internal()));
540 // TODO(rossberg): More precisely, instead of the above assertion, we should 903 // TODO(rossberg): More precisely, instead of the above assertion, we should
541 // back-propagate the constraint that it has to be a subtype of Internal. 904 // back-propagate the constraint that it has to be a subtype of Internal.
542 905
543 ContextAccess access = OpParameter<ContextAccess>(node); 906 ContextAccess access = OpParameter<ContextAccess>(node);
544 Type* context_type = outer.upper; 907 Type* context_type = outer.upper;
545 MaybeHandle<Context> context; 908 MaybeHandle<Context> context;
546 if (context_type->IsConstant()) { 909 if (context_type->IsConstant()) {
(...skipping 14 matching lines...) Expand all
561 context = handle(context.ToHandleChecked()->previous(), isolate()); 924 context = handle(context.ToHandleChecked()->previous(), isolate());
562 } 925 }
563 } 926 }
564 if (context.is_null()) { 927 if (context.is_null()) {
565 return Bounds::Unbounded(zone()); 928 return Bounds::Unbounded(zone());
566 } else { 929 } else {
567 Handle<Object> value = 930 Handle<Object> value =
568 handle(context.ToHandleChecked()->get(static_cast<int>(access.index())), 931 handle(context.ToHandleChecked()->get(static_cast<int>(access.index())),
569 isolate()); 932 isolate());
570 Type* lower = TypeConstant(value); 933 Type* lower = TypeConstant(value);
571 return Bounds(lower, Type::Any(zone())); 934 return Bounds(lower, Type::Any());
572 } 935 }
573 } 936 }
574 937
575 938
576 Bounds Typer::Visitor::TypeJSStoreContext(Node* node) { 939 Bounds Typer::Visitor::TypeJSStoreContext(Node* node) {
577 UNREACHABLE(); 940 UNREACHABLE();
578 return Bounds(); 941 return Bounds();
579 } 942 }
580 943
581 944
(...skipping 29 matching lines...) Expand all
611 974
612 975
613 Bounds Typer::Visitor::TypeJSCreateGlobalContext(Node* node) { 976 Bounds Typer::Visitor::TypeJSCreateGlobalContext(Node* node) {
614 Type* outer = ContextType(node); 977 Type* outer = ContextType(node);
615 return Bounds(Type::Context(outer, zone())); 978 return Bounds(Type::Context(outer, zone()));
616 } 979 }
617 980
618 981
619 // JS other operators. 982 // JS other operators.
620 983
984
621 Bounds Typer::Visitor::TypeJSYield(Node* node) { 985 Bounds Typer::Visitor::TypeJSYield(Node* node) {
622 return Bounds::Unbounded(zone()); 986 return Bounds::Unbounded(zone());
623 } 987 }
624 988
625 989
626 Bounds Typer::Visitor::TypeJSCallConstruct(Node* node) { 990 Bounds Typer::Visitor::TypeJSCallConstruct(Node* node) {
627 return Bounds(Type::None(zone()), Type::Receiver(zone())); 991 return Bounds(Type::None(), Type::Receiver());
992 }
993
994
995 Type* Typer::Visitor::JSCallFunctionTyper(Type* fun, Typer* t) {
996 return fun->IsFunction() ? fun->AsFunction()->Result() : Type::Any();
628 } 997 }
629 998
630 999
631 Bounds Typer::Visitor::TypeJSCallFunction(Node* node) { 1000 Bounds Typer::Visitor::TypeJSCallFunction(Node* node) {
632 Bounds fun = OperandType(node, 0); 1001 return TypeUnaryOp(node, JSCallFunctionTyper); // We ignore argument types.
633 Type* lower = fun.lower->IsFunction()
634 ? fun.lower->AsFunction()->Result() : Type::None(zone());
635 Type* upper = fun.upper->IsFunction()
636 ? fun.upper->AsFunction()->Result() : Type::Any(zone());
637 return Bounds(lower, upper);
638 } 1002 }
639 1003
640 1004
641 Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) { 1005 Bounds Typer::Visitor::TypeJSCallRuntime(Node* node) {
642 return Bounds::Unbounded(zone()); 1006 return Bounds::Unbounded(zone());
643 } 1007 }
644 1008
645 1009
646 Bounds Typer::Visitor::TypeJSDebugger(Node* node) { 1010 Bounds Typer::Visitor::TypeJSDebugger(Node* node) {
647 return Bounds::Unbounded(zone()); 1011 return Bounds::Unbounded(zone());
648 } 1012 }
649 1013
650 1014
651 // Simplified operators. 1015 // Simplified operators.
652 1016
1017
653 Bounds Typer::Visitor::TypeBooleanNot(Node* node) { 1018 Bounds Typer::Visitor::TypeBooleanNot(Node* node) {
654 return Bounds(Type::Boolean(zone())); 1019 return Bounds(Type::Boolean());
655 } 1020 }
656 1021
657 1022
658 Bounds Typer::Visitor::TypeBooleanToNumber(Node* node) { 1023 Bounds Typer::Visitor::TypeBooleanToNumber(Node* node) {
659 return Bounds(Type::Number(zone())); 1024 return Bounds(Type::Number());
660 } 1025 }
661 1026
662 1027
663 Bounds Typer::Visitor::TypeNumberEqual(Node* node) { 1028 Bounds Typer::Visitor::TypeNumberEqual(Node* node) {
664 return Bounds(Type::Boolean(zone())); 1029 return Bounds(Type::Boolean());
665 } 1030 }
666 1031
667 1032
668 Bounds Typer::Visitor::TypeNumberLessThan(Node* node) { 1033 Bounds Typer::Visitor::TypeNumberLessThan(Node* node) {
669 return Bounds(Type::Boolean(zone())); 1034 return Bounds(Type::Boolean());
670 } 1035 }
671 1036
672 1037
673 Bounds Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) { 1038 Bounds Typer::Visitor::TypeNumberLessThanOrEqual(Node* node) {
674 return Bounds(Type::Boolean(zone())); 1039 return Bounds(Type::Boolean());
675 } 1040 }
676 1041
677 1042
678 Bounds Typer::Visitor::TypeNumberAdd(Node* node) { 1043 Bounds Typer::Visitor::TypeNumberAdd(Node* node) {
679 return Bounds(Type::Number(zone())); 1044 return Bounds(Type::Number());
680 } 1045 }
681 1046
682 1047
683 Bounds Typer::Visitor::TypeNumberSubtract(Node* node) { 1048 Bounds Typer::Visitor::TypeNumberSubtract(Node* node) {
684 return Bounds(Type::Number(zone())); 1049 return Bounds(Type::Number());
685 } 1050 }
686 1051
687 1052
688 Bounds Typer::Visitor::TypeNumberMultiply(Node* node) { 1053 Bounds Typer::Visitor::TypeNumberMultiply(Node* node) {
689 return Bounds(Type::Number(zone())); 1054 return Bounds(Type::Number());
690 } 1055 }
691 1056
692 1057
693 Bounds Typer::Visitor::TypeNumberDivide(Node* node) { 1058 Bounds Typer::Visitor::TypeNumberDivide(Node* node) {
694 return Bounds(Type::Number(zone())); 1059 return Bounds(Type::Number());
695 } 1060 }
696 1061
697 1062
698 Bounds Typer::Visitor::TypeNumberModulus(Node* node) { 1063 Bounds Typer::Visitor::TypeNumberModulus(Node* node) {
699 return Bounds(Type::Number(zone())); 1064 return Bounds(Type::Number());
700 } 1065 }
701 1066
702 1067
703 Bounds Typer::Visitor::TypeNumberToInt32(Node* node) { 1068 Bounds Typer::Visitor::TypeNumberToInt32(Node* node) {
704 Bounds arg = OperandType(node, 0); 1069 return TypeUnaryOp(node, NumberToInt32);
705 Type* s32 = Type::Signed32(zone());
706 Type* lower = arg.lower->Is(s32) ? arg.lower : s32;
707 Type* upper = arg.upper->Is(s32) ? arg.upper : s32;
708 return Bounds(lower, upper);
709 } 1070 }
710 1071
711 1072
712 Bounds Typer::Visitor::TypeNumberToUint32(Node* node) { 1073 Bounds Typer::Visitor::TypeNumberToUint32(Node* node) {
713 Bounds arg = OperandType(node, 0); 1074 return TypeUnaryOp(node, NumberToUint32);
714 Type* u32 = Type::Unsigned32(zone());
715 Type* lower = arg.lower->Is(u32) ? arg.lower : u32;
716 Type* upper = arg.upper->Is(u32) ? arg.upper : u32;
717 return Bounds(lower, upper);
718 } 1075 }
719 1076
720 1077
721 Bounds Typer::Visitor::TypeReferenceEqual(Node* node) { 1078 Bounds Typer::Visitor::TypeReferenceEqual(Node* node) {
722 return Bounds(Type::Boolean(zone())); 1079 return Bounds(Type::Boolean());
723 } 1080 }
724 1081
725 1082
726 Bounds Typer::Visitor::TypeStringEqual(Node* node) { 1083 Bounds Typer::Visitor::TypeStringEqual(Node* node) {
727 return Bounds(Type::Boolean(zone())); 1084 return Bounds(Type::Boolean());
728 } 1085 }
729 1086
730 1087
731 Bounds Typer::Visitor::TypeStringLessThan(Node* node) { 1088 Bounds Typer::Visitor::TypeStringLessThan(Node* node) {
732 return Bounds(Type::Boolean(zone())); 1089 return Bounds(Type::Boolean());
733 } 1090 }
734 1091
735 1092
736 Bounds Typer::Visitor::TypeStringLessThanOrEqual(Node* node) { 1093 Bounds Typer::Visitor::TypeStringLessThanOrEqual(Node* node) {
737 return Bounds(Type::Boolean(zone())); 1094 return Bounds(Type::Boolean());
738 } 1095 }
739 1096
740 1097
741 Bounds Typer::Visitor::TypeStringAdd(Node* node) { 1098 Bounds Typer::Visitor::TypeStringAdd(Node* node) {
742 return Bounds(Type::String(zone())); 1099 return Bounds(Type::String());
1100 }
1101
1102
1103 static Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) {
1104 // TODO(neis): Enable when expressible.
1105 /*
1106 return Type::Union(
1107 Type::Intersect(type, Type::Semantic(), zone),
1108 Type::Intersect(rep, Type::Representation(), zone), zone);
1109 */
1110 return type;
743 } 1111 }
744 1112
745 1113
746 Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) { 1114 Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) {
747 // TODO(titzer): type is type of input, representation is Word32. 1115 Bounds arg = OperandType(node, 0);
748 return Bounds(Type::Integral32()); 1116 // TODO(neis): DCHECK(arg.upper->Is(Type::Signed32()));
1117 return Bounds(
1118 ChangeRepresentation(arg.lower, Type::UntaggedInt32(), zone()),
1119 ChangeRepresentation(arg.upper, Type::UntaggedInt32(), zone()));
749 } 1120 }
750 1121
751 1122
752 Bounds Typer::Visitor::TypeChangeTaggedToUint32(Node* node) { 1123 Bounds Typer::Visitor::TypeChangeTaggedToUint32(Node* node) {
753 return Bounds(Type::Integral32()); // TODO(titzer): add appropriate rep 1124 Bounds arg = OperandType(node, 0);
1125 // TODO(neis): DCHECK(arg.upper->Is(Type::Unsigned32()));
1126 return Bounds(
1127 ChangeRepresentation(arg.lower, Type::UntaggedInt32(), zone()),
1128 ChangeRepresentation(arg.upper, Type::UntaggedInt32(), zone()));
754 } 1129 }
755 1130
756 1131
757 Bounds Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) { 1132 Bounds Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
758 // TODO(titzer): type is type of input, representation is Float64. 1133 Bounds arg = OperandType(node, 0);
759 return Bounds(Type::Number()); 1134 // TODO(neis): DCHECK(arg.upper->Is(Type::Number()));
1135 return Bounds(
1136 ChangeRepresentation(arg.lower, Type::UntaggedFloat64(), zone()),
1137 ChangeRepresentation(arg.upper, Type::UntaggedFloat64(), zone()));
760 } 1138 }
761 1139
762 1140
763 Bounds Typer::Visitor::TypeChangeInt32ToTagged(Node* node) { 1141 Bounds Typer::Visitor::TypeChangeInt32ToTagged(Node* node) {
764 // TODO(titzer): type is type of input, representation is Tagged. 1142 Bounds arg = OperandType(node, 0);
765 return Bounds(Type::Integral32()); 1143 // TODO(neis): DCHECK(arg.upper->Is(Type::Signed32()));
1144 return Bounds(
1145 ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
1146 ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
766 } 1147 }
767 1148
768 1149
769 Bounds Typer::Visitor::TypeChangeUint32ToTagged(Node* node) { 1150 Bounds Typer::Visitor::TypeChangeUint32ToTagged(Node* node) {
770 // TODO(titzer): type is type of input, representation is Tagged. 1151 Bounds arg = OperandType(node, 0);
771 return Bounds(Type::Unsigned32()); 1152 // TODO(neis): DCHECK(arg.upper->Is(Type::Unsigned32()));
1153 return Bounds(
1154 ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
1155 ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
772 } 1156 }
773 1157
774 1158
775 Bounds Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) { 1159 Bounds Typer::Visitor::TypeChangeFloat64ToTagged(Node* node) {
776 // TODO(titzer): type is type of input, representation is Tagged. 1160 Bounds arg = OperandType(node, 0);
777 return Bounds(Type::Number()); 1161 // TODO(neis): CHECK(arg.upper->Is(Type::Number()));
1162 return Bounds(
1163 ChangeRepresentation(arg.lower, Type::Tagged(), zone()),
1164 ChangeRepresentation(arg.upper, Type::Tagged(), zone()));
778 } 1165 }
779 1166
780 1167
781 Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) { 1168 Bounds Typer::Visitor::TypeChangeBoolToBit(Node* node) {
782 // TODO(titzer): type is type of input, representation is Bit. 1169 Bounds arg = OperandType(node, 0);
783 return Bounds(Type::Boolean()); 1170 // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
1171 return Bounds(
1172 ChangeRepresentation(arg.lower, Type::UntaggedInt1(), zone()),
1173 ChangeRepresentation(arg.upper, Type::UntaggedInt1(), zone()));
784 } 1174 }
785 1175
786 1176
787 Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) { 1177 Bounds Typer::Visitor::TypeChangeBitToBool(Node* node) {
788 // TODO(titzer): type is type of input, representation is Tagged. 1178 Bounds arg = OperandType(node, 0);
789 return Bounds(Type::Boolean()); 1179 // TODO(neis): DCHECK(arg.upper->Is(Type::Boolean()));
1180 return Bounds(
1181 ChangeRepresentation(arg.lower, Type::TaggedPtr(), zone()),
1182 ChangeRepresentation(arg.upper, Type::TaggedPtr(), zone()));
790 } 1183 }
791 1184
792 1185
793 Bounds Typer::Visitor::TypeLoadField(Node* node) { 1186 Bounds Typer::Visitor::TypeLoadField(Node* node) {
794 return Bounds(FieldAccessOf(node->op()).type); 1187 return Bounds(FieldAccessOf(node->op()).type);
795 } 1188 }
796 1189
797 1190
798 Bounds Typer::Visitor::TypeLoadElement(Node* node) { 1191 Bounds Typer::Visitor::TypeLoadElement(Node* node) {
799 return Bounds(ElementAccessOf(node->op()).type); 1192 return Bounds(ElementAccessOf(node->op()).type);
800 } 1193 }
801 1194
802 1195
803 Bounds Typer::Visitor::TypeStoreField(Node* node) { 1196 Bounds Typer::Visitor::TypeStoreField(Node* node) {
804 UNREACHABLE(); 1197 UNREACHABLE();
805 return Bounds(); 1198 return Bounds();
806 } 1199 }
807 1200
808 1201
809 Bounds Typer::Visitor::TypeStoreElement(Node* node) { 1202 Bounds Typer::Visitor::TypeStoreElement(Node* node) {
810 UNREACHABLE(); 1203 UNREACHABLE();
811 return Bounds(); 1204 return Bounds();
812 } 1205 }
813 1206
814 1207
815 // Machine operators. 1208 // Machine operators.
816 1209
1210
817 // TODO(rossberg): implement 1211 // TODO(rossberg): implement
818 #define DEFINE_METHOD(x) \ 1212 #define DEFINE_METHOD(x) \
819 Bounds Typer::Visitor::Type##x(Node* node) { return Bounds(Type::None()); } 1213 Bounds Typer::Visitor::Type##x(Node* node) { \
1214 return Bounds::Unbounded(zone()); \
1215 }
820 MACHINE_OP_LIST(DEFINE_METHOD) 1216 MACHINE_OP_LIST(DEFINE_METHOD)
821 #undef DEFINE_METHOD 1217 #undef DEFINE_METHOD
822 1218
823 1219
824 // Heap constants. 1220 // Heap constants.
825 1221
826 Type* Typer::Visitor::TypeConstant(Handle<Object> value) { 1222 Type* Typer::Visitor::TypeConstant(Handle<Object> value) {
827 if (value->IsJSFunction()) { 1223 if (value->IsJSFunction()) {
828 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) { 1224 if (JSFunction::cast(*value)->shared()->HasBuiltinFunctionId()) {
829 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) { 1225 switch (JSFunction::cast(*value)->shared()->builtin_function_id()) {
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
907 } 1303 }
908 1304
909 1305
910 void Typer::DecorateGraph(Graph* graph) { 1306 void Typer::DecorateGraph(Graph* graph) {
911 graph->AddDecorator(new (zone()) TyperDecorator(this)); 1307 graph->AddDecorator(new (zone()) TyperDecorator(this));
912 } 1308 }
913 1309
914 } 1310 }
915 } 1311 }
916 } // namespace v8::internal::compiler 1312 } // 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