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 |