| 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 |