OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 #ifndef V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 5 #ifndef V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |
6 #define V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 6 #define V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |
7 | 7 |
8 #include <cstring> | 8 #include <cstring> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 | 10 |
(...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 type_(type), | 478 type_(type), |
479 use_list_(NULL), | 479 use_list_(NULL), |
480 range_(NULL), | 480 range_(NULL), |
481 #ifdef DEBUG | 481 #ifdef DEBUG |
482 range_poisoned_(false), | 482 range_poisoned_(false), |
483 #endif | 483 #endif |
484 flags_(0) {} | 484 flags_(0) {} |
485 virtual ~HValue() {} | 485 virtual ~HValue() {} |
486 | 486 |
487 virtual SourcePosition position() const { return SourcePosition::Unknown(); } | 487 virtual SourcePosition position() const { return SourcePosition::Unknown(); } |
488 virtual SourcePosition operand_position(int index) const { | |
489 return position(); | |
490 } | |
491 | 488 |
492 HBasicBlock* block() const { return block_; } | 489 HBasicBlock* block() const { return block_; } |
493 void SetBlock(HBasicBlock* block); | 490 void SetBlock(HBasicBlock* block); |
494 | 491 |
495 // Note: Never call this method for an unlinked value. | 492 // Note: Never call this method for an unlinked value. |
496 Isolate* isolate() const; | 493 Isolate* isolate() const; |
497 | 494 |
498 int id() const { return id_; } | 495 int id() const { return id_; } |
499 void set_id(int id) { id_ = id; } | 496 void set_id(int id) { id_ = id; } |
500 | 497 |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 P3 p3, P4 p4, P5 p5) { \ | 937 P3 p3, P4 p4, P5 p5) { \ |
941 return new (zone) I(context, p1, p2, p3, p4, p5); \ | 938 return new (zone) I(context, p1, p2, p3, p4, p5); \ |
942 } | 939 } |
943 | 940 |
944 #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P6(I, P1, P2, P3, P4, P5, P6) \ | 941 #define DECLARE_INSTRUCTION_WITH_CONTEXT_FACTORY_P6(I, P1, P2, P3, P4, P5, P6) \ |
945 static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \ | 942 static I* New(Isolate* isolate, Zone* zone, HValue* context, P1 p1, P2 p2, \ |
946 P3 p3, P4 p4, P5 p5, P6 p6) { \ | 943 P3 p3, P4 p4, P5 p5, P6 p6) { \ |
947 return new (zone) I(context, p1, p2, p3, p4, p5, p6); \ | 944 return new (zone) I(context, p1, p2, p3, p4, p5, p6); \ |
948 } | 945 } |
949 | 946 |
950 | |
951 // A helper class to represent per-operand position information attached to | |
952 // the HInstruction in the compact form. Uses tagging to distinguish between | |
953 // case when only instruction's position is available and case when operands' | |
954 // positions are also available. | |
955 // In the first case it contains intruction's position as a tagged value. | |
956 // In the second case it points to an array which contains instruction's | |
957 // position and operands' positions. | |
958 class HPositionInfo { | |
959 public: | |
960 explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { } | |
961 | |
962 SourcePosition position() const { | |
963 if (has_operand_positions()) { | |
964 return operand_positions()[kInstructionPosIndex]; | |
965 } | |
966 return SourcePosition::FromRaw(static_cast<int>(UntagPosition(data_))); | |
967 } | |
968 | |
969 void set_position(SourcePosition pos) { | |
970 if (has_operand_positions()) { | |
971 operand_positions()[kInstructionPosIndex] = pos; | |
972 } else { | |
973 data_ = TagPosition(pos.raw()); | |
974 } | |
975 } | |
976 | |
977 void ensure_storage_for_operand_positions(Zone* zone, int operand_count) { | |
978 if (has_operand_positions()) { | |
979 return; | |
980 } | |
981 | |
982 const int length = kFirstOperandPosIndex + operand_count; | |
983 SourcePosition* positions = zone->NewArray<SourcePosition>(length); | |
984 for (int i = 0; i < length; i++) { | |
985 positions[i] = SourcePosition::Unknown(); | |
986 } | |
987 | |
988 const SourcePosition pos = position(); | |
989 data_ = reinterpret_cast<intptr_t>(positions); | |
990 set_position(pos); | |
991 | |
992 DCHECK(has_operand_positions()); | |
993 } | |
994 | |
995 SourcePosition operand_position(int idx) const { | |
996 if (!has_operand_positions()) { | |
997 return position(); | |
998 } | |
999 return *operand_position_slot(idx); | |
1000 } | |
1001 | |
1002 void set_operand_position(int idx, SourcePosition pos) { | |
1003 *operand_position_slot(idx) = pos; | |
1004 } | |
1005 | |
1006 private: | |
1007 static const intptr_t kInstructionPosIndex = 0; | |
1008 static const intptr_t kFirstOperandPosIndex = 1; | |
1009 | |
1010 SourcePosition* operand_position_slot(int idx) const { | |
1011 DCHECK(has_operand_positions()); | |
1012 return &(operand_positions()[kFirstOperandPosIndex + idx]); | |
1013 } | |
1014 | |
1015 bool has_operand_positions() const { | |
1016 return !IsTaggedPosition(data_); | |
1017 } | |
1018 | |
1019 SourcePosition* operand_positions() const { | |
1020 DCHECK(has_operand_positions()); | |
1021 return reinterpret_cast<SourcePosition*>(data_); | |
1022 } | |
1023 | |
1024 static const intptr_t kPositionTag = 1; | |
1025 static const intptr_t kPositionShift = 1; | |
1026 static bool IsTaggedPosition(intptr_t val) { | |
1027 return (val & kPositionTag) != 0; | |
1028 } | |
1029 static intptr_t UntagPosition(intptr_t val) { | |
1030 DCHECK(IsTaggedPosition(val)); | |
1031 return val >> kPositionShift; | |
1032 } | |
1033 static intptr_t TagPosition(intptr_t val) { | |
1034 const intptr_t result = (val << kPositionShift) | kPositionTag; | |
1035 DCHECK(UntagPosition(result) == val); | |
1036 return result; | |
1037 } | |
1038 | |
1039 intptr_t data_; | |
1040 }; | |
1041 | |
1042 | |
1043 class HInstruction : public HValue { | 947 class HInstruction : public HValue { |
1044 public: | 948 public: |
1045 HInstruction* next() const { return next_; } | 949 HInstruction* next() const { return next_; } |
1046 HInstruction* previous() const { return previous_; } | 950 HInstruction* previous() const { return previous_; } |
1047 | 951 |
1048 std::ostream& PrintTo(std::ostream& os) const override; // NOLINT | 952 std::ostream& PrintTo(std::ostream& os) const override; // NOLINT |
1049 virtual std::ostream& PrintDataTo(std::ostream& os) const; // NOLINT | 953 virtual std::ostream& PrintDataTo(std::ostream& os) const; // NOLINT |
1050 | 954 |
1051 bool IsLinked() const { return block() != NULL; } | 955 bool IsLinked() const { return block() != NULL; } |
1052 void Unlink(); | 956 void Unlink(); |
1053 | 957 |
1054 void InsertBefore(HInstruction* next); | 958 void InsertBefore(HInstruction* next); |
1055 | 959 |
1056 template<class T> T* Prepend(T* instr) { | 960 template<class T> T* Prepend(T* instr) { |
1057 instr->InsertBefore(this); | 961 instr->InsertBefore(this); |
1058 return instr; | 962 return instr; |
1059 } | 963 } |
1060 | 964 |
1061 void InsertAfter(HInstruction* previous); | 965 void InsertAfter(HInstruction* previous); |
1062 | 966 |
1063 template<class T> T* Append(T* instr) { | 967 template<class T> T* Append(T* instr) { |
1064 instr->InsertAfter(this); | 968 instr->InsertAfter(this); |
1065 return instr; | 969 return instr; |
1066 } | 970 } |
1067 | 971 |
1068 // The position is a write-once variable. | 972 // The position is a write-once variable. |
1069 SourcePosition position() const override { | 973 SourcePosition position() const override { return position_; } |
1070 return SourcePosition(position_.position()); | 974 bool has_position() const { return position_.IsKnown(); } |
1071 } | |
1072 bool has_position() const { | |
1073 return !position().IsUnknown(); | |
1074 } | |
1075 void set_position(SourcePosition position) { | 975 void set_position(SourcePosition position) { |
1076 DCHECK(!has_position()); | 976 DCHECK(position.IsKnown()); |
1077 DCHECK(!position.IsUnknown()); | 977 position_ = position; |
1078 position_.set_position(position); | |
1079 } | |
1080 | |
1081 SourcePosition operand_position(int index) const override { | |
1082 const SourcePosition pos = position_.operand_position(index); | |
1083 return pos.IsUnknown() ? position() : pos; | |
1084 } | |
1085 void set_operand_position(Zone* zone, int index, SourcePosition pos) { | |
1086 DCHECK(0 <= index && index < OperandCount()); | |
1087 position_.ensure_storage_for_operand_positions(zone, OperandCount()); | |
1088 position_.set_operand_position(index, pos); | |
1089 } | 978 } |
1090 | 979 |
1091 bool Dominates(HInstruction* other); | 980 bool Dominates(HInstruction* other); |
1092 bool CanTruncateToSmi() const { return CheckFlag(kTruncatingToSmi); } | 981 bool CanTruncateToSmi() const { return CheckFlag(kTruncatingToSmi); } |
1093 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } | 982 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } |
1094 bool CanTruncateToNumber() const { return CheckFlag(kTruncatingToNumber); } | 983 bool CanTruncateToNumber() const { return CheckFlag(kTruncatingToNumber); } |
1095 | 984 |
1096 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; | 985 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; |
1097 | 986 |
1098 #ifdef DEBUG | 987 #ifdef DEBUG |
1099 void Verify() override; | 988 void Verify() override; |
1100 #endif | 989 #endif |
1101 | 990 |
1102 bool CanDeoptimize(); | 991 bool CanDeoptimize(); |
1103 | 992 |
1104 virtual bool HasStackCheck() { return false; } | 993 virtual bool HasStackCheck() { return false; } |
1105 | 994 |
1106 DECLARE_ABSTRACT_INSTRUCTION(Instruction) | 995 DECLARE_ABSTRACT_INSTRUCTION(Instruction) |
1107 | 996 |
1108 protected: | 997 protected: |
1109 explicit HInstruction(HType type = HType::Tagged()) | 998 explicit HInstruction(HType type = HType::Tagged()) |
1110 : HValue(type), | 999 : HValue(type), |
1111 next_(NULL), | 1000 next_(NULL), |
1112 previous_(NULL), | 1001 previous_(NULL), |
1113 position_(kNoSourcePosition) { | 1002 position_(SourcePosition::Unknown()) { |
1114 SetDependsOnFlag(kOsrEntries); | 1003 SetDependsOnFlag(kOsrEntries); |
1115 } | 1004 } |
1116 | 1005 |
1117 void DeleteFromGraph() override { Unlink(); } | 1006 void DeleteFromGraph() override { Unlink(); } |
1118 | 1007 |
1119 private: | 1008 private: |
1120 void InitializeAsFirst(HBasicBlock* block) { | 1009 void InitializeAsFirst(HBasicBlock* block) { |
1121 DCHECK(!IsLinked()); | 1010 DCHECK(!IsLinked()); |
1122 SetBlock(block); | 1011 SetBlock(block); |
1123 } | 1012 } |
1124 | 1013 |
1125 HInstruction* next_; | 1014 HInstruction* next_; |
1126 HInstruction* previous_; | 1015 HInstruction* previous_; |
1127 HPositionInfo position_; | 1016 SourcePosition position_; |
1128 | 1017 |
1129 friend class HBasicBlock; | 1018 friend class HBasicBlock; |
1130 }; | 1019 }; |
1131 | 1020 |
1132 | 1021 |
1133 template<int V> | 1022 template<int V> |
1134 class HTemplateInstruction : public HInstruction { | 1023 class HTemplateInstruction : public HInstruction { |
1135 public: | 1024 public: |
1136 int OperandCount() const final { return V; } | 1025 int OperandCount() const final { return V; } |
1137 HValue* OperandAt(int i) const final { return inputs_[i]; } | 1026 HValue* OperandAt(int i) const final { return inputs_[i]; } |
(...skipping 776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1914 TailCallMode syntactic_tail_call_mode, Zone* zone) | 1803 TailCallMode syntactic_tail_call_mode, Zone* zone) |
1915 : return_id_(return_id), | 1804 : return_id_(return_id), |
1916 shared_(handle(closure->shared())), | 1805 shared_(handle(closure->shared())), |
1917 closure_(closure), | 1806 closure_(closure), |
1918 closure_context_(closure_context), | 1807 closure_context_(closure_context), |
1919 arguments_count_(arguments_count), | 1808 arguments_count_(arguments_count), |
1920 arguments_pushed_(false), | 1809 arguments_pushed_(false), |
1921 function_(function), | 1810 function_(function), |
1922 inlining_kind_(inlining_kind), | 1811 inlining_kind_(inlining_kind), |
1923 syntactic_tail_call_mode_(syntactic_tail_call_mode), | 1812 syntactic_tail_call_mode_(syntactic_tail_call_mode), |
1924 inlining_id_(0), | 1813 inlining_id_(-1), |
1925 arguments_var_(arguments_var), | 1814 arguments_var_(arguments_var), |
1926 arguments_object_(arguments_object), | 1815 arguments_object_(arguments_object), |
1927 return_targets_(2, zone) {} | 1816 return_targets_(2, zone) {} |
1928 | 1817 |
1929 BailoutId return_id_; | 1818 BailoutId return_id_; |
1930 Handle<SharedFunctionInfo> shared_; | 1819 Handle<SharedFunctionInfo> shared_; |
1931 Handle<JSFunction> closure_; | 1820 Handle<JSFunction> closure_; |
1932 HConstant* closure_context_; | 1821 HConstant* closure_context_; |
1933 int arguments_count_; | 1822 int arguments_count_; |
1934 bool arguments_pushed_; | 1823 bool arguments_pushed_; |
(...skipping 1533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3468 | 3357 |
3469 virtual bool IsCommutative() const { return false; } | 3358 virtual bool IsCommutative() const { return false; } |
3470 | 3359 |
3471 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT | 3360 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT |
3472 | 3361 |
3473 Representation RequiredInputRepresentation(int index) override { | 3362 Representation RequiredInputRepresentation(int index) override { |
3474 if (index == 0) return Representation::Tagged(); | 3363 if (index == 0) return Representation::Tagged(); |
3475 return representation(); | 3364 return representation(); |
3476 } | 3365 } |
3477 | 3366 |
3478 void SetOperandPositions(Zone* zone, SourcePosition left_pos, | |
3479 SourcePosition right_pos) { | |
3480 set_operand_position(zone, 1, left_pos); | |
3481 set_operand_position(zone, 2, right_pos); | |
3482 } | |
3483 | |
3484 bool RightIsPowerOf2() { | 3367 bool RightIsPowerOf2() { |
3485 if (!right()->IsInteger32Constant()) return false; | 3368 if (!right()->IsInteger32Constant()) return false; |
3486 int32_t value = right()->GetInteger32Constant(); | 3369 int32_t value = right()->GetInteger32Constant(); |
3487 if (value < 0) { | 3370 if (value < 0) { |
3488 return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(-value)); | 3371 return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(-value)); |
3489 } | 3372 } |
3490 return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(value)); | 3373 return base::bits::IsPowerOfTwo32(static_cast<uint32_t>(value)); |
3491 } | 3374 } |
3492 | 3375 |
3493 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) | 3376 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) |
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3885 return representation(); | 3768 return representation(); |
3886 } | 3769 } |
3887 Representation observed_input_representation(int index) override { | 3770 Representation observed_input_representation(int index) override { |
3888 return observed_input_representation_[index]; | 3771 return observed_input_representation_[index]; |
3889 } | 3772 } |
3890 | 3773 |
3891 bool KnownSuccessorBlock(HBasicBlock** block) override; | 3774 bool KnownSuccessorBlock(HBasicBlock** block) override; |
3892 | 3775 |
3893 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT | 3776 std::ostream& PrintDataTo(std::ostream& os) const override; // NOLINT |
3894 | 3777 |
3895 void SetOperandPositions(Zone* zone, SourcePosition left_pos, | |
3896 SourcePosition right_pos) { | |
3897 set_operand_position(zone, 0, left_pos); | |
3898 set_operand_position(zone, 1, right_pos); | |
3899 } | |
3900 | |
3901 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) | 3778 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) |
3902 | 3779 |
3903 private: | 3780 private: |
3904 HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token, | 3781 HCompareNumericAndBranch(HValue* left, HValue* right, Token::Value token, |
3905 HBasicBlock* true_target, HBasicBlock* false_target) | 3782 HBasicBlock* true_target, HBasicBlock* false_target) |
3906 : token_(token) { | 3783 : token_(token) { |
3907 SetFlag(kFlexibleRepresentation); | 3784 SetFlag(kFlexibleRepresentation); |
3908 DCHECK(Token::IsCompareOp(token)); | 3785 DCHECK(Token::IsCompareOp(token)); |
3909 SetOperandAt(0, left); | 3786 SetOperandAt(0, left); |
3910 SetOperandAt(1, right); | 3787 SetOperandAt(1, right); |
(...skipping 2971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6882 bool IsDeletable() const override { return true; } | 6759 bool IsDeletable() const override { return true; } |
6883 }; | 6760 }; |
6884 | 6761 |
6885 #undef DECLARE_INSTRUCTION | 6762 #undef DECLARE_INSTRUCTION |
6886 #undef DECLARE_CONCRETE_INSTRUCTION | 6763 #undef DECLARE_CONCRETE_INSTRUCTION |
6887 | 6764 |
6888 } // namespace internal | 6765 } // namespace internal |
6889 } // namespace v8 | 6766 } // namespace v8 |
6890 | 6767 |
6891 #endif // V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ | 6768 #endif // V8_CRANKSHAFT_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |