| 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_LITHIUM_H_ | 5 #ifndef V8_LITHIUM_H_ |
| 6 #define V8_LITHIUM_H_ | 6 #define V8_LITHIUM_H_ |
| 7 | 7 |
| 8 #include <set> | 8 #include <set> |
| 9 | 9 |
| 10 #include "src/allocation.h" | 10 #include "src/allocation.h" |
| 11 #include "src/hydrogen.h" | 11 #include "src/hydrogen.h" |
| 12 #include "src/safepoint-table.h" | 12 #include "src/safepoint-table.h" |
| 13 #include "src/zone-allocator.h" | 13 #include "src/zone-allocator.h" |
| 14 | 14 |
| 15 namespace v8 { | 15 namespace v8 { |
| 16 namespace internal { | 16 namespace internal { |
| 17 | 17 |
| 18 #define LITHIUM_OPERAND_LIST(V) \ | 18 #define LITHIUM_OPERAND_LIST(V) \ |
| 19 V(ConstantOperand, CONSTANT_OPERAND, 128) \ | 19 V(ConstantOperand, CONSTANT_OPERAND, 128) \ |
| 20 V(StackSlot, STACK_SLOT, 128) \ | 20 V(StackSlot, STACK_SLOT, 128) \ |
| 21 V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \ | 21 V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \ |
| 22 V(Register, REGISTER, 16) \ | 22 V(Register, REGISTER, 16) \ |
| 23 V(DoubleRegister, DOUBLE_REGISTER, 16) | 23 V(DoubleRegister, DOUBLE_REGISTER, 16) |
| 24 | 24 |
| 25 | |
| 26 class LOperand : public ZoneObject { | 25 class LOperand : public ZoneObject { |
| 27 public: | 26 public: |
| 28 enum Kind { | 27 enum Kind { |
| 29 INVALID, | 28 INVALID, |
| 30 UNALLOCATED, | 29 UNALLOCATED, |
| 31 CONSTANT_OPERAND, | 30 CONSTANT_OPERAND, |
| 32 STACK_SLOT, | 31 STACK_SLOT, |
| 33 DOUBLE_STACK_SLOT, | 32 DOUBLE_STACK_SLOT, |
| 34 REGISTER, | 33 REGISTER, |
| 35 DOUBLE_REGISTER | 34 DOUBLE_REGISTER |
| 36 }; | 35 }; |
| 37 | 36 |
| 38 LOperand() : value_(KindField::encode(INVALID)) { } | 37 LOperand() : value_(KindField::encode(INVALID)) { } |
| 39 | 38 |
| 40 Kind kind() const { return KindField::decode(value_); } | 39 Kind kind() const { return KindField::decode(value_); } |
| 41 int index() const { return static_cast<int>(value_) >> kKindFieldWidth; } | 40 int index() const { return static_cast<int>(value_) >> kKindFieldWidth; } |
| 42 #define LITHIUM_OPERAND_PREDICATE(name, type, number) \ | 41 #define LITHIUM_OPERAND_PREDICATE(name, type, number) \ |
| 43 bool Is##name() const { return kind() == type; } | 42 bool Is##name() const { return kind() == type; } |
| 44 LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_PREDICATE) | 43 LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_PREDICATE) |
| 45 LITHIUM_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) | 44 LITHIUM_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) |
| 46 LITHIUM_OPERAND_PREDICATE(Ignored, INVALID, 0) | 45 LITHIUM_OPERAND_PREDICATE(Ignored, INVALID, 0) |
| 47 #undef LITHIUM_OPERAND_PREDICATE | 46 #undef LITHIUM_OPERAND_PREDICATE |
| 48 bool Equals(LOperand* other) const { return value_ == other->value_; } | 47 bool Equals(LOperand* other) const { return value_ == other->value_; } |
| 49 | 48 |
| 50 void PrintTo(StringStream* stream); | 49 void PrintTo(StringStream* stream); |
| 51 void ConvertTo(Kind kind, int index) { | 50 void ConvertTo(Kind kind, int index) { |
| 51 if (kind == REGISTER) ASSERT(index >= 0); |
| 52 value_ = KindField::encode(kind); | 52 value_ = KindField::encode(kind); |
| 53 value_ |= index << kKindFieldWidth; | 53 value_ |= index << kKindFieldWidth; |
| 54 ASSERT(this->index() == index); | 54 ASSERT(this->index() == index); |
| 55 } | 55 } |
| 56 | 56 |
| 57 // Calls SetUpCache()/TearDownCache() for each subclass. | 57 // Calls SetUpCache()/TearDownCache() for each subclass. |
| 58 static void SetUpCaches(); | 58 static void SetUpCaches(); |
| 59 static void TearDownCaches(); | 59 static void TearDownCaches(); |
| 60 | 60 |
| 61 protected: | 61 protected: |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 271 bool IsPending() const { | 271 bool IsPending() const { |
| 272 return destination_ == NULL && source_ != NULL; | 272 return destination_ == NULL && source_ != NULL; |
| 273 } | 273 } |
| 274 | 274 |
| 275 // True if this move a move into the given destination operand. | 275 // True if this move a move into the given destination operand. |
| 276 bool Blocks(LOperand* operand) const { | 276 bool Blocks(LOperand* operand) const { |
| 277 return !IsEliminated() && source()->Equals(operand); | 277 return !IsEliminated() && source()->Equals(operand); |
| 278 } | 278 } |
| 279 | 279 |
| 280 // A move is redundant if it's been eliminated, if its source and | 280 // A move is redundant if it's been eliminated, if its source and |
| 281 // destination are the same, or if its destination is unneeded. | 281 // destination are the same, or if its destination is unneeded or constant. |
| 282 bool IsRedundant() const { | 282 bool IsRedundant() const { |
| 283 return IsEliminated() || source_->Equals(destination_) || IsIgnored(); | 283 return IsEliminated() || source_->Equals(destination_) || IsIgnored() || |
| 284 (destination_ != NULL && destination_->IsConstantOperand()); |
| 284 } | 285 } |
| 285 | 286 |
| 286 bool IsIgnored() const { | 287 bool IsIgnored() const { |
| 287 return destination_ != NULL && destination_->IsIgnored(); | 288 return destination_ != NULL && destination_->IsIgnored(); |
| 288 } | 289 } |
| 289 | 290 |
| 290 // We clear both operands to indicate move that's been eliminated. | 291 // We clear both operands to indicate move that's been eliminated. |
| 291 void Eliminate() { source_ = destination_ = NULL; } | 292 void Eliminate() { source_ = destination_ = NULL; } |
| 292 bool IsEliminated() const { | 293 bool IsEliminated() const { |
| 293 ASSERT(source_ != NULL || destination_ == NULL); | 294 ASSERT(source_ != NULL || destination_ == NULL); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 class LParallelMove V8_FINAL : public ZoneObject { | 335 class LParallelMove V8_FINAL : public ZoneObject { |
| 335 public: | 336 public: |
| 336 explicit LParallelMove(Zone* zone) : move_operands_(4, zone) { } | 337 explicit LParallelMove(Zone* zone) : move_operands_(4, zone) { } |
| 337 | 338 |
| 338 void AddMove(LOperand* from, LOperand* to, Zone* zone) { | 339 void AddMove(LOperand* from, LOperand* to, Zone* zone) { |
| 339 move_operands_.Add(LMoveOperands(from, to), zone); | 340 move_operands_.Add(LMoveOperands(from, to), zone); |
| 340 } | 341 } |
| 341 | 342 |
| 342 bool IsRedundant() const; | 343 bool IsRedundant() const; |
| 343 | 344 |
| 344 const ZoneList<LMoveOperands>* move_operands() const { | 345 ZoneList<LMoveOperands>* move_operands() { return &move_operands_; } |
| 345 return &move_operands_; | |
| 346 } | |
| 347 | 346 |
| 348 void PrintDataTo(StringStream* stream) const; | 347 void PrintDataTo(StringStream* stream) const; |
| 349 | 348 |
| 350 private: | 349 private: |
| 351 ZoneList<LMoveOperands> move_operands_; | 350 ZoneList<LMoveOperands> move_operands_; |
| 352 }; | 351 }; |
| 353 | 352 |
| 354 | 353 |
| 355 class LPointerMap V8_FINAL : public ZoneObject { | 354 class LPointerMap V8_FINAL : public ZoneObject { |
| 356 public: | 355 public: |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 740 chunk_(chunk) { } | 739 chunk_(chunk) { } |
| 741 ~LPhase(); | 740 ~LPhase(); |
| 742 | 741 |
| 743 private: | 742 private: |
| 744 LChunk* chunk_; | 743 LChunk* chunk_; |
| 745 | 744 |
| 746 DISALLOW_COPY_AND_ASSIGN(LPhase); | 745 DISALLOW_COPY_AND_ASSIGN(LPhase); |
| 747 }; | 746 }; |
| 748 | 747 |
| 749 | 748 |
| 749 // A register-allocator view of a Lithium instruction. It contains the id of |
| 750 // the output operand and a list of input operand uses. |
| 751 |
| 752 enum RegisterKind { |
| 753 UNALLOCATED_REGISTERS, |
| 754 GENERAL_REGISTERS, |
| 755 DOUBLE_REGISTERS |
| 756 }; |
| 757 |
| 758 // Iterator for non-null temp operands. |
| 759 class TempIterator BASE_EMBEDDED { |
| 760 public: |
| 761 inline explicit TempIterator(LInstruction* instr); |
| 762 inline bool Done(); |
| 763 inline LOperand* Current(); |
| 764 inline void Advance(); |
| 765 |
| 766 private: |
| 767 inline void SkipUninteresting(); |
| 768 LInstruction* instr_; |
| 769 int limit_; |
| 770 int current_; |
| 771 }; |
| 772 |
| 773 |
| 774 // Iterator for non-constant input operands. |
| 775 class InputIterator BASE_EMBEDDED { |
| 776 public: |
| 777 inline explicit InputIterator(LInstruction* instr); |
| 778 inline bool Done(); |
| 779 inline LOperand* Current(); |
| 780 inline void Advance(); |
| 781 |
| 782 private: |
| 783 inline void SkipUninteresting(); |
| 784 LInstruction* instr_; |
| 785 int limit_; |
| 786 int current_; |
| 787 }; |
| 788 |
| 789 |
| 790 class UseIterator BASE_EMBEDDED { |
| 791 public: |
| 792 inline explicit UseIterator(LInstruction* instr); |
| 793 inline bool Done(); |
| 794 inline LOperand* Current(); |
| 795 inline void Advance(); |
| 796 |
| 797 private: |
| 798 InputIterator input_iterator_; |
| 799 DeepIterator env_iterator_; |
| 800 }; |
| 801 |
| 802 class LInstruction; |
| 803 class LCodeGen; |
| 750 } } // namespace v8::internal | 804 } } // namespace v8::internal |
| 751 | 805 |
| 752 #endif // V8_LITHIUM_H_ | 806 #endif // V8_LITHIUM_H_ |
| OLD | NEW |