| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 539 | 539 |
| 540 HValue* base_; | 540 HValue* base_; |
| 541 int offset_; | 541 int offset_; |
| 542 int scale_; | 542 int scale_; |
| 543 }; | 543 }; |
| 544 | 544 |
| 545 | 545 |
| 546 typedef EnumSet<GVNFlag, int32_t> GVNFlagSet; | 546 typedef EnumSet<GVNFlag, int32_t> GVNFlagSet; |
| 547 | 547 |
| 548 | 548 |
| 549 // This class encapsulates encoding and decoding of sources positions from |
| 550 // which hydrogen values originated. |
| 551 // When FLAG_track_hydrogen_positions is set this object encodes the |
| 552 // identifier of the inlining and absolute offset from the start of the |
| 553 // inlined function. |
| 554 // When the flag is not set we simply track absolute offset from the |
| 555 // script start. |
| 556 class HSourcePosition { |
| 557 public: |
| 558 HSourcePosition(const HSourcePosition& other) : value_(other.value_) { } |
| 559 |
| 560 static HSourcePosition Unknown() { |
| 561 return HSourcePosition(RelocInfo::kNoPosition); |
| 562 } |
| 563 |
| 564 bool IsUnknown() const { return value_ == RelocInfo::kNoPosition; } |
| 565 |
| 566 int position() const { return PositionField::decode(value_); } |
| 567 void set_position(int position) { |
| 568 if (FLAG_hydrogen_track_positions) { |
| 569 value_ = static_cast<int>(PositionField::update(value_, position)); |
| 570 } else { |
| 571 value_ = position; |
| 572 } |
| 573 } |
| 574 |
| 575 int inlining_id() const { return InliningIdField::decode(value_); } |
| 576 void set_inlining_id(int inlining_id) { |
| 577 if (FLAG_hydrogen_track_positions) { |
| 578 value_ = static_cast<int>(InliningIdField::update(value_, inlining_id)); |
| 579 } |
| 580 } |
| 581 |
| 582 int raw() const { return value_; } |
| 583 |
| 584 void PrintTo(FILE* f); |
| 585 |
| 586 private: |
| 587 typedef BitField<int, 0, 9> InliningIdField; |
| 588 |
| 589 // Offset from the start of the inlined function. |
| 590 typedef BitField<int, 9, 22> PositionField; |
| 591 |
| 592 // On HPositionInfo can use this constructor. |
| 593 explicit HSourcePosition(int value) : value_(value) { } |
| 594 |
| 595 friend class HPositionInfo; |
| 596 |
| 597 // If FLAG_hydrogen_track_positions is set contains bitfields InliningIdField |
| 598 // and PositionField. |
| 599 // Otherwise contains absolute offset from the script start. |
| 600 int value_; |
| 601 }; |
| 602 |
| 603 |
| 549 class HValue : public ZoneObject { | 604 class HValue : public ZoneObject { |
| 550 public: | 605 public: |
| 551 static const int kNoNumber = -1; | 606 static const int kNoNumber = -1; |
| 552 | 607 |
| 553 enum Flag { | 608 enum Flag { |
| 554 kFlexibleRepresentation, | 609 kFlexibleRepresentation, |
| 555 kCannotBeTagged, | 610 kCannotBeTagged, |
| 556 // Participate in Global Value Numbering, i.e. elimination of | 611 // Participate in Global Value Numbering, i.e. elimination of |
| 557 // unnecessary recomputations. If an instruction sets this flag, it must | 612 // unnecessary recomputations. If an instruction sets this flag, it must |
| 558 // implement DataEquals(), which will be used to determine if other | 613 // implement DataEquals(), which will be used to determine if other |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 | 675 |
| 621 HValue(HType type = HType::Tagged()) | 676 HValue(HType type = HType::Tagged()) |
| 622 : block_(NULL), | 677 : block_(NULL), |
| 623 id_(kNoNumber), | 678 id_(kNoNumber), |
| 624 type_(type), | 679 type_(type), |
| 625 use_list_(NULL), | 680 use_list_(NULL), |
| 626 range_(NULL), | 681 range_(NULL), |
| 627 flags_(0) {} | 682 flags_(0) {} |
| 628 virtual ~HValue() {} | 683 virtual ~HValue() {} |
| 629 | 684 |
| 630 virtual int position() const { return RelocInfo::kNoPosition; } | 685 virtual HSourcePosition position() const { |
| 631 virtual int operand_position(int index) const { return position(); } | 686 return HSourcePosition::Unknown(); |
| 687 } |
| 688 virtual HSourcePosition operand_position(int index) const { |
| 689 return position(); |
| 690 } |
| 632 | 691 |
| 633 HBasicBlock* block() const { return block_; } | 692 HBasicBlock* block() const { return block_; } |
| 634 void SetBlock(HBasicBlock* block); | 693 void SetBlock(HBasicBlock* block); |
| 635 | 694 |
| 636 // Note: Never call this method for an unlinked value. | 695 // Note: Never call this method for an unlinked value. |
| 637 Isolate* isolate() const; | 696 Isolate* isolate() const; |
| 638 | 697 |
| 639 int id() const { return id_; } | 698 int id() const { return id_; } |
| 640 void set_id(int id) { id_ = id; } | 699 void set_id(int id) { id_ = id; } |
| 641 | 700 |
| (...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1078 } | 1137 } |
| 1079 | 1138 |
| 1080 | 1139 |
| 1081 // A helper class to represent per-operand position information attached to | 1140 // A helper class to represent per-operand position information attached to |
| 1082 // the HInstruction in the compact form. Uses tagging to distinguish between | 1141 // the HInstruction in the compact form. Uses tagging to distinguish between |
| 1083 // case when only instruction's position is available and case when operands' | 1142 // case when only instruction's position is available and case when operands' |
| 1084 // positions are also available. | 1143 // positions are also available. |
| 1085 // In the first case it contains intruction's position as a tagged value. | 1144 // In the first case it contains intruction's position as a tagged value. |
| 1086 // In the second case it points to an array which contains instruction's | 1145 // In the second case it points to an array which contains instruction's |
| 1087 // position and operands' positions. | 1146 // position and operands' positions. |
| 1088 // TODO(vegorov): what we really want to track here is a combination of | |
| 1089 // source position and a script id because cross script inlining can easily | |
| 1090 // result in optimized functions composed of several scripts. | |
| 1091 class HPositionInfo { | 1147 class HPositionInfo { |
| 1092 public: | 1148 public: |
| 1093 explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { } | 1149 explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { } |
| 1094 | 1150 |
| 1095 int position() const { | 1151 HSourcePosition position() const { |
| 1096 if (has_operand_positions()) { | 1152 if (has_operand_positions()) { |
| 1097 return static_cast<int>(operand_positions()[kInstructionPosIndex]); | 1153 return operand_positions()[kInstructionPosIndex]; |
| 1098 } | 1154 } |
| 1099 return static_cast<int>(UntagPosition(data_)); | 1155 return HSourcePosition(static_cast<int>(UntagPosition(data_))); |
| 1100 } | 1156 } |
| 1101 | 1157 |
| 1102 void set_position(int pos) { | 1158 void set_position(HSourcePosition pos) { |
| 1103 if (has_operand_positions()) { | 1159 if (has_operand_positions()) { |
| 1104 operand_positions()[kInstructionPosIndex] = pos; | 1160 operand_positions()[kInstructionPosIndex] = pos; |
| 1105 } else { | 1161 } else { |
| 1106 data_ = TagPosition(pos); | 1162 data_ = TagPosition(pos.raw()); |
| 1107 } | 1163 } |
| 1108 } | 1164 } |
| 1109 | 1165 |
| 1110 void ensure_storage_for_operand_positions(Zone* zone, int operand_count) { | 1166 void ensure_storage_for_operand_positions(Zone* zone, int operand_count) { |
| 1111 if (has_operand_positions()) { | 1167 if (has_operand_positions()) { |
| 1112 return; | 1168 return; |
| 1113 } | 1169 } |
| 1114 | 1170 |
| 1115 const int length = kFirstOperandPosIndex + operand_count; | 1171 const int length = kFirstOperandPosIndex + operand_count; |
| 1116 intptr_t* positions = | 1172 HSourcePosition* positions = |
| 1117 zone->NewArray<intptr_t>(length); | 1173 zone->NewArray<HSourcePosition>(length); |
| 1118 for (int i = 0; i < length; i++) { | 1174 for (int i = 0; i < length; i++) { |
| 1119 positions[i] = RelocInfo::kNoPosition; | 1175 positions[i] = HSourcePosition::Unknown(); |
| 1120 } | 1176 } |
| 1121 | 1177 |
| 1122 const int pos = position(); | 1178 const HSourcePosition pos = position(); |
| 1123 data_ = reinterpret_cast<intptr_t>(positions); | 1179 data_ = reinterpret_cast<intptr_t>(positions); |
| 1124 set_position(pos); | 1180 set_position(pos); |
| 1125 | 1181 |
| 1126 ASSERT(has_operand_positions()); | 1182 ASSERT(has_operand_positions()); |
| 1127 } | 1183 } |
| 1128 | 1184 |
| 1129 int operand_position(int idx) const { | 1185 HSourcePosition operand_position(int idx) const { |
| 1130 if (!has_operand_positions()) { | 1186 if (!has_operand_positions()) { |
| 1131 return position(); | 1187 return position(); |
| 1132 } | 1188 } |
| 1133 return static_cast<int>(*operand_position_slot(idx)); | 1189 return *operand_position_slot(idx); |
| 1134 } | 1190 } |
| 1135 | 1191 |
| 1136 void set_operand_position(int idx, int pos) { | 1192 void set_operand_position(int idx, HSourcePosition pos) { |
| 1137 *operand_position_slot(idx) = pos; | 1193 *operand_position_slot(idx) = pos; |
| 1138 } | 1194 } |
| 1139 | 1195 |
| 1140 private: | 1196 private: |
| 1141 static const intptr_t kInstructionPosIndex = 0; | 1197 static const intptr_t kInstructionPosIndex = 0; |
| 1142 static const intptr_t kFirstOperandPosIndex = 1; | 1198 static const intptr_t kFirstOperandPosIndex = 1; |
| 1143 | 1199 |
| 1144 intptr_t* operand_position_slot(int idx) const { | 1200 HSourcePosition* operand_position_slot(int idx) const { |
| 1145 ASSERT(has_operand_positions()); | 1201 ASSERT(has_operand_positions()); |
| 1146 return &(operand_positions()[kFirstOperandPosIndex + idx]); | 1202 return &(operand_positions()[kFirstOperandPosIndex + idx]); |
| 1147 } | 1203 } |
| 1148 | 1204 |
| 1149 bool has_operand_positions() const { | 1205 bool has_operand_positions() const { |
| 1150 return !IsTaggedPosition(data_); | 1206 return !IsTaggedPosition(data_); |
| 1151 } | 1207 } |
| 1152 | 1208 |
| 1153 intptr_t* operand_positions() const { | 1209 HSourcePosition* operand_positions() const { |
| 1154 ASSERT(has_operand_positions()); | 1210 ASSERT(has_operand_positions()); |
| 1155 return reinterpret_cast<intptr_t*>(data_); | 1211 return reinterpret_cast<HSourcePosition*>(data_); |
| 1156 } | 1212 } |
| 1157 | 1213 |
| 1158 static const intptr_t kPositionTag = 1; | 1214 static const intptr_t kPositionTag = 1; |
| 1159 static const intptr_t kPositionShift = 1; | 1215 static const intptr_t kPositionShift = 1; |
| 1160 static bool IsTaggedPosition(intptr_t val) { | 1216 static bool IsTaggedPosition(intptr_t val) { |
| 1161 return (val & kPositionTag) != 0; | 1217 return (val & kPositionTag) != 0; |
| 1162 } | 1218 } |
| 1163 static intptr_t UntagPosition(intptr_t val) { | 1219 static intptr_t UntagPosition(intptr_t val) { |
| 1164 ASSERT(IsTaggedPosition(val)); | 1220 ASSERT(IsTaggedPosition(val)); |
| 1165 return val >> kPositionShift; | 1221 return val >> kPositionShift; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1193 } | 1249 } |
| 1194 | 1250 |
| 1195 void InsertAfter(HInstruction* previous); | 1251 void InsertAfter(HInstruction* previous); |
| 1196 | 1252 |
| 1197 template<class T> T* Append(T* instr) { | 1253 template<class T> T* Append(T* instr) { |
| 1198 instr->InsertAfter(this); | 1254 instr->InsertAfter(this); |
| 1199 return instr; | 1255 return instr; |
| 1200 } | 1256 } |
| 1201 | 1257 |
| 1202 // The position is a write-once variable. | 1258 // The position is a write-once variable. |
| 1203 virtual int position() const V8_OVERRIDE { | 1259 virtual HSourcePosition position() const V8_OVERRIDE { |
| 1204 return position_.position(); | 1260 return HSourcePosition(position_.position()); |
| 1205 } | 1261 } |
| 1206 bool has_position() const { | 1262 bool has_position() const { |
| 1207 return position_.position() != RelocInfo::kNoPosition; | 1263 return !position().IsUnknown(); |
| 1208 } | 1264 } |
| 1209 void set_position(int position) { | 1265 void set_position(HSourcePosition position) { |
| 1210 ASSERT(!has_position()); | 1266 ASSERT(!has_position()); |
| 1211 ASSERT(position != RelocInfo::kNoPosition); | 1267 ASSERT(!position.IsUnknown()); |
| 1212 position_.set_position(position); | 1268 position_.set_position(position); |
| 1213 } | 1269 } |
| 1214 | 1270 |
| 1215 virtual int operand_position(int index) const V8_OVERRIDE { | 1271 virtual HSourcePosition operand_position(int index) const V8_OVERRIDE { |
| 1216 const int pos = position_.operand_position(index); | 1272 const HSourcePosition pos = position_.operand_position(index); |
| 1217 return (pos != RelocInfo::kNoPosition) ? pos : position(); | 1273 return pos.IsUnknown() ? position() : pos; |
| 1218 } | 1274 } |
| 1219 void set_operand_position(Zone* zone, int index, int pos) { | 1275 void set_operand_position(Zone* zone, int index, HSourcePosition pos) { |
| 1220 ASSERT(0 <= index && index < OperandCount()); | 1276 ASSERT(0 <= index && index < OperandCount()); |
| 1221 position_.ensure_storage_for_operand_positions(zone, OperandCount()); | 1277 position_.ensure_storage_for_operand_positions(zone, OperandCount()); |
| 1222 position_.set_operand_position(index, pos); | 1278 position_.set_operand_position(index, pos); |
| 1223 } | 1279 } |
| 1224 | 1280 |
| 1225 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } | 1281 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } |
| 1226 | 1282 |
| 1227 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; | 1283 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; |
| 1228 | 1284 |
| 1229 #ifdef DEBUG | 1285 #ifdef DEBUG |
| (...skipping 1926 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3156 virtual HValue* OperandAt(int index) const V8_OVERRIDE { | 3212 virtual HValue* OperandAt(int index) const V8_OVERRIDE { |
| 3157 return inputs_[index]; | 3213 return inputs_[index]; |
| 3158 } | 3214 } |
| 3159 HValue* GetRedundantReplacement(); | 3215 HValue* GetRedundantReplacement(); |
| 3160 void AddInput(HValue* value); | 3216 void AddInput(HValue* value); |
| 3161 bool HasRealUses(); | 3217 bool HasRealUses(); |
| 3162 | 3218 |
| 3163 bool IsReceiver() const { return merged_index_ == 0; } | 3219 bool IsReceiver() const { return merged_index_ == 0; } |
| 3164 bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; } | 3220 bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; } |
| 3165 | 3221 |
| 3166 virtual int position() const V8_OVERRIDE; | 3222 virtual HSourcePosition position() const V8_OVERRIDE; |
| 3167 | 3223 |
| 3168 int merged_index() const { return merged_index_; } | 3224 int merged_index() const { return merged_index_; } |
| 3169 | 3225 |
| 3170 InductionVariableData* induction_variable_data() { | 3226 InductionVariableData* induction_variable_data() { |
| 3171 return induction_variable_data_; | 3227 return induction_variable_data_; |
| 3172 } | 3228 } |
| 3173 bool IsInductionVariable() { | 3229 bool IsInductionVariable() { |
| 3174 return induction_variable_data_ != NULL; | 3230 return induction_variable_data_ != NULL; |
| 3175 } | 3231 } |
| 3176 bool IsLimitedInductionVariable() { | 3232 bool IsLimitedInductionVariable() { |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3661 | 3717 |
| 3662 virtual bool IsCommutative() const { return false; } | 3718 virtual bool IsCommutative() const { return false; } |
| 3663 | 3719 |
| 3664 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 3720 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 3665 | 3721 |
| 3666 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 3722 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 3667 if (index == 0) return Representation::Tagged(); | 3723 if (index == 0) return Representation::Tagged(); |
| 3668 return representation(); | 3724 return representation(); |
| 3669 } | 3725 } |
| 3670 | 3726 |
| 3671 void SetOperandPositions(Zone* zone, int left_pos, int right_pos) { | 3727 void SetOperandPositions(Zone* zone, |
| 3728 HSourcePosition left_pos, |
| 3729 HSourcePosition right_pos) { |
| 3672 set_operand_position(zone, 1, left_pos); | 3730 set_operand_position(zone, 1, left_pos); |
| 3673 set_operand_position(zone, 2, right_pos); | 3731 set_operand_position(zone, 2, right_pos); |
| 3674 } | 3732 } |
| 3675 | 3733 |
| 3676 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) | 3734 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) |
| 3677 | 3735 |
| 3678 private: | 3736 private: |
| 3679 bool IgnoreObservedOutputRepresentation(Representation current_rep); | 3737 bool IgnoreObservedOutputRepresentation(Representation current_rep); |
| 3680 | 3738 |
| 3681 Representation observed_input_representation_[2]; | 3739 Representation observed_input_representation_[2]; |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4116 HInferRepresentationPhase* h_infer) V8_OVERRIDE; | 4174 HInferRepresentationPhase* h_infer) V8_OVERRIDE; |
| 4117 | 4175 |
| 4118 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 4176 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 4119 return representation(); | 4177 return representation(); |
| 4120 } | 4178 } |
| 4121 virtual Representation observed_input_representation(int index) V8_OVERRIDE { | 4179 virtual Representation observed_input_representation(int index) V8_OVERRIDE { |
| 4122 return observed_input_representation_[index]; | 4180 return observed_input_representation_[index]; |
| 4123 } | 4181 } |
| 4124 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 4182 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 4125 | 4183 |
| 4126 void SetOperandPositions(Zone* zone, int left_pos, int right_pos) { | 4184 void SetOperandPositions(Zone* zone, |
| 4185 HSourcePosition left_pos, |
| 4186 HSourcePosition right_pos) { |
| 4127 set_operand_position(zone, 0, left_pos); | 4187 set_operand_position(zone, 0, left_pos); |
| 4128 set_operand_position(zone, 1, right_pos); | 4188 set_operand_position(zone, 1, right_pos); |
| 4129 } | 4189 } |
| 4130 | 4190 |
| 4131 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) | 4191 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) |
| 4132 | 4192 |
| 4133 private: | 4193 private: |
| 4134 HCompareNumericAndBranch(HValue* left, | 4194 HCompareNumericAndBranch(HValue* left, |
| 4135 HValue* right, | 4195 HValue* right, |
| 4136 Token::Value token, | 4196 Token::Value token, |
| (...skipping 3318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7455 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 7515 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 7456 }; | 7516 }; |
| 7457 | 7517 |
| 7458 | 7518 |
| 7459 #undef DECLARE_INSTRUCTION | 7519 #undef DECLARE_INSTRUCTION |
| 7460 #undef DECLARE_CONCRETE_INSTRUCTION | 7520 #undef DECLARE_CONCRETE_INSTRUCTION |
| 7461 | 7521 |
| 7462 } } // namespace v8::internal | 7522 } } // namespace v8::internal |
| 7463 | 7523 |
| 7464 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7524 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |