OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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/operation-typer.h" | 5 #include "src/compiler/operation-typer.h" |
6 | 6 |
7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
8 #include "src/compiler/type-cache.h" | 8 #include "src/compiler/type-cache.h" |
9 #include "src/compiler/types.h" | 9 #include "src/compiler/types.h" |
10 #include "src/factory.h" | 10 #include "src/factory.h" |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
359 } | 359 } |
360 | 360 |
361 Type* OperationTyper::NumberExpm1(Type* type) { | 361 Type* OperationTyper::NumberExpm1(Type* type) { |
362 DCHECK(type->Is(Type::Number())); | 362 DCHECK(type->Is(Type::Number())); |
363 return Type::Union(Type::PlainNumber(), Type::NaN(), zone()); | 363 return Type::Union(Type::PlainNumber(), Type::NaN(), zone()); |
364 } | 364 } |
365 | 365 |
366 Type* OperationTyper::NumberFloor(Type* type) { | 366 Type* OperationTyper::NumberFloor(Type* type) { |
367 DCHECK(type->Is(Type::Number())); | 367 DCHECK(type->Is(Type::Number())); |
368 if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type; | 368 if (type->Is(cache_.kIntegerOrMinusZeroOrNaN)) return type; |
369 // TODO(bmeurer): We could infer a more precise type here. | 369 type = Type::Intersect(type, Type::MinusZeroOrNaN(), zone()); |
370 return cache_.kIntegerOrMinusZeroOrNaN; | 370 type = Type::Union(type, cache_.kInteger, zone()); |
| 371 return type; |
371 } | 372 } |
372 | 373 |
373 Type* OperationTyper::NumberFround(Type* type) { | 374 Type* OperationTyper::NumberFround(Type* type) { |
374 DCHECK(type->Is(Type::Number())); | 375 DCHECK(type->Is(Type::Number())); |
375 return Type::Number(); | 376 return Type::Number(); |
376 } | 377 } |
377 | 378 |
378 Type* OperationTyper::NumberLog(Type* type) { | 379 Type* OperationTyper::NumberLog(Type* type) { |
379 DCHECK(type->Is(Type::Number())); | 380 DCHECK(type->Is(Type::Number())); |
380 return Type::Number(); | 381 return Type::Number(); |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 | 618 |
618 Type* OperationTyper::NumberDivide(Type* lhs, Type* rhs) { | 619 Type* OperationTyper::NumberDivide(Type* lhs, Type* rhs) { |
619 DCHECK(lhs->Is(Type::Number())); | 620 DCHECK(lhs->Is(Type::Number())); |
620 DCHECK(rhs->Is(Type::Number())); | 621 DCHECK(rhs->Is(Type::Number())); |
621 | 622 |
622 if (!lhs->IsInhabited() || !rhs->IsInhabited()) { | 623 if (!lhs->IsInhabited() || !rhs->IsInhabited()) { |
623 return Type::None(); | 624 return Type::None(); |
624 } | 625 } |
625 | 626 |
626 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); | 627 if (lhs->Is(Type::NaN()) || rhs->Is(Type::NaN())) return Type::NaN(); |
627 // Division is tricky, so all we do is try ruling out nan. | 628 // Division is tricky, so all we do is try ruling out -0 and NaN. |
| 629 bool maybe_minuszero = !lhs->Is(cache_.kPositiveIntegerOrNaN) || |
| 630 !rhs->Is(cache_.kPositiveIntegerOrNaN); |
628 bool maybe_nan = | 631 bool maybe_nan = |
629 lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) || | 632 lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) || |
630 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && | 633 ((lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY) && |
631 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); | 634 (rhs->Min() == -V8_INFINITY || rhs->Max() == +V8_INFINITY)); |
632 return maybe_nan ? Type::Number() : Type::OrderedNumber(); | 635 |
| 636 // Take into account the -0 and NaN information computed earlier. |
| 637 Type* type = Type::PlainNumber(); |
| 638 if (maybe_minuszero) type = Type::Union(type, Type::MinusZero(), zone()); |
| 639 if (maybe_nan) type = Type::Union(type, Type::NaN(), zone()); |
| 640 return type; |
633 } | 641 } |
634 | 642 |
635 Type* OperationTyper::NumberModulus(Type* lhs, Type* rhs) { | 643 Type* OperationTyper::NumberModulus(Type* lhs, Type* rhs) { |
636 DCHECK(lhs->Is(Type::Number())); | 644 DCHECK(lhs->Is(Type::Number())); |
637 DCHECK(rhs->Is(Type::Number())); | 645 DCHECK(rhs->Is(Type::Number())); |
638 | 646 |
639 // Modulus can yield NaN if either {lhs} or {rhs} are NaN, or | 647 // Modulus can yield NaN if either {lhs} or {rhs} are NaN, or |
640 // {lhs} is not finite, or the {rhs} is a zero value. | 648 // {lhs} is not finite, or the {rhs} is a zero value. |
641 bool maybe_nan = lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) || | 649 bool maybe_nan = lhs->Maybe(Type::NaN()) || rhs->Maybe(cache_.kZeroish) || |
642 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY; | 650 lhs->Min() == -V8_INFINITY || lhs->Max() == +V8_INFINITY; |
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 return singleton_true(); | 992 return singleton_true(); |
985 } | 993 } |
986 | 994 |
987 Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) { | 995 Type* OperationTyper::TypeTypeGuard(const Operator* sigma_op, Type* input) { |
988 return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone()); | 996 return Type::Intersect(input, TypeGuardTypeOf(sigma_op), zone()); |
989 } | 997 } |
990 | 998 |
991 } // namespace compiler | 999 } // namespace compiler |
992 } // namespace internal | 1000 } // namespace internal |
993 } // namespace v8 | 1001 } // namespace v8 |
OLD | NEW |