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

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

Issue 2202883005: [turbofan] Unify number operation typing rules. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove useless cementation. DCHECKs instead of defensive programming are way more useful. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/typer.h ('k') | src/type-cache.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/typer.h" 5 #include "src/compiler/typer.h"
6 6
7 #include "src/base/flags.h" 7 #include "src/base/flags.h"
8 #include "src/bootstrapper.h" 8 #include "src/bootstrapper.h"
9 #include "src/compiler/common-operator.h" 9 #include "src/compiler/common-operator.h"
10 #include "src/compiler/graph-reducer.h" 10 #include "src/compiler/graph-reducer.h"
(...skipping 21 matching lines...) Expand all
32 32
33 Typer::Typer(Isolate* isolate, Graph* graph) 33 Typer::Typer(Isolate* isolate, Graph* graph)
34 : isolate_(isolate), 34 : isolate_(isolate),
35 graph_(graph), 35 graph_(graph),
36 decorator_(nullptr), 36 decorator_(nullptr),
37 cache_(TypeCache::Get()), 37 cache_(TypeCache::Get()),
38 operation_typer_(isolate, zone()) { 38 operation_typer_(isolate, zone()) {
39 Zone* zone = this->zone(); 39 Zone* zone = this->zone();
40 Factory* const factory = isolate->factory(); 40 Factory* const factory = isolate->factory();
41 41
42 Type* infinity = Type::Constant(factory->infinity_value(), zone);
43 Type* minus_infinity = Type::Constant(factory->minus_infinity_value(), zone);
44 // Unfortunately, the infinities created in other places might be different
45 // ones (eg the result of NewNumber in TypeNumberConstant).
46 Type* truncating_to_zero =
47 Type::Union(Type::Union(infinity, minus_infinity, zone),
48 Type::MinusZeroOrNaN(), zone);
49 DCHECK(!truncating_to_zero->Maybe(Type::Integral32()));
50
51 singleton_false_ = Type::Constant(factory->false_value(), zone); 42 singleton_false_ = Type::Constant(factory->false_value(), zone);
52 singleton_true_ = Type::Constant(factory->true_value(), zone); 43 singleton_true_ = Type::Constant(factory->true_value(), zone);
53 singleton_the_hole_ = Type::Constant(factory->the_hole_value(), zone); 44 singleton_the_hole_ = Type::Constant(factory->the_hole_value(), zone);
54 signed32ish_ = Type::Union(Type::Signed32(), truncating_to_zero, zone);
55 unsigned32ish_ = Type::Union(Type::Unsigned32(), truncating_to_zero, zone);
56 falsish_ = Type::Union( 45 falsish_ = Type::Union(
57 Type::Undetectable(), 46 Type::Undetectable(),
58 Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone), 47 Type::Union(Type::Union(singleton_false_, cache_.kZeroish, zone),
59 singleton_the_hole_, zone), 48 singleton_the_hole_, zone),
60 zone); 49 zone);
61 truish_ = Type::Union( 50 truish_ = Type::Union(
62 singleton_true_, 51 singleton_true_,
63 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone); 52 Type::Union(Type::DetectableReceiver(), Type::Symbol(), zone), zone);
64 53
65 decorator_ = new (zone) Decorator(this); 54 decorator_ = new (zone) Decorator(this);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE) 87 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
99 SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE) 88 SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
100 MACHINE_OP_LIST(DECLARE_CASE) 89 MACHINE_OP_LIST(DECLARE_CASE)
101 MACHINE_SIMD_OP_LIST(DECLARE_CASE) 90 MACHINE_SIMD_OP_LIST(DECLARE_CASE)
102 JS_SIMPLE_UNOP_LIST(DECLARE_CASE) 91 JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
103 JS_OBJECT_OP_LIST(DECLARE_CASE) 92 JS_OBJECT_OP_LIST(DECLARE_CASE)
104 JS_CONTEXT_OP_LIST(DECLARE_CASE) 93 JS_CONTEXT_OP_LIST(DECLARE_CASE)
105 JS_OTHER_OP_LIST(DECLARE_CASE) 94 JS_OTHER_OP_LIST(DECLARE_CASE)
106 #undef DECLARE_CASE 95 #undef DECLARE_CASE
107 96
97 #define DECLARE_CASE(x) \
98 case IrOpcode::k##x: \
99 return UpdateType(node, TypeBinaryOp(node, x));
100 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
101 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
102 #undef DECLARE_CASE
103
104 #define DECLARE_CASE(x) \
105 case IrOpcode::k##x: \
106 return UpdateType(node, TypeUnaryOp(node, x));
107 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
108 #undef DECLARE_CASE
109
108 #define DECLARE_CASE(x) case IrOpcode::k##x: 110 #define DECLARE_CASE(x) case IrOpcode::k##x:
109 DECLARE_CASE(Loop) 111 DECLARE_CASE(Loop)
110 DECLARE_CASE(Branch) 112 DECLARE_CASE(Branch)
111 DECLARE_CASE(IfTrue) 113 DECLARE_CASE(IfTrue)
112 DECLARE_CASE(IfFalse) 114 DECLARE_CASE(IfFalse)
113 DECLARE_CASE(IfSuccess) 115 DECLARE_CASE(IfSuccess)
114 DECLARE_CASE(Switch) 116 DECLARE_CASE(Switch)
115 DECLARE_CASE(IfValue) 117 DECLARE_CASE(IfValue)
116 DECLARE_CASE(IfDefault) 118 DECLARE_CASE(IfDefault)
117 DECLARE_CASE(Merge) 119 DECLARE_CASE(Merge)
(...skipping 30 matching lines...) Expand all
148 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE) 150 SIMPLIFIED_COMPARE_BINOP_LIST(DECLARE_CASE)
149 SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE) 151 SIMPLIFIED_OTHER_OP_LIST(DECLARE_CASE)
150 MACHINE_OP_LIST(DECLARE_CASE) 152 MACHINE_OP_LIST(DECLARE_CASE)
151 MACHINE_SIMD_OP_LIST(DECLARE_CASE) 153 MACHINE_SIMD_OP_LIST(DECLARE_CASE)
152 JS_SIMPLE_UNOP_LIST(DECLARE_CASE) 154 JS_SIMPLE_UNOP_LIST(DECLARE_CASE)
153 JS_OBJECT_OP_LIST(DECLARE_CASE) 155 JS_OBJECT_OP_LIST(DECLARE_CASE)
154 JS_CONTEXT_OP_LIST(DECLARE_CASE) 156 JS_CONTEXT_OP_LIST(DECLARE_CASE)
155 JS_OTHER_OP_LIST(DECLARE_CASE) 157 JS_OTHER_OP_LIST(DECLARE_CASE)
156 #undef DECLARE_CASE 158 #undef DECLARE_CASE
157 159
160 #define DECLARE_CASE(x) \
161 case IrOpcode::k##x: \
162 return TypeBinaryOp(node, x);
163 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
164 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
165 #undef DECLARE_CASE
166
167 #define DECLARE_CASE(x) \
168 case IrOpcode::k##x: \
169 return TypeUnaryOp(node, x);
170 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
171 #undef DECLARE_CASE
172
158 #define DECLARE_CASE(x) case IrOpcode::k##x: 173 #define DECLARE_CASE(x) case IrOpcode::k##x:
159 DECLARE_CASE(Loop) 174 DECLARE_CASE(Loop)
160 DECLARE_CASE(Branch) 175 DECLARE_CASE(Branch)
161 DECLARE_CASE(IfTrue) 176 DECLARE_CASE(IfTrue)
162 DECLARE_CASE(IfFalse) 177 DECLARE_CASE(IfFalse)
163 DECLARE_CASE(IfSuccess) 178 DECLARE_CASE(IfSuccess)
164 DECLARE_CASE(Switch) 179 DECLARE_CASE(Switch)
165 DECLARE_CASE(IfValue) 180 DECLARE_CASE(IfValue)
166 DECLARE_CASE(IfDefault) 181 DECLARE_CASE(IfDefault)
167 DECLARE_CASE(Merge) 182 DECLARE_CASE(Merge)
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 static Type* FalsifyUndefined(ComparisonOutcome, Typer*); 257 static Type* FalsifyUndefined(ComparisonOutcome, Typer*);
243 258
244 static Type* ToPrimitive(Type*, Typer*); 259 static Type* ToPrimitive(Type*, Typer*);
245 static Type* ToBoolean(Type*, Typer*); 260 static Type* ToBoolean(Type*, Typer*);
246 static Type* ToInteger(Type*, Typer*); 261 static Type* ToInteger(Type*, Typer*);
247 static Type* ToLength(Type*, Typer*); 262 static Type* ToLength(Type*, Typer*);
248 static Type* ToName(Type*, Typer*); 263 static Type* ToName(Type*, Typer*);
249 static Type* ToNumber(Type*, Typer*); 264 static Type* ToNumber(Type*, Typer*);
250 static Type* ToObject(Type*, Typer*); 265 static Type* ToObject(Type*, Typer*);
251 static Type* ToString(Type*, Typer*); 266 static Type* ToString(Type*, Typer*);
252 static Type* NumberCeil(Type*, Typer*); 267 #define DECLARE_METHOD(Name) \
253 static Type* NumberFloor(Type*, Typer*); 268 static Type* Name(Type* type, Typer* t) { \
254 static Type* NumberMax(Type*, Type*, Typer*); 269 return t->operation_typer_.Name(type); \
255 static Type* NumberMin(Type*, Type*, Typer*); 270 }
256 static Type* NumberRound(Type*, Typer*); 271 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_METHOD)
257 static Type* NumberSign(Type*, Typer*); 272 #undef DECLARE_METHOD
258 static Type* NumberTrunc(Type*, Typer*); 273 #define DECLARE_METHOD(Name) \
259 static Type* NumberToInt32(Type*, Typer*); 274 static Type* Name(Type* lhs, Type* rhs, Typer* t) { \
260 static Type* NumberToUint32(Type*, Typer*); 275 return t->operation_typer_.Name(lhs, rhs); \
276 }
277 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_METHOD)
278 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_METHOD)
279 #undef DECLARE_METHOD
261 280
262 static Type* ObjectIsCallable(Type*, Typer*); 281 static Type* ObjectIsCallable(Type*, Typer*);
263 static Type* ObjectIsNumber(Type*, Typer*); 282 static Type* ObjectIsNumber(Type*, Typer*);
264 static Type* ObjectIsReceiver(Type*, Typer*); 283 static Type* ObjectIsReceiver(Type*, Typer*);
265 static Type* ObjectIsSmi(Type*, Typer*); 284 static Type* ObjectIsSmi(Type*, Typer*);
266 static Type* ObjectIsString(Type*, Typer*); 285 static Type* ObjectIsString(Type*, Typer*);
267 static Type* ObjectIsUndetectable(Type*, Typer*); 286 static Type* ObjectIsUndetectable(Type*, Typer*);
268 287
269 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*); 288 static ComparisonOutcome JSCompareTyper(Type*, Type*, Typer*);
270 289
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
444 // ES6 section 7.1.14 ToPropertyKey ( argument ) 463 // ES6 section 7.1.14 ToPropertyKey ( argument )
445 type = ToPrimitive(type, t); 464 type = ToPrimitive(type, t);
446 if (type->Is(Type::Name())) return type; 465 if (type->Is(Type::Name())) return type;
447 if (type->Maybe(Type::Symbol())) return Type::Name(); 466 if (type->Maybe(Type::Symbol())) return Type::Name();
448 return ToString(type, t); 467 return ToString(type, t);
449 } 468 }
450 469
451 470
452 // static 471 // static
453 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) { 472 Type* Typer::Visitor::ToNumber(Type* type, Typer* t) {
454 if (type->Is(Type::Number())) return type; 473 return t->operation_typer_.ToNumber(type);
455 if (type->Is(Type::NullOrUndefined())) {
456 if (type->Is(Type::Null())) return t->cache_.kSingletonZero;
457 if (type->Is(Type::Undefined())) return Type::NaN();
458 return Type::Union(Type::NaN(), t->cache_.kSingletonZero, t->zone());
459 }
460 if (type->Is(Type::NumberOrUndefined())) {
461 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
462 Type::NaN(), t->zone());
463 }
464 if (type->Is(t->singleton_false_)) return t->cache_.kSingletonZero;
465 if (type->Is(t->singleton_true_)) return t->cache_.kSingletonOne;
466 if (type->Is(Type::Boolean())) return t->cache_.kZeroOrOne;
467 if (type->Is(Type::BooleanOrNumber())) {
468 return Type::Union(Type::Intersect(type, Type::Number(), t->zone()),
469 t->cache_.kZeroOrOne, t->zone());
470 }
471 return Type::Number();
472 } 474 }
473 475
474 476
475 // static 477 // static
476 Type* Typer::Visitor::ToObject(Type* type, Typer* t) { 478 Type* Typer::Visitor::ToObject(Type* type, Typer* t) {
477 // ES6 section 7.1.13 ToObject ( argument ) 479 // ES6 section 7.1.13 ToObject ( argument )
478 if (type->Is(Type::Receiver())) return type; 480 if (type->Is(Type::Receiver())) return type;
479 if (type->Is(Type::Primitive())) return Type::OtherObject(); 481 if (type->Is(Type::Primitive())) return Type::OtherObject();
480 if (!type->Maybe(Type::OtherUndetectable())) { 482 if (!type->Maybe(Type::OtherUndetectable())) {
481 return Type::DetectableReceiver(); 483 return Type::DetectableReceiver();
482 } 484 }
483 return Type::Receiver(); 485 return Type::Receiver();
484 } 486 }
485 487
486 488
487 // static 489 // static
488 Type* Typer::Visitor::ToString(Type* type, Typer* t) { 490 Type* Typer::Visitor::ToString(Type* type, Typer* t) {
489 // ES6 section 7.1.12 ToString ( argument ) 491 // ES6 section 7.1.12 ToString ( argument )
490 type = ToPrimitive(type, t); 492 type = ToPrimitive(type, t);
491 if (type->Is(Type::String())) return type; 493 if (type->Is(Type::String())) return type;
492 return Type::String(); 494 return Type::String();
493 } 495 }
494 496
495 // static
496 Type* Typer::Visitor::NumberCeil(Type* type, Typer* t) {
497 DCHECK(type->Is(Type::Number()));
498 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type;
499 // TODO(bmeurer): We could infer a more precise type here.
500 return t->cache_.kIntegerOrMinusZeroOrNaN;
501 }
502
503 // static
504 Type* Typer::Visitor::NumberFloor(Type* type, Typer* t) {
505 DCHECK(type->Is(Type::Number()));
506 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type;
507 // TODO(bmeurer): We could infer a more precise type here.
508 return t->cache_.kIntegerOrMinusZeroOrNaN;
509 }
510
511 // static
512 Type* Typer::Visitor::NumberMax(Type* lhs, Type* rhs, Typer* t) {
513 DCHECK(lhs->Is(Type::Number()));
514 DCHECK(rhs->Is(Type::Number()));
515 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) {
516 return Type::NaN();
517 }
518 Type* type = Type::None();
519 // TODO(turbofan): Improve minus zero handling here.
520 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
521 type = Type::Union(type, Type::NaN(), t->zone());
522 }
523 lhs = Type::Intersect(lhs, Type::OrderedNumber(), t->zone());
524 rhs = Type::Intersect(rhs, Type::OrderedNumber(), t->zone());
525 if (lhs->Is(t->cache_.kInteger) && rhs->Is(t->cache_.kInteger)) {
526 double max = std::max(lhs->Max(), rhs->Max());
527 double min = std::max(lhs->Min(), rhs->Min());
528 type = Type::Union(type, Type::Range(min, max, t->zone()), t->zone());
529 } else {
530 type = Type::Union(type, Type::Union(lhs, rhs, t->zone()), t->zone());
531 }
532 return type;
533 }
534
535 // static
536 Type* Typer::Visitor::NumberMin(Type* lhs, Type* rhs, Typer* t) {
537 DCHECK(lhs->Is(Type::Number()));
538 DCHECK(rhs->Is(Type::Number()));
539 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) {
540 return Type::NaN();
541 }
542 Type* type = Type::None();
543 // TODO(turbofan): Improve minus zero handling here.
544 if (lhs->Maybe(Type::NaN()) || rhs->Maybe(Type::NaN())) {
545 type = Type::Union(type, Type::NaN(), t->zone());
546 }
547 lhs = Type::Intersect(lhs, Type::OrderedNumber(), t->zone());
548 rhs = Type::Intersect(rhs, Type::OrderedNumber(), t->zone());
549 if (lhs->Is(t->cache_.kInteger) && rhs->Is(t->cache_.kInteger)) {
550 double max = std::min(lhs->Max(), rhs->Max());
551 double min = std::min(lhs->Min(), rhs->Min());
552 type = Type::Union(type, Type::Range(min, max, t->zone()), t->zone());
553 } else {
554 type = Type::Union(type, Type::Union(lhs, rhs, t->zone()), t->zone());
555 }
556 return type;
557 }
558
559 // static
560 Type* Typer::Visitor::NumberRound(Type* type, Typer* t) {
561 DCHECK(type->Is(Type::Number()));
562 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type;
563 // TODO(bmeurer): We could infer a more precise type here.
564 return t->cache_.kIntegerOrMinusZeroOrNaN;
565 }
566
567 // static
568 Type* Typer::Visitor::NumberSign(Type* type, Typer* t) {
569 DCHECK(type->Is(Type::Number()));
570 if (type->Is(t->cache_.kZeroish)) return type;
571 bool maybe_minuszero = type->Maybe(Type::MinusZero());
572 bool maybe_nan = type->Maybe(Type::NaN());
573 type = Type::Intersect(type, Type::PlainNumber(), t->zone());
574 if (type->Max() < 0.0) {
575 type = t->cache_.kSingletonMinusOne;
576 } else if (type->Max() <= 0.0) {
577 type = t->cache_.kMinusOneOrZero;
578 } else if (type->Min() > 0.0) {
579 type = t->cache_.kSingletonOne;
580 } else if (type->Min() >= 0.0) {
581 type = t->cache_.kZeroOrOne;
582 } else {
583 type = Type::Range(-1.0, 1.0, t->zone());
584 }
585 if (maybe_minuszero) {
586 type = Type::Union(type, Type::MinusZero(), t->zone());
587 }
588 if (maybe_nan) {
589 type = Type::Union(type, Type::NaN(), t->zone());
590 }
591 return type;
592 }
593
594 // static
595 Type* Typer::Visitor::NumberTrunc(Type* type, Typer* t) {
596 DCHECK(type->Is(Type::Number()));
597 if (type->Is(t->cache_.kIntegerOrMinusZeroOrNaN)) return type;
598 // TODO(bmeurer): We could infer a more precise type here.
599 return t->cache_.kIntegerOrMinusZeroOrNaN;
600 }
601
602 Type* Typer::Visitor::NumberToInt32(Type* type, Typer* t) {
603 if (type->Is(Type::Signed32())) return type;
604 if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero;
605 if (type->Is(t->signed32ish_)) {
606 return Type::Intersect(
607 Type::Union(type, t->cache_.kSingletonZero, t->zone()),
608 Type::Signed32(), t->zone());
609 }
610 return Type::Signed32();
611 }
612
613
614 Type* Typer::Visitor::NumberToUint32(Type* type, Typer* t) {
615 if (type->Is(Type::Unsigned32())) return type;
616 if (type->Is(t->cache_.kZeroish)) return t->cache_.kSingletonZero;
617 if (type->Is(t->unsigned32ish_)) {
618 return Type::Intersect(
619 Type::Union(type, t->cache_.kSingletonZero, t->zone()),
620 Type::Unsigned32(), t->zone());
621 }
622 return Type::Unsigned32();
623 }
624
625 // Type checks. 497 // Type checks.
626 498
627 Type* Typer::Visitor::ObjectIsCallable(Type* type, Typer* t) { 499 Type* Typer::Visitor::ObjectIsCallable(Type* type, Typer* t) {
628 if (type->Is(Type::Function())) return t->singleton_true_; 500 if (type->Is(Type::Function())) return t->singleton_true_;
629 if (type->Is(Type::Primitive())) return t->singleton_false_; 501 if (type->Is(Type::Primitive())) return t->singleton_false_;
630 return Type::Boolean(); 502 return Type::Boolean();
631 } 503 }
632 504
633 Type* Typer::Visitor::ObjectIsNumber(Type* type, Typer* t) { 505 Type* Typer::Visitor::ObjectIsNumber(Type* type, Typer* t) {
634 if (type->Is(Type::Number())) return t->singleton_true_; 506 if (type->Is(Type::Number())) return t->singleton_true_;
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 889
1018 Type* Typer::Visitor::JSGreaterThanOrEqualTyper( 890 Type* Typer::Visitor::JSGreaterThanOrEqualTyper(
1019 Type* lhs, Type* rhs, Typer* t) { 891 Type* lhs, Type* rhs, Typer* t) {
1020 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t); 892 return FalsifyUndefined(Invert(JSCompareTyper(lhs, rhs, t), t), t);
1021 } 893 }
1022 894
1023 // JS bitwise operators. 895 // JS bitwise operators.
1024 896
1025 897
1026 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { 898 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
1027 lhs = NumberToInt32(ToNumber(lhs, t), t); 899 return NumberBitwiseOr(ToNumber(lhs, t), ToNumber(rhs, t), t);
1028 rhs = NumberToInt32(ToNumber(rhs, t), t);
1029 double lmin = lhs->Min();
1030 double rmin = rhs->Min();
1031 double lmax = lhs->Max();
1032 double rmax = rhs->Max();
1033 // Or-ing any two values results in a value no smaller than their minimum.
1034 // Even no smaller than their maximum if both values are non-negative.
1035 double min =
1036 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin);
1037 double max = Type::Signed32()->Max();
1038
1039 // Or-ing with 0 is essentially a conversion to int32.
1040 if (rmin == 0 && rmax == 0) {
1041 min = lmin;
1042 max = lmax;
1043 }
1044 if (lmin == 0 && lmax == 0) {
1045 min = rmin;
1046 max = rmax;
1047 }
1048
1049 if (lmax < 0 || rmax < 0) {
1050 // Or-ing two values of which at least one is negative results in a negative
1051 // value.
1052 max = std::min(max, -1.0);
1053 }
1054 return Type::Range(min, max, t->zone());
1055 } 900 }
1056 901
1057 902
1058 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { 903 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
1059 lhs = NumberToInt32(ToNumber(lhs, t), t); 904 return NumberBitwiseAnd(ToNumber(lhs, t), ToNumber(rhs, t), t);
1060 rhs = NumberToInt32(ToNumber(rhs, t), t);
1061 double lmin = lhs->Min();
1062 double rmin = rhs->Min();
1063 double lmax = lhs->Max();
1064 double rmax = rhs->Max();
1065 double min = Type::Signed32()->Min();
1066 // And-ing any two values results in a value no larger than their maximum.
1067 // Even no larger than their minimum if both values are non-negative.
1068 double max =
1069 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax);
1070 // And-ing with a non-negative value x causes the result to be between
1071 // zero and x.
1072 if (lmin >= 0) {
1073 min = 0;
1074 max = std::min(max, lmax);
1075 }
1076 if (rmin >= 0) {
1077 min = 0;
1078 max = std::min(max, rmax);
1079 }
1080 return Type::Range(min, max, t->zone());
1081 } 905 }
1082 906
1083 907
1084 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { 908 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) {
1085 lhs = NumberToInt32(ToNumber(lhs, t), t); 909 return NumberBitwiseXor(ToNumber(lhs, t), ToNumber(rhs, t), t);
1086 rhs = NumberToInt32(ToNumber(rhs, t), t);
1087 double lmin = lhs->Min();
1088 double rmin = rhs->Min();
1089 double lmax = lhs->Max();
1090 double rmax = rhs->Max();
1091 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) {
1092 // Xor-ing negative or non-negative values results in a non-negative value.
1093 return Type::Unsigned31();
1094 }
1095 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) {
1096 // Xor-ing a negative and a non-negative value results in a negative value.
1097 // TODO(jarin) Use a range here.
1098 return Type::Negative32();
1099 }
1100 return Type::Signed32();
1101 } 910 }
1102 911
1103 912
1104 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { 913 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
1105 return Type::Signed32(); 914 return NumberShiftLeft(ToNumber(lhs, t), ToNumber(rhs, t), t);
1106 } 915 }
1107 916
1108 917
1109 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { 918 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
1110 lhs = NumberToInt32(ToNumber(lhs, t), t); 919 return NumberShiftRight(ToNumber(lhs, t), ToNumber(rhs, t), t);
1111 rhs = NumberToUint32(ToNumber(rhs, t), t);
1112 double min = kMinInt;
1113 double max = kMaxInt;
1114 if (lhs->Min() >= 0) {
1115 // Right-shifting a non-negative value cannot make it negative, nor larger.
1116 min = std::max(min, 0.0);
1117 max = std::min(max, lhs->Max());
1118 if (rhs->Min() > 0 && rhs->Max() <= 31) {
1119 max = static_cast<int>(max) >> static_cast<int>(rhs->Min());
1120 }
1121 }
1122 if (lhs->Max() < 0) {
1123 // Right-shifting a negative value cannot make it non-negative, nor smaller.
1124 min = std::max(min, lhs->Min());
1125 max = std::min(max, -1.0);
1126 if (rhs->Min() > 0 && rhs->Max() <= 31) {
1127 min = static_cast<int>(min) >> static_cast<int>(rhs->Min());
1128 }
1129 }
1130 if (rhs->Min() > 0 && rhs->Max() <= 31) {
1131 // Right-shifting by a positive value yields a small integer value.
1132 double shift_min = kMinInt >> static_cast<int>(rhs->Min());
1133 double shift_max = kMaxInt >> static_cast<int>(rhs->Min());
1134 min = std::max(min, shift_min);
1135 max = std::min(max, shift_max);
1136 }
1137 // TODO(jarin) Ideally, the following micro-optimization should be performed
1138 // by the type constructor.
1139 if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) {
1140 return Type::Range(min, max, t->zone());
1141 }
1142 return Type::Signed32();
1143 } 920 }
1144 921
1145 922
1146 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { 923 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
1147 lhs = NumberToUint32(ToNumber(lhs, t), t); 924 return NumberShiftRightLogical(ToNumber(lhs, t), ToNumber(rhs, t), t);
1148 // Logical right-shifting any value cannot make it larger.
1149 return Type::Range(0.0, lhs->Max(), t->zone());
1150 } 925 }
1151 926
1152 927
1153 // JS arithmetic operators. 928 // JS arithmetic operators.
1154 929
1155 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) { 930 Type* Typer::Visitor::JSAddTyper(Type* lhs, Type* rhs, Typer* t) {
1156 lhs = ToPrimitive(lhs, t); 931 lhs = ToPrimitive(lhs, t);
1157 rhs = ToPrimitive(rhs, t); 932 rhs = ToPrimitive(rhs, t);
1158 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) { 933 if (lhs->Maybe(Type::String()) || rhs->Maybe(Type::String())) {
1159 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) { 934 if (lhs->Is(Type::String()) || rhs->Is(Type::String())) {
1160 return Type::String(); 935 return Type::String();
1161 } else { 936 } else {
1162 return Type::NumberOrString(); 937 return Type::NumberOrString();
1163 } 938 }
1164 } 939 }
1165 // The addition must be numeric. 940 // The addition must be numeric.
1166 return t->operation_typer()->NumberAdd(ToNumber(lhs, t), ToNumber(rhs, t)); 941 return NumberAdd(ToNumber(lhs, t), ToNumber(rhs, t), t);
1167 } 942 }
1168 943
1169 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) { 944 Type* Typer::Visitor::JSSubtractTyper(Type* lhs, Type* rhs, Typer* t) {
1170 return t->operation_typer()->NumberSubtract(ToNumber(lhs, t), 945 return NumberSubtract(ToNumber(lhs, t), ToNumber(rhs, t), t);
1171 ToNumber(rhs, t));
1172 } 946 }
1173 947
1174 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) { 948 Type* Typer::Visitor::JSMultiplyTyper(Type* lhs, Type* rhs, Typer* t) {
1175 return t->operation_typer()->NumberMultiply(ToNumber(lhs, t), 949 return NumberMultiply(ToNumber(lhs, t), ToNumber(rhs, t), t);
1176 ToNumber(rhs, t));
1177 } 950 }
1178 951
1179 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) { 952 Type* Typer::Visitor::JSDivideTyper(Type* lhs, Type* rhs, Typer* t) {
1180 return t->operation_typer()->NumberDivide(ToNumber(lhs, t), ToNumber(rhs, t)); 953 return NumberDivide(ToNumber(lhs, t), ToNumber(rhs, t), t);
1181 } 954 }
1182 955
1183 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) { 956 Type* Typer::Visitor::JSModulusTyper(Type* lhs, Type* rhs, Typer* t) {
1184 return t->operation_typer()->NumberModulus(ToNumber(lhs, t), 957 return NumberModulus(ToNumber(lhs, t), ToNumber(rhs, t), t);
1185 ToNumber(rhs, t));
1186 } 958 }
1187 959
1188 960
1189 // JS unary operators. 961 // JS unary operators.
1190 962
1191 963
1192 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) { 964 Type* Typer::Visitor::JSTypeOfTyper(Type* type, Typer* t) {
1193 Factory* const f = t->isolate()->factory(); 965 Factory* const f = t->isolate()->factory();
1194 if (type->Is(Type::Boolean())) { 966 if (type->Is(Type::Boolean())) {
1195 return Type::Constant(f->boolean_string(), t->zone()); 967 return Type::Constant(f->boolean_string(), t->zone());
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after
1662 } 1434 }
1663 1435
1664 Type* Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) { 1436 Type* Typer::Visitor::TypeSpeculativeNumberLessThan(Node* node) {
1665 return Type::Boolean(); 1437 return Type::Boolean();
1666 } 1438 }
1667 1439
1668 Type* Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) { 1440 Type* Typer::Visitor::TypeSpeculativeNumberLessThanOrEqual(Node* node) {
1669 return Type::Boolean(); 1441 return Type::Boolean();
1670 } 1442 }
1671 1443
1672 Type* Typer::Visitor::TypeNumberAdd(Node* node) { return Type::Number(); }
1673
1674 Type* Typer::Visitor::TypeNumberSubtract(Node* node) { return Type::Number(); }
1675
1676 Type* Typer::Visitor::TypeSpeculativeNumberAdd(Node* node) {
1677 return Type::Number();
1678 }
1679
1680 Type* Typer::Visitor::TypeSpeculativeNumberSubtract(Node* node) {
1681 return Type::Number();
1682 }
1683
1684 Type* Typer::Visitor::TypeSpeculativeNumberMultiply(Node* node) {
1685 return Type::Number();
1686 }
1687
1688 Type* Typer::Visitor::TypeSpeculativeNumberDivide(Node* node) {
1689 return Type::Number();
1690 }
1691
1692 Type* Typer::Visitor::TypeSpeculativeNumberModulus(Node* node) {
1693 return Type::Number();
1694 }
1695
1696 Type* Typer::Visitor::TypeSpeculativeNumberShiftLeft(Node* node) {
1697 return Type::Signed32();
1698 }
1699
1700 Type* Typer::Visitor::TypeSpeculativeNumberShiftRight(Node* node) {
1701 return Type::Signed32();
1702 }
1703
1704 Type* Typer::Visitor::TypeSpeculativeNumberShiftRightLogical(Node* node) {
1705 return Type::Unsigned32();
1706 }
1707
1708 Type* Typer::Visitor::TypeSpeculativeNumberBitwiseOr(Node* node) {
1709 return Type::Signed32();
1710 }
1711
1712 Type* Typer::Visitor::TypeSpeculativeNumberBitwiseXor(Node* node) {
1713 return Type::Signed32();
1714 }
1715
1716 Type* Typer::Visitor::TypeSpeculativeNumberBitwiseAnd(Node* node) {
1717 return Type::Signed32();
1718 }
1719
1720 Type* Typer::Visitor::TypeNumberMultiply(Node* node) { return Type::Number(); }
1721
1722 Type* Typer::Visitor::TypeNumberDivide(Node* node) { return Type::Number(); }
1723
1724 Type* Typer::Visitor::TypeNumberModulus(Node* node) { return Type::Number(); }
1725
1726 Type* Typer::Visitor::TypeNumberBitwiseOr(Node* node) {
1727 return Type::Signed32();
1728 }
1729
1730
1731 Type* Typer::Visitor::TypeNumberBitwiseXor(Node* node) {
1732 return Type::Signed32();
1733 }
1734
1735
1736 Type* Typer::Visitor::TypeNumberBitwiseAnd(Node* node) {
1737 return Type::Signed32();
1738 }
1739
1740
1741 Type* Typer::Visitor::TypeNumberShiftLeft(Node* node) {
1742 return Type::Signed32();
1743 }
1744
1745
1746 Type* Typer::Visitor::TypeNumberShiftRight(Node* node) {
1747 return Type::Signed32();
1748 }
1749
1750
1751 Type* Typer::Visitor::TypeNumberShiftRightLogical(Node* node) {
1752 return Type::Unsigned32();
1753 }
1754
1755 Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) { 1444 Type* Typer::Visitor::TypePlainPrimitiveToNumber(Node* node) {
1756 return TypeUnaryOp(node, ToNumber); 1445 return TypeUnaryOp(node, ToNumber);
1757 } 1446 }
1758 1447
1759 Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) { 1448 Type* Typer::Visitor::TypePlainPrimitiveToWord32(Node* node) {
1760 return Type::Integral32(); 1449 return Type::Integral32();
1761 } 1450 }
1762 1451
1763 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) { 1452 Type* Typer::Visitor::TypePlainPrimitiveToFloat64(Node* node) {
1764 return Type::Number(); 1453 return Type::Number();
1765 } 1454 }
1766 1455
1767 Type* Typer::Visitor::TypeNumberImul(Node* node) { return Type::Signed32(); }
1768
1769 Type* Typer::Visitor::TypeNumberAbs(Node* node) {
1770 return typer_->operation_typer()->NumberAbs(Operand(node, 0));
1771 }
1772
1773 Type* Typer::Visitor::TypeNumberClz32(Node* node) {
1774 return typer_->cache_.kZeroToThirtyTwo;
1775 }
1776
1777 Type* Typer::Visitor::TypeNumberCeil(Node* node) {
1778 return TypeUnaryOp(node, NumberCeil);
1779 }
1780
1781 Type* Typer::Visitor::TypeNumberFloor(Node* node) {
1782 return TypeUnaryOp(node, NumberFloor);
1783 }
1784
1785 Type* Typer::Visitor::TypeNumberFround(Node* node) { return Type::Number(); }
1786
1787 Type* Typer::Visitor::TypeNumberSign(Node* node) {
1788 return TypeUnaryOp(node, NumberSign);
1789 }
1790
1791 Type* Typer::Visitor::TypeNumberAcos(Node* node) { return Type::Number(); }
1792
1793 Type* Typer::Visitor::TypeNumberAcosh(Node* node) { return Type::Number(); }
1794
1795 Type* Typer::Visitor::TypeNumberAsin(Node* node) { return Type::Number(); }
1796
1797 Type* Typer::Visitor::TypeNumberAsinh(Node* node) { return Type::Number(); }
1798
1799 Type* Typer::Visitor::TypeNumberAtan(Node* node) { return Type::Number(); }
1800
1801 Type* Typer::Visitor::TypeNumberAtanh(Node* node) { return Type::Number(); }
1802
1803 Type* Typer::Visitor::TypeNumberAtan2(Node* node) { return Type::Number(); }
1804
1805 Type* Typer::Visitor::TypeNumberCos(Node* node) { return Type::Number(); }
1806
1807 Type* Typer::Visitor::TypeNumberCosh(Node* node) { return Type::Number(); }
1808
1809 Type* Typer::Visitor::TypeNumberExp(Node* node) {
1810 return Type::Union(Type::PlainNumber(), Type::NaN(), zone());
1811 }
1812
1813 // TODO(mvstanton): Is this type sufficient, or should it look like Exp()?
1814 Type* Typer::Visitor::TypeNumberExpm1(Node* node) { return Type::Number(); }
1815
1816 Type* Typer::Visitor::TypeNumberLog(Node* node) { return Type::Number(); }
1817
1818 Type* Typer::Visitor::TypeNumberLog1p(Node* node) { return Type::Number(); }
1819
1820 Type* Typer::Visitor::TypeNumberLog2(Node* node) { return Type::Number(); }
1821
1822 Type* Typer::Visitor::TypeNumberLog10(Node* node) { return Type::Number(); }
1823
1824 Type* Typer::Visitor::TypeNumberCbrt(Node* node) { return Type::Number(); }
1825
1826 Type* Typer::Visitor::TypeNumberMax(Node* node) {
1827 return TypeBinaryOp(node, NumberMax);
1828 }
1829
1830 Type* Typer::Visitor::TypeNumberMin(Node* node) {
1831 return TypeBinaryOp(node, NumberMin);
1832 }
1833
1834 Type* Typer::Visitor::TypeNumberPow(Node* node) { return Type::Number(); }
1835
1836 Type* Typer::Visitor::TypeNumberRound(Node* node) {
1837 return TypeUnaryOp(node, NumberRound);
1838 }
1839
1840 Type* Typer::Visitor::TypeNumberSin(Node* node) { return Type::Number(); }
1841
1842 Type* Typer::Visitor::TypeNumberSinh(Node* node) { return Type::Number(); }
1843
1844 Type* Typer::Visitor::TypeNumberSqrt(Node* node) { return Type::Number(); }
1845
1846 Type* Typer::Visitor::TypeNumberTan(Node* node) { return Type::Number(); }
1847
1848 Type* Typer::Visitor::TypeNumberTanh(Node* node) { return Type::Number(); }
1849
1850 Type* Typer::Visitor::TypeNumberTrunc(Node* node) {
1851 return TypeUnaryOp(node, NumberTrunc);
1852 }
1853
1854 Type* Typer::Visitor::TypeNumberToInt32(Node* node) {
1855 return TypeUnaryOp(node, NumberToInt32);
1856 }
1857
1858
1859 Type* Typer::Visitor::TypeNumberToUint32(Node* node) {
1860 return TypeUnaryOp(node, NumberToUint32);
1861 }
1862
1863
1864 // static 1456 // static
1865 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) { 1457 Type* Typer::Visitor::ReferenceEqualTyper(Type* lhs, Type* rhs, Typer* t) {
1866 if (lhs->IsConstant() && rhs->Is(lhs)) { 1458 if (lhs->IsConstant() && rhs->Is(lhs)) {
1867 return t->singleton_true_; 1459 return t->singleton_true_;
1868 } 1460 }
1869 return Type::Boolean(); 1461 return Type::Boolean();
1870 } 1462 }
1871 1463
1872 1464
1873 Type* Typer::Visitor::TypeReferenceEqual(Node* node) { 1465 Type* Typer::Visitor::TypeReferenceEqual(Node* node) {
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
2264 1856
2265 Type* Typer::Visitor::TypeChangeFloat32ToFloat64(Node* node) { 1857 Type* Typer::Visitor::TypeChangeFloat32ToFloat64(Node* node) {
2266 return Type::Intersect(Type::Number(), Type::UntaggedFloat64(), zone()); 1858 return Type::Intersect(Type::Number(), Type::UntaggedFloat64(), zone());
2267 } 1859 }
2268 1860
2269 1861
2270 Type* Typer::Visitor::TypeChangeFloat64ToInt32(Node* node) { 1862 Type* Typer::Visitor::TypeChangeFloat64ToInt32(Node* node) {
2271 return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone()); 1863 return Type::Intersect(Type::Signed32(), Type::UntaggedIntegral32(), zone());
2272 } 1864 }
2273 1865
2274 Type* Typer::Visitor::TypeNumberSilenceNaN(Node* node) {
2275 return Type::Number();
2276 }
2277
2278 Type* Typer::Visitor::TypeChangeFloat64ToUint32(Node* node) { 1866 Type* Typer::Visitor::TypeChangeFloat64ToUint32(Node* node) {
2279 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(), 1867 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(),
2280 zone()); 1868 zone());
2281 } 1869 }
2282 1870
2283 Type* Typer::Visitor::TypeTruncateFloat64ToUint32(Node* node) { 1871 Type* Typer::Visitor::TypeTruncateFloat64ToUint32(Node* node) {
2284 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(), 1872 return Type::Intersect(Type::Unsigned32(), Type::UntaggedIntegral32(),
2285 zone()); 1873 zone());
2286 } 1874 }
2287 1875
(...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after
2704 } 2292 }
2705 if (Type::IsInteger(*value)) { 2293 if (Type::IsInteger(*value)) {
2706 return Type::Range(value->Number(), value->Number(), zone()); 2294 return Type::Range(value->Number(), value->Number(), zone());
2707 } 2295 }
2708 return Type::Constant(value, zone()); 2296 return Type::Constant(value, zone());
2709 } 2297 }
2710 2298
2711 } // namespace compiler 2299 } // namespace compiler
2712 } // namespace internal 2300 } // namespace internal
2713 } // namespace v8 2301 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/typer.h ('k') | src/type-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698