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