| 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 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 530 | 530 |
| 531 HValue* base_; | 531 HValue* base_; |
| 532 int offset_; | 532 int offset_; |
| 533 int scale_; | 533 int scale_; |
| 534 }; | 534 }; |
| 535 | 535 |
| 536 | 536 |
| 537 typedef EnumSet<GVNFlag, int64_t> GVNFlagSet; | 537 typedef EnumSet<GVNFlag, int64_t> GVNFlagSet; |
| 538 | 538 |
| 539 | 539 |
| 540 // This class encapsulates encoding and decoding of sources positions from |
| 541 // which hydrogen values originated. |
| 542 // When FLAG_track_hydrogen_positions is set this object encodes the |
| 543 // identifier of the inlining and absolute offset from the start of the |
| 544 // inlined function. |
| 545 // When the flag is not set we simply track absolute offset from the |
| 546 // script start. |
| 547 class HSourcePosition { |
| 548 public: |
| 549 HSourcePosition(const HSourcePosition& other) : value_(other.value_) { } |
| 550 |
| 551 static HSourcePosition Unknown() { |
| 552 return HSourcePosition(RelocInfo::kNoPosition); |
| 553 } |
| 554 |
| 555 bool IsUnknown() const { return value_ == RelocInfo::kNoPosition; } |
| 556 |
| 557 int position() const { return PositionField::decode(value_); } |
| 558 void set_position(int position) { |
| 559 if (FLAG_hydrogen_track_positions) { |
| 560 value_ = static_cast<int>(PositionField::update(value_, position)); |
| 561 } else { |
| 562 value_ = position; |
| 563 } |
| 564 } |
| 565 |
| 566 int inlining_id() const { return InliningIdField::decode(value_); } |
| 567 void set_inlining_id(int inlining_id) { |
| 568 if (FLAG_hydrogen_track_positions) { |
| 569 value_ = static_cast<int>(InliningIdField::update(value_, inlining_id)); |
| 570 } |
| 571 } |
| 572 |
| 573 int raw() const { return value_; } |
| 574 |
| 575 void PrintTo(FILE* f); |
| 576 |
| 577 private: |
| 578 typedef BitField<int, 0, 9> InliningIdField; |
| 579 |
| 580 // Offset from the start of the inlined function. |
| 581 typedef BitField<int, 9, 22> PositionField; |
| 582 |
| 583 // On HPositionInfo can use this constructor. |
| 584 explicit HSourcePosition(int value) : value_(value) { } |
| 585 |
| 586 friend class HPositionInfo; |
| 587 |
| 588 // If FLAG_hydrogen_track_positions is set contains bitfields InliningIdField |
| 589 // and PositionField. |
| 590 // Otherwise contains absolute offset from the script start. |
| 591 int value_; |
| 592 }; |
| 593 |
| 594 |
| 540 class HValue : public ZoneObject { | 595 class HValue : public ZoneObject { |
| 541 public: | 596 public: |
| 542 static const int kNoNumber = -1; | 597 static const int kNoNumber = -1; |
| 543 | 598 |
| 544 enum Flag { | 599 enum Flag { |
| 545 kFlexibleRepresentation, | 600 kFlexibleRepresentation, |
| 546 kCannotBeTagged, | 601 kCannotBeTagged, |
| 547 // Participate in Global Value Numbering, i.e. elimination of | 602 // Participate in Global Value Numbering, i.e. elimination of |
| 548 // unnecessary recomputations. If an instruction sets this flag, it must | 603 // unnecessary recomputations. If an instruction sets this flag, it must |
| 549 // implement DataEquals(), which will be used to determine if other | 604 // implement DataEquals(), which will be used to determine if other |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 623 | 678 |
| 624 HValue(HType type = HType::Tagged()) | 679 HValue(HType type = HType::Tagged()) |
| 625 : block_(NULL), | 680 : block_(NULL), |
| 626 id_(kNoNumber), | 681 id_(kNoNumber), |
| 627 type_(type), | 682 type_(type), |
| 628 use_list_(NULL), | 683 use_list_(NULL), |
| 629 range_(NULL), | 684 range_(NULL), |
| 630 flags_(0) {} | 685 flags_(0) {} |
| 631 virtual ~HValue() {} | 686 virtual ~HValue() {} |
| 632 | 687 |
| 633 virtual int position() const { return RelocInfo::kNoPosition; } | 688 virtual HSourcePosition position() const { |
| 634 virtual int operand_position(int index) const { return position(); } | 689 return HSourcePosition::Unknown(); |
| 690 } |
| 691 virtual HSourcePosition operand_position(int index) const { |
| 692 return position(); |
| 693 } |
| 635 | 694 |
| 636 HBasicBlock* block() const { return block_; } | 695 HBasicBlock* block() const { return block_; } |
| 637 void SetBlock(HBasicBlock* block); | 696 void SetBlock(HBasicBlock* block); |
| 638 | 697 |
| 639 // Note: Never call this method for an unlinked value. | 698 // Note: Never call this method for an unlinked value. |
| 640 Isolate* isolate() const; | 699 Isolate* isolate() const; |
| 641 | 700 |
| 642 int id() const { return id_; } | 701 int id() const { return id_; } |
| 643 void set_id(int id) { id_ = id; } | 702 void set_id(int id) { id_ = id; } |
| 644 | 703 |
| (...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1096 } | 1155 } |
| 1097 | 1156 |
| 1098 | 1157 |
| 1099 // A helper class to represent per-operand position information attached to | 1158 // A helper class to represent per-operand position information attached to |
| 1100 // the HInstruction in the compact form. Uses tagging to distinguish between | 1159 // the HInstruction in the compact form. Uses tagging to distinguish between |
| 1101 // case when only instruction's position is available and case when operands' | 1160 // case when only instruction's position is available and case when operands' |
| 1102 // positions are also available. | 1161 // positions are also available. |
| 1103 // In the first case it contains intruction's position as a tagged value. | 1162 // In the first case it contains intruction's position as a tagged value. |
| 1104 // In the second case it points to an array which contains instruction's | 1163 // In the second case it points to an array which contains instruction's |
| 1105 // position and operands' positions. | 1164 // position and operands' positions. |
| 1106 // TODO(vegorov): what we really want to track here is a combination of | |
| 1107 // source position and a script id because cross script inlining can easily | |
| 1108 // result in optimized functions composed of several scripts. | |
| 1109 class HPositionInfo { | 1165 class HPositionInfo { |
| 1110 public: | 1166 public: |
| 1111 explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { } | 1167 explicit HPositionInfo(int pos) : data_(TagPosition(pos)) { } |
| 1112 | 1168 |
| 1113 int position() const { | 1169 HSourcePosition position() const { |
| 1114 if (has_operand_positions()) { | 1170 if (has_operand_positions()) { |
| 1115 return static_cast<int>(operand_positions()[kInstructionPosIndex]); | 1171 return operand_positions()[kInstructionPosIndex]; |
| 1116 } | 1172 } |
| 1117 return static_cast<int>(UntagPosition(data_)); | 1173 return HSourcePosition(static_cast<int>(UntagPosition(data_))); |
| 1118 } | 1174 } |
| 1119 | 1175 |
| 1120 void set_position(int pos) { | 1176 void set_position(HSourcePosition pos) { |
| 1121 if (has_operand_positions()) { | 1177 if (has_operand_positions()) { |
| 1122 operand_positions()[kInstructionPosIndex] = pos; | 1178 operand_positions()[kInstructionPosIndex] = pos; |
| 1123 } else { | 1179 } else { |
| 1124 data_ = TagPosition(pos); | 1180 data_ = TagPosition(pos.raw()); |
| 1125 } | 1181 } |
| 1126 } | 1182 } |
| 1127 | 1183 |
| 1128 void ensure_storage_for_operand_positions(Zone* zone, int operand_count) { | 1184 void ensure_storage_for_operand_positions(Zone* zone, int operand_count) { |
| 1129 if (has_operand_positions()) { | 1185 if (has_operand_positions()) { |
| 1130 return; | 1186 return; |
| 1131 } | 1187 } |
| 1132 | 1188 |
| 1133 const int length = kFirstOperandPosIndex + operand_count; | 1189 const int length = kFirstOperandPosIndex + operand_count; |
| 1134 intptr_t* positions = | 1190 HSourcePosition* positions = |
| 1135 zone->NewArray<intptr_t>(length); | 1191 zone->NewArray<HSourcePosition>(length); |
| 1136 for (int i = 0; i < length; i++) { | 1192 for (int i = 0; i < length; i++) { |
| 1137 positions[i] = RelocInfo::kNoPosition; | 1193 positions[i] = HSourcePosition::Unknown(); |
| 1138 } | 1194 } |
| 1139 | 1195 |
| 1140 const int pos = position(); | 1196 const HSourcePosition pos = position(); |
| 1141 data_ = reinterpret_cast<intptr_t>(positions); | 1197 data_ = reinterpret_cast<intptr_t>(positions); |
| 1142 set_position(pos); | 1198 set_position(pos); |
| 1143 | 1199 |
| 1144 ASSERT(has_operand_positions()); | 1200 ASSERT(has_operand_positions()); |
| 1145 } | 1201 } |
| 1146 | 1202 |
| 1147 int operand_position(int idx) const { | 1203 HSourcePosition operand_position(int idx) const { |
| 1148 if (!has_operand_positions()) { | 1204 if (!has_operand_positions()) { |
| 1149 return position(); | 1205 return position(); |
| 1150 } | 1206 } |
| 1151 return static_cast<int>(*operand_position_slot(idx)); | 1207 return *operand_position_slot(idx); |
| 1152 } | 1208 } |
| 1153 | 1209 |
| 1154 void set_operand_position(int idx, int pos) { | 1210 void set_operand_position(int idx, HSourcePosition pos) { |
| 1155 *operand_position_slot(idx) = pos; | 1211 *operand_position_slot(idx) = pos; |
| 1156 } | 1212 } |
| 1157 | 1213 |
| 1158 private: | 1214 private: |
| 1159 static const intptr_t kInstructionPosIndex = 0; | 1215 static const intptr_t kInstructionPosIndex = 0; |
| 1160 static const intptr_t kFirstOperandPosIndex = 1; | 1216 static const intptr_t kFirstOperandPosIndex = 1; |
| 1161 | 1217 |
| 1162 intptr_t* operand_position_slot(int idx) const { | 1218 HSourcePosition* operand_position_slot(int idx) const { |
| 1163 ASSERT(has_operand_positions()); | 1219 ASSERT(has_operand_positions()); |
| 1164 return &(operand_positions()[kFirstOperandPosIndex + idx]); | 1220 return &(operand_positions()[kFirstOperandPosIndex + idx]); |
| 1165 } | 1221 } |
| 1166 | 1222 |
| 1167 bool has_operand_positions() const { | 1223 bool has_operand_positions() const { |
| 1168 return !IsTaggedPosition(data_); | 1224 return !IsTaggedPosition(data_); |
| 1169 } | 1225 } |
| 1170 | 1226 |
| 1171 intptr_t* operand_positions() const { | 1227 HSourcePosition* operand_positions() const { |
| 1172 ASSERT(has_operand_positions()); | 1228 ASSERT(has_operand_positions()); |
| 1173 return reinterpret_cast<intptr_t*>(data_); | 1229 return reinterpret_cast<HSourcePosition*>(data_); |
| 1174 } | 1230 } |
| 1175 | 1231 |
| 1176 static const intptr_t kPositionTag = 1; | 1232 static const intptr_t kPositionTag = 1; |
| 1177 static const intptr_t kPositionShift = 1; | 1233 static const intptr_t kPositionShift = 1; |
| 1178 static bool IsTaggedPosition(intptr_t val) { | 1234 static bool IsTaggedPosition(intptr_t val) { |
| 1179 return (val & kPositionTag) != 0; | 1235 return (val & kPositionTag) != 0; |
| 1180 } | 1236 } |
| 1181 static intptr_t UntagPosition(intptr_t val) { | 1237 static intptr_t UntagPosition(intptr_t val) { |
| 1182 ASSERT(IsTaggedPosition(val)); | 1238 ASSERT(IsTaggedPosition(val)); |
| 1183 return val >> kPositionShift; | 1239 return val >> kPositionShift; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1211 } | 1267 } |
| 1212 | 1268 |
| 1213 void InsertAfter(HInstruction* previous); | 1269 void InsertAfter(HInstruction* previous); |
| 1214 | 1270 |
| 1215 template<class T> T* Append(T* instr) { | 1271 template<class T> T* Append(T* instr) { |
| 1216 instr->InsertAfter(this); | 1272 instr->InsertAfter(this); |
| 1217 return instr; | 1273 return instr; |
| 1218 } | 1274 } |
| 1219 | 1275 |
| 1220 // The position is a write-once variable. | 1276 // The position is a write-once variable. |
| 1221 virtual int position() const V8_OVERRIDE { | 1277 virtual HSourcePosition position() const V8_OVERRIDE { |
| 1222 return position_.position(); | 1278 return HSourcePosition(position_.position()); |
| 1223 } | 1279 } |
| 1224 bool has_position() const { | 1280 bool has_position() const { |
| 1225 return position_.position() != RelocInfo::kNoPosition; | 1281 return !position().IsUnknown(); |
| 1226 } | 1282 } |
| 1227 void set_position(int position) { | 1283 void set_position(HSourcePosition position) { |
| 1228 ASSERT(!has_position()); | 1284 ASSERT(!has_position()); |
| 1229 ASSERT(position != RelocInfo::kNoPosition); | 1285 ASSERT(!position.IsUnknown()); |
| 1230 position_.set_position(position); | 1286 position_.set_position(position); |
| 1231 } | 1287 } |
| 1232 | 1288 |
| 1233 virtual int operand_position(int index) const V8_OVERRIDE { | 1289 virtual HSourcePosition operand_position(int index) const V8_OVERRIDE { |
| 1234 const int pos = position_.operand_position(index); | 1290 const HSourcePosition pos = position_.operand_position(index); |
| 1235 return (pos != RelocInfo::kNoPosition) ? pos : position(); | 1291 return pos.IsUnknown() ? position() : pos; |
| 1236 } | 1292 } |
| 1237 void set_operand_position(Zone* zone, int index, int pos) { | 1293 void set_operand_position(Zone* zone, int index, HSourcePosition pos) { |
| 1238 ASSERT(0 <= index && index < OperandCount()); | 1294 ASSERT(0 <= index && index < OperandCount()); |
| 1239 position_.ensure_storage_for_operand_positions(zone, OperandCount()); | 1295 position_.ensure_storage_for_operand_positions(zone, OperandCount()); |
| 1240 position_.set_operand_position(index, pos); | 1296 position_.set_operand_position(index, pos); |
| 1241 } | 1297 } |
| 1242 | 1298 |
| 1243 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } | 1299 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); } |
| 1244 | 1300 |
| 1245 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; | 1301 virtual LInstruction* CompileToLithium(LChunkBuilder* builder) = 0; |
| 1246 | 1302 |
| 1247 #ifdef DEBUG | 1303 #ifdef DEBUG |
| (...skipping 1894 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3142 virtual HValue* OperandAt(int index) const V8_OVERRIDE { | 3198 virtual HValue* OperandAt(int index) const V8_OVERRIDE { |
| 3143 return inputs_[index]; | 3199 return inputs_[index]; |
| 3144 } | 3200 } |
| 3145 HValue* GetRedundantReplacement(); | 3201 HValue* GetRedundantReplacement(); |
| 3146 void AddInput(HValue* value); | 3202 void AddInput(HValue* value); |
| 3147 bool HasRealUses(); | 3203 bool HasRealUses(); |
| 3148 | 3204 |
| 3149 bool IsReceiver() const { return merged_index_ == 0; } | 3205 bool IsReceiver() const { return merged_index_ == 0; } |
| 3150 bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; } | 3206 bool HasMergedIndex() const { return merged_index_ != kInvalidMergedIndex; } |
| 3151 | 3207 |
| 3152 virtual int position() const V8_OVERRIDE; | 3208 virtual HSourcePosition position() const V8_OVERRIDE; |
| 3153 | 3209 |
| 3154 int merged_index() const { return merged_index_; } | 3210 int merged_index() const { return merged_index_; } |
| 3155 | 3211 |
| 3156 InductionVariableData* induction_variable_data() { | 3212 InductionVariableData* induction_variable_data() { |
| 3157 return induction_variable_data_; | 3213 return induction_variable_data_; |
| 3158 } | 3214 } |
| 3159 bool IsInductionVariable() { | 3215 bool IsInductionVariable() { |
| 3160 return induction_variable_data_ != NULL; | 3216 return induction_variable_data_ != NULL; |
| 3161 } | 3217 } |
| 3162 bool IsLimitedInductionVariable() { | 3218 bool IsLimitedInductionVariable() { |
| (...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3647 | 3703 |
| 3648 virtual bool IsCommutative() const { return false; } | 3704 virtual bool IsCommutative() const { return false; } |
| 3649 | 3705 |
| 3650 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 3706 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 3651 | 3707 |
| 3652 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 3708 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 3653 if (index == 0) return Representation::Tagged(); | 3709 if (index == 0) return Representation::Tagged(); |
| 3654 return representation(); | 3710 return representation(); |
| 3655 } | 3711 } |
| 3656 | 3712 |
| 3657 void SetOperandPositions(Zone* zone, int left_pos, int right_pos) { | 3713 void SetOperandPositions(Zone* zone, |
| 3714 HSourcePosition left_pos, |
| 3715 HSourcePosition right_pos) { |
| 3658 set_operand_position(zone, 1, left_pos); | 3716 set_operand_position(zone, 1, left_pos); |
| 3659 set_operand_position(zone, 2, right_pos); | 3717 set_operand_position(zone, 2, right_pos); |
| 3660 } | 3718 } |
| 3661 | 3719 |
| 3662 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) | 3720 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) |
| 3663 | 3721 |
| 3664 private: | 3722 private: |
| 3665 bool IgnoreObservedOutputRepresentation(Representation current_rep); | 3723 bool IgnoreObservedOutputRepresentation(Representation current_rep); |
| 3666 | 3724 |
| 3667 Representation observed_input_representation_[2]; | 3725 Representation observed_input_representation_[2]; |
| (...skipping 434 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4102 HInferRepresentationPhase* h_infer) V8_OVERRIDE; | 4160 HInferRepresentationPhase* h_infer) V8_OVERRIDE; |
| 4103 | 4161 |
| 4104 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { | 4162 virtual Representation RequiredInputRepresentation(int index) V8_OVERRIDE { |
| 4105 return representation(); | 4163 return representation(); |
| 4106 } | 4164 } |
| 4107 virtual Representation observed_input_representation(int index) V8_OVERRIDE { | 4165 virtual Representation observed_input_representation(int index) V8_OVERRIDE { |
| 4108 return observed_input_representation_[index]; | 4166 return observed_input_representation_[index]; |
| 4109 } | 4167 } |
| 4110 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; | 4168 virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE; |
| 4111 | 4169 |
| 4112 void SetOperandPositions(Zone* zone, int left_pos, int right_pos) { | 4170 void SetOperandPositions(Zone* zone, |
| 4171 HSourcePosition left_pos, |
| 4172 HSourcePosition right_pos) { |
| 4113 set_operand_position(zone, 0, left_pos); | 4173 set_operand_position(zone, 0, left_pos); |
| 4114 set_operand_position(zone, 1, right_pos); | 4174 set_operand_position(zone, 1, right_pos); |
| 4115 } | 4175 } |
| 4116 | 4176 |
| 4117 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) | 4177 DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch) |
| 4118 | 4178 |
| 4119 private: | 4179 private: |
| 4120 HCompareNumericAndBranch(HValue* left, | 4180 HCompareNumericAndBranch(HValue* left, |
| 4121 HValue* right, | 4181 HValue* right, |
| 4122 Token::Value token, | 4182 Token::Value token, |
| (...skipping 3304 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7427 virtual bool IsDeletable() const V8_OVERRIDE { return true; } | 7487 virtual bool IsDeletable() const V8_OVERRIDE { return true; } |
| 7428 }; | 7488 }; |
| 7429 | 7489 |
| 7430 | 7490 |
| 7431 #undef DECLARE_INSTRUCTION | 7491 #undef DECLARE_INSTRUCTION |
| 7432 #undef DECLARE_CONCRETE_INSTRUCTION | 7492 #undef DECLARE_CONCRETE_INSTRUCTION |
| 7433 | 7493 |
| 7434 } } // namespace v8::internal | 7494 } } // namespace v8::internal |
| 7435 | 7495 |
| 7436 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 7496 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |