OLD | NEW |
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/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
6 | 6 |
7 #include "src/assembler.h" | 7 #include "src/assembler.h" |
8 #include "src/base/lazy-instance.h" | 8 #include "src/base/lazy-instance.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/compiler/node.h" | 10 #include "src/compiler/node.h" |
(...skipping 19 matching lines...) Expand all Loading... |
30 UNREACHABLE(); | 30 UNREACHABLE(); |
31 return os; | 31 return os; |
32 } | 32 } |
33 | 33 |
34 | 34 |
35 BranchHint BranchHintOf(const Operator* const op) { | 35 BranchHint BranchHintOf(const Operator* const op) { |
36 DCHECK_EQ(IrOpcode::kBranch, op->opcode()); | 36 DCHECK_EQ(IrOpcode::kBranch, op->opcode()); |
37 return OpParameter<BranchHint>(op); | 37 return OpParameter<BranchHint>(op); |
38 } | 38 } |
39 | 39 |
40 DeoptimizeReason DeoptimizeReasonOf(Operator const* const op) { | |
41 DCHECK(op->opcode() == IrOpcode::kDeoptimizeIf || | |
42 op->opcode() == IrOpcode::kDeoptimizeUnless); | |
43 return OpParameter<DeoptimizeReason>(op); | |
44 } | |
45 | |
46 int ValueInputCountOfReturn(Operator const* const op) { | 40 int ValueInputCountOfReturn(Operator const* const op) { |
47 DCHECK(op->opcode() == IrOpcode::kReturn); | 41 DCHECK(op->opcode() == IrOpcode::kReturn); |
48 // Return nodes have a hidden input at index 0 which we ignore in the value | 42 // Return nodes have a hidden input at index 0 which we ignore in the value |
49 // input count. | 43 // input count. |
50 return op->ValueInputCount() - 1; | 44 return op->ValueInputCount() - 1; |
51 } | 45 } |
52 | 46 |
53 size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); } | |
54 | |
55 std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) { | |
56 switch (kind) { | |
57 case DeoptimizeKind::kEager: | |
58 return os << "Eager"; | |
59 case DeoptimizeKind::kSoft: | |
60 return os << "Soft"; | |
61 } | |
62 UNREACHABLE(); | |
63 return os; | |
64 } | |
65 | |
66 bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { | 47 bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { |
67 return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason(); | 48 return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason(); |
68 } | 49 } |
69 | 50 |
70 bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { | 51 bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) { |
71 return !(lhs == rhs); | 52 return !(lhs == rhs); |
72 } | 53 } |
73 | 54 |
74 size_t hash_value(DeoptimizeParameters p) { | 55 size_t hash_value(DeoptimizeParameters p) { |
75 return base::hash_combine(p.kind(), p.reason()); | 56 return base::hash_combine(p.kind(), p.reason()); |
76 } | 57 } |
77 | 58 |
78 std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) { | 59 std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) { |
79 return os << p.kind() << ":" << p.reason(); | 60 return os << p.kind() << ":" << p.reason(); |
80 } | 61 } |
81 | 62 |
82 DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const op) { | 63 DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const op) { |
83 DCHECK_EQ(IrOpcode::kDeoptimize, op->opcode()); | 64 DCHECK(op->opcode() == IrOpcode::kDeoptimize || |
| 65 op->opcode() == IrOpcode::kDeoptimizeIf || |
| 66 op->opcode() == IrOpcode::kDeoptimizeUnless); |
84 return OpParameter<DeoptimizeParameters>(op); | 67 return OpParameter<DeoptimizeParameters>(op); |
85 } | 68 } |
86 | 69 |
87 | 70 |
88 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) { | 71 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) { |
89 return lhs.representation() == rhs.representation() && | 72 return lhs.representation() == rhs.representation() && |
90 lhs.hint() == rhs.hint(); | 73 lhs.hint() == rhs.hint(); |
91 } | 74 } |
92 | 75 |
93 | 76 |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 V(8) | 412 V(8) |
430 | 413 |
431 #define CACHED_DEOPTIMIZE_LIST(V) \ | 414 #define CACHED_DEOPTIMIZE_LIST(V) \ |
432 V(Eager, MinusZero) \ | 415 V(Eager, MinusZero) \ |
433 V(Eager, NoReason) \ | 416 V(Eager, NoReason) \ |
434 V(Eager, WrongMap) \ | 417 V(Eager, WrongMap) \ |
435 V(Soft, InsufficientTypeFeedbackForGenericKeyedAccess) \ | 418 V(Soft, InsufficientTypeFeedbackForGenericKeyedAccess) \ |
436 V(Soft, InsufficientTypeFeedbackForGenericNamedAccess) | 419 V(Soft, InsufficientTypeFeedbackForGenericNamedAccess) |
437 | 420 |
438 #define CACHED_DEOPTIMIZE_IF_LIST(V) \ | 421 #define CACHED_DEOPTIMIZE_IF_LIST(V) \ |
439 V(DivisionByZero) \ | 422 V(Eager, DivisionByZero) \ |
440 V(Hole) \ | 423 V(Eager, Hole) \ |
441 V(MinusZero) \ | 424 V(Eager, MinusZero) \ |
442 V(Overflow) \ | 425 V(Eager, Overflow) \ |
443 V(Smi) | 426 V(Eager, Smi) |
444 | 427 |
445 #define CACHED_DEOPTIMIZE_UNLESS_LIST(V) \ | 428 #define CACHED_DEOPTIMIZE_UNLESS_LIST(V) \ |
446 V(LostPrecision) \ | 429 V(Eager, LostPrecision) \ |
447 V(LostPrecisionOrNaN) \ | 430 V(Eager, LostPrecisionOrNaN) \ |
448 V(NoReason) \ | 431 V(Eager, NoReason) \ |
449 V(NotAHeapNumber) \ | 432 V(Eager, NotAHeapNumber) \ |
450 V(NotANumberOrOddball) \ | 433 V(Eager, NotANumberOrOddball) \ |
451 V(NotASmi) \ | 434 V(Eager, NotASmi) \ |
452 V(OutOfBounds) \ | 435 V(Eager, OutOfBounds) \ |
453 V(WrongInstanceType) \ | 436 V(Eager, WrongInstanceType) \ |
454 V(WrongMap) | 437 V(Eager, WrongMap) |
455 | 438 |
456 #define CACHED_TRAP_IF_LIST(V) \ | 439 #define CACHED_TRAP_IF_LIST(V) \ |
457 V(TrapDivUnrepresentable) \ | 440 V(TrapDivUnrepresentable) \ |
458 V(TrapFloatUnrepresentable) | 441 V(TrapFloatUnrepresentable) |
459 | 442 |
460 // The reason for a trap. | 443 // The reason for a trap. |
461 #define CACHED_TRAP_UNLESS_LIST(V) \ | 444 #define CACHED_TRAP_UNLESS_LIST(V) \ |
462 V(TrapUnreachable) \ | 445 V(TrapUnreachable) \ |
463 V(TrapMemOutOfBounds) \ | 446 V(TrapMemOutOfBounds) \ |
464 V(TrapDivByZero) \ | 447 V(TrapDivByZero) \ |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 "Deoptimize", // name | 611 "Deoptimize", // name |
629 1, 1, 1, 0, 0, 1, // counts | 612 1, 1, 1, 0, 0, 1, // counts |
630 DeoptimizeParameters(kKind, kReason)) {} // parameter | 613 DeoptimizeParameters(kKind, kReason)) {} // parameter |
631 }; | 614 }; |
632 #define CACHED_DEOPTIMIZE(Kind, Reason) \ | 615 #define CACHED_DEOPTIMIZE(Kind, Reason) \ |
633 DeoptimizeOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \ | 616 DeoptimizeOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \ |
634 kDeoptimize##Kind##Reason##Operator; | 617 kDeoptimize##Kind##Reason##Operator; |
635 CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE) | 618 CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE) |
636 #undef CACHED_DEOPTIMIZE | 619 #undef CACHED_DEOPTIMIZE |
637 | 620 |
638 template <DeoptimizeReason kReason> | 621 template <DeoptimizeKind kKind, DeoptimizeReason kReason> |
639 struct DeoptimizeIfOperator final : public Operator1<DeoptimizeReason> { | 622 struct DeoptimizeIfOperator final : public Operator1<DeoptimizeParameters> { |
640 DeoptimizeIfOperator() | 623 DeoptimizeIfOperator() |
641 : Operator1<DeoptimizeReason>( // -- | 624 : Operator1<DeoptimizeParameters>( // -- |
642 IrOpcode::kDeoptimizeIf, // opcode | 625 IrOpcode::kDeoptimizeIf, // opcode |
643 Operator::kFoldable | Operator::kNoThrow, // properties | 626 Operator::kFoldable | Operator::kNoThrow, // properties |
644 "DeoptimizeIf", // name | 627 "DeoptimizeIf", // name |
645 2, 1, 1, 0, 1, 1, // counts | 628 2, 1, 1, 0, 1, 1, // counts |
646 kReason) {} // parameter | 629 DeoptimizeParameters(kKind, kReason)) {} // parameter |
647 }; | 630 }; |
648 #define CACHED_DEOPTIMIZE_IF(Reason) \ | 631 #define CACHED_DEOPTIMIZE_IF(Kind, Reason) \ |
649 DeoptimizeIfOperator<DeoptimizeReason::k##Reason> \ | 632 DeoptimizeIfOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \ |
650 kDeoptimizeIf##Reason##Operator; | 633 kDeoptimizeIf##Kind##Reason##Operator; |
651 CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF) | 634 CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF) |
652 #undef CACHED_DEOPTIMIZE_IF | 635 #undef CACHED_DEOPTIMIZE_IF |
653 | 636 |
654 template <DeoptimizeReason kReason> | 637 template <DeoptimizeKind kKind, DeoptimizeReason kReason> |
655 struct DeoptimizeUnlessOperator final : public Operator1<DeoptimizeReason> { | 638 struct DeoptimizeUnlessOperator final |
| 639 : public Operator1<DeoptimizeParameters> { |
656 DeoptimizeUnlessOperator() | 640 DeoptimizeUnlessOperator() |
657 : Operator1<DeoptimizeReason>( // -- | 641 : Operator1<DeoptimizeParameters>( // -- |
658 IrOpcode::kDeoptimizeUnless, // opcode | 642 IrOpcode::kDeoptimizeUnless, // opcode |
659 Operator::kFoldable | Operator::kNoThrow, // properties | 643 Operator::kFoldable | Operator::kNoThrow, // properties |
660 "DeoptimizeUnless", // name | 644 "DeoptimizeUnless", // name |
661 2, 1, 1, 0, 1, 1, // counts | 645 2, 1, 1, 0, 1, 1, // counts |
662 kReason) {} // parameter | 646 DeoptimizeParameters(kKind, kReason)) {} // parameter |
663 }; | 647 }; |
664 #define CACHED_DEOPTIMIZE_UNLESS(Reason) \ | 648 #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \ |
665 DeoptimizeUnlessOperator<DeoptimizeReason::k##Reason> \ | 649 DeoptimizeUnlessOperator<DeoptimizeKind::k##Kind, \ |
666 kDeoptimizeUnless##Reason##Operator; | 650 DeoptimizeReason::k##Reason> \ |
| 651 kDeoptimizeUnless##Kind##Reason##Operator; |
667 CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS) | 652 CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS) |
668 #undef CACHED_DEOPTIMIZE_UNLESS | 653 #undef CACHED_DEOPTIMIZE_UNLESS |
669 | 654 |
670 template <int32_t trap_id> | 655 template <int32_t trap_id> |
671 struct TrapIfOperator final : public Operator1<int32_t> { | 656 struct TrapIfOperator final : public Operator1<int32_t> { |
672 TrapIfOperator() | 657 TrapIfOperator() |
673 : Operator1<int32_t>( // -- | 658 : Operator1<int32_t>( // -- |
674 IrOpcode::kTrapIf, // opcode | 659 IrOpcode::kTrapIf, // opcode |
675 Operator::kFoldable | Operator::kNoThrow, // properties | 660 Operator::kFoldable | Operator::kNoThrow, // properties |
676 "TrapIf", // name | 661 "TrapIf", // name |
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
852 // Uncached | 837 // Uncached |
853 DeoptimizeParameters parameter(kind, reason); | 838 DeoptimizeParameters parameter(kind, reason); |
854 return new (zone()) Operator1<DeoptimizeParameters>( // -- | 839 return new (zone()) Operator1<DeoptimizeParameters>( // -- |
855 IrOpcode::kDeoptimize, // opcodes | 840 IrOpcode::kDeoptimize, // opcodes |
856 Operator::kFoldable | Operator::kNoThrow, // properties | 841 Operator::kFoldable | Operator::kNoThrow, // properties |
857 "Deoptimize", // name | 842 "Deoptimize", // name |
858 1, 1, 1, 0, 0, 1, // counts | 843 1, 1, 1, 0, 0, 1, // counts |
859 parameter); // parameter | 844 parameter); // parameter |
860 } | 845 } |
861 | 846 |
862 const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeReason reason) { | 847 const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeKind kind, |
863 switch (reason) { | 848 DeoptimizeReason reason) { |
864 #define CACHED_DEOPTIMIZE_IF(Reason) \ | 849 #define CACHED_DEOPTIMIZE_IF(Kind, Reason) \ |
865 case DeoptimizeReason::k##Reason: \ | 850 if (kind == DeoptimizeKind::k##Kind && \ |
866 return &cache_.kDeoptimizeIf##Reason##Operator; | 851 reason == DeoptimizeReason::k##Reason) { \ |
867 CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF) | 852 return &cache_.kDeoptimizeIf##Kind##Reason##Operator; \ |
| 853 } |
| 854 CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF) |
868 #undef CACHED_DEOPTIMIZE_IF | 855 #undef CACHED_DEOPTIMIZE_IF |
869 default: | |
870 break; | |
871 } | |
872 // Uncached | 856 // Uncached |
873 return new (zone()) Operator1<DeoptimizeReason>( // -- | 857 DeoptimizeParameters parameter(kind, reason); |
874 IrOpcode::kDeoptimizeIf, // opcode | 858 return new (zone()) Operator1<DeoptimizeParameters>( // -- |
875 Operator::kFoldable | Operator::kNoThrow, // properties | 859 IrOpcode::kDeoptimizeIf, // opcode |
876 "DeoptimizeIf", // name | 860 Operator::kFoldable | Operator::kNoThrow, // properties |
877 2, 1, 1, 0, 1, 1, // counts | 861 "DeoptimizeIf", // name |
878 reason); // parameter | 862 2, 1, 1, 0, 1, 1, // counts |
| 863 parameter); // parameter |
879 } | 864 } |
880 | 865 |
881 const Operator* CommonOperatorBuilder::DeoptimizeUnless( | 866 const Operator* CommonOperatorBuilder::DeoptimizeUnless( |
882 DeoptimizeReason reason) { | 867 DeoptimizeKind kind, DeoptimizeReason reason) { |
883 switch (reason) { | 868 #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \ |
884 #define CACHED_DEOPTIMIZE_UNLESS(Reason) \ | 869 if (kind == DeoptimizeKind::k##Kind && \ |
885 case DeoptimizeReason::k##Reason: \ | 870 reason == DeoptimizeReason::k##Reason) { \ |
886 return &cache_.kDeoptimizeUnless##Reason##Operator; | 871 return &cache_.kDeoptimizeUnless##Kind##Reason##Operator; \ |
887 CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS) | 872 } |
| 873 CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS) |
888 #undef CACHED_DEOPTIMIZE_UNLESS | 874 #undef CACHED_DEOPTIMIZE_UNLESS |
889 default: | |
890 break; | |
891 } | |
892 // Uncached | 875 // Uncached |
893 return new (zone()) Operator1<DeoptimizeReason>( // -- | 876 DeoptimizeParameters parameter(kind, reason); |
894 IrOpcode::kDeoptimizeUnless, // opcode | 877 return new (zone()) Operator1<DeoptimizeParameters>( // -- |
895 Operator::kFoldable | Operator::kNoThrow, // properties | 878 IrOpcode::kDeoptimizeUnless, // opcode |
896 "DeoptimizeUnless", // name | 879 Operator::kFoldable | Operator::kNoThrow, // properties |
897 2, 1, 1, 0, 1, 1, // counts | 880 "DeoptimizeUnless", // name |
898 reason); // parameter | 881 2, 1, 1, 0, 1, 1, // counts |
| 882 parameter); // parameter |
899 } | 883 } |
900 | 884 |
901 const Operator* CommonOperatorBuilder::TrapIf(int32_t trap_id) { | 885 const Operator* CommonOperatorBuilder::TrapIf(int32_t trap_id) { |
902 switch (trap_id) { | 886 switch (trap_id) { |
903 #define CACHED_TRAP_IF(Trap) \ | 887 #define CACHED_TRAP_IF(Trap) \ |
904 case Runtime::kThrowWasm##Trap: \ | 888 case Runtime::kThrowWasm##Trap: \ |
905 return &cache_.kTrapIf##Trap##Operator; | 889 return &cache_.kTrapIf##Trap##Operator; |
906 CACHED_TRAP_IF_LIST(CACHED_TRAP_IF) | 890 CACHED_TRAP_IF_LIST(CACHED_TRAP_IF) |
907 #undef CACHED_TRAP_IF | 891 #undef CACHED_TRAP_IF |
908 default: | 892 default: |
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1364 CommonOperatorBuilder::CreateFrameStateFunctionInfo( | 1348 CommonOperatorBuilder::CreateFrameStateFunctionInfo( |
1365 FrameStateType type, int parameter_count, int local_count, | 1349 FrameStateType type, int parameter_count, int local_count, |
1366 Handle<SharedFunctionInfo> shared_info) { | 1350 Handle<SharedFunctionInfo> shared_info) { |
1367 return new (zone()->New(sizeof(FrameStateFunctionInfo))) | 1351 return new (zone()->New(sizeof(FrameStateFunctionInfo))) |
1368 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info); | 1352 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info); |
1369 } | 1353 } |
1370 | 1354 |
1371 } // namespace compiler | 1355 } // namespace compiler |
1372 } // namespace internal | 1356 } // namespace internal |
1373 } // namespace v8 | 1357 } // namespace v8 |
OLD | NEW |