| 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 "allocation.h" | 10 #include "allocation.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 enum Kind { | 28 enum Kind { |
| 29 INVALID, | 29 INVALID, |
| 30 UNALLOCATED, | 30 UNALLOCATED, |
| 31 CONSTANT_OPERAND, | 31 CONSTANT_OPERAND, |
| 32 STACK_SLOT, | 32 STACK_SLOT, |
| 33 DOUBLE_STACK_SLOT, | 33 DOUBLE_STACK_SLOT, |
| 34 REGISTER, | 34 REGISTER, |
| 35 DOUBLE_REGISTER | 35 DOUBLE_REGISTER |
| 36 }; | 36 }; |
| 37 | 37 |
| 38 LOperand() : value_(KindField::encode(INVALID)) { } | 38 LOperand() : value_(KindField::encode(INVALID)), parent_linstr_(NULL) { } |
| 39 | 39 |
| 40 Kind kind() const { return KindField::decode(value_); } | 40 Kind kind() const { return KindField::decode(value_); } |
| 41 int index() const { return static_cast<int>(value_) >> kKindFieldWidth; } | 41 int index() const { return static_cast<int>(value_) >> kKindFieldWidth; } |
| 42 #define LITHIUM_OPERAND_PREDICATE(name, type, number) \ | 42 #define LITHIUM_OPERAND_PREDICATE(name, type, number) \ |
| 43 bool Is##name() const { return kind() == type; } | 43 bool Is##name() const { return kind() == type; } |
| 44 LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_PREDICATE) | 44 LITHIUM_OPERAND_LIST(LITHIUM_OPERAND_PREDICATE) |
| 45 LITHIUM_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) | 45 LITHIUM_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) |
| 46 LITHIUM_OPERAND_PREDICATE(Ignored, INVALID, 0) | 46 LITHIUM_OPERAND_PREDICATE(Ignored, INVALID, 0) |
| 47 #undef LITHIUM_OPERAND_PREDICATE | 47 #undef LITHIUM_OPERAND_PREDICATE |
| 48 bool Equals(LOperand* other) const { return value_ == other->value_; } | 48 bool Equals(LOperand* other) const { return value_ == other->value_; } |
| 49 | 49 |
| 50 bool IsInMemory() const { return IsStackSlot() || IsDoubleStackSlot(); } |
| 51 bool IsInRegister() const { return IsRegister() || IsDoubleRegister(); } |
| 52 |
| 50 void PrintTo(StringStream* stream); | 53 void PrintTo(StringStream* stream); |
| 51 void ConvertTo(Kind kind, int index) { | 54 void ConvertTo(Kind kind, int index) { |
| 52 value_ = KindField::encode(kind); | 55 value_ = KindField::encode(kind); |
| 53 value_ |= index << kKindFieldWidth; | 56 value_ |= index << kKindFieldWidth; |
| 54 ASSERT(this->index() == index); | 57 ASSERT(this->index() == index); |
| 55 } | 58 } |
| 56 | 59 |
| 60 void set_parent_linstr(LInstruction* instr) { parent_linstr_ = instr; } |
| 61 LInstruction* parent_linstr() const { return parent_linstr_; } |
| 62 |
| 57 // Calls SetUpCache()/TearDownCache() for each subclass. | 63 // Calls SetUpCache()/TearDownCache() for each subclass. |
| 58 static void SetUpCaches(); | 64 static void SetUpCaches(); |
| 59 static void TearDownCaches(); | 65 static void TearDownCaches(); |
| 60 | 66 |
| 61 protected: | 67 protected: |
| 62 static const int kKindFieldWidth = 3; | 68 static const int kKindFieldWidth = 3; |
| 63 class KindField : public BitField<Kind, 0, kKindFieldWidth> { }; | 69 class KindField : public BitField<Kind, 0, kKindFieldWidth> { }; |
| 64 | 70 |
| 65 LOperand(Kind kind, int index) { ConvertTo(kind, index); } | 71 LOperand(Kind kind, int index) : parent_linstr_(NULL) { |
| 72 ConvertTo(kind, index); |
| 73 } |
| 66 | 74 |
| 67 unsigned value_; | 75 unsigned value_; |
| 76 LInstruction* parent_linstr_; |
| 68 }; | 77 }; |
| 69 | 78 |
| 70 | 79 |
| 71 class LUnallocated : public LOperand { | 80 class LUnallocated : public LOperand { |
| 72 public: | 81 public: |
| 73 enum BasicPolicy { | 82 enum BasicPolicy { |
| 74 FIXED_SLOT, | 83 FIXED_SLOT, |
| 75 EXTENDED_POLICY | 84 EXTENDED_POLICY |
| 76 }; | 85 }; |
| 77 | 86 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 124 LUnallocated(ExtendedPolicy policy, Lifetime lifetime) | 133 LUnallocated(ExtendedPolicy policy, Lifetime lifetime) |
| 125 : LOperand(UNALLOCATED, 0) { | 134 : LOperand(UNALLOCATED, 0) { |
| 126 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); | 135 value_ |= BasicPolicyField::encode(EXTENDED_POLICY); |
| 127 value_ |= ExtendedPolicyField::encode(policy); | 136 value_ |= ExtendedPolicyField::encode(policy); |
| 128 value_ |= LifetimeField::encode(lifetime); | 137 value_ |= LifetimeField::encode(lifetime); |
| 129 } | 138 } |
| 130 | 139 |
| 131 LUnallocated* CopyUnconstrained(Zone* zone) { | 140 LUnallocated* CopyUnconstrained(Zone* zone) { |
| 132 LUnallocated* result = new(zone) LUnallocated(ANY); | 141 LUnallocated* result = new(zone) LUnallocated(ANY); |
| 133 result->set_virtual_register(virtual_register()); | 142 result->set_virtual_register(virtual_register()); |
| 143 result->set_parent_linstr(parent_linstr()); |
| 134 return result; | 144 return result; |
| 135 } | 145 } |
| 136 | 146 |
| 137 static LUnallocated* cast(LOperand* op) { | 147 static LUnallocated* cast(LOperand* op) { |
| 138 ASSERT(op->IsUnallocated()); | 148 ASSERT(op->IsUnallocated()); |
| 139 return reinterpret_cast<LUnallocated*>(op); | 149 return reinterpret_cast<LUnallocated*>(op); |
| 140 } | 150 } |
| 141 | 151 |
| 142 // The encoding used for LUnallocated operands depends on the policy that is | 152 // The encoding used for LUnallocated operands depends on the policy that is |
| 143 // stored within the operand. The FIXED_SLOT policy uses a compact encoding | 153 // stored within the operand. The FIXED_SLOT policy uses a compact encoding |
| (...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 280 // A move is redundant if it's been eliminated, if its source and | 290 // A move is redundant if it's been eliminated, if its source and |
| 281 // destination are the same, or if its destination is unneeded. | 291 // destination are the same, or if its destination is unneeded. |
| 282 bool IsRedundant() const { | 292 bool IsRedundant() const { |
| 283 return IsEliminated() || source_->Equals(destination_) || IsIgnored(); | 293 return IsEliminated() || source_->Equals(destination_) || IsIgnored(); |
| 284 } | 294 } |
| 285 | 295 |
| 286 bool IsIgnored() const { | 296 bool IsIgnored() const { |
| 287 return destination_ != NULL && destination_->IsIgnored(); | 297 return destination_ != NULL && destination_->IsIgnored(); |
| 288 } | 298 } |
| 289 | 299 |
| 300 bool UsesRegeneration() const; |
| 301 |
| 290 // We clear both operands to indicate move that's been eliminated. | 302 // We clear both operands to indicate move that's been eliminated. |
| 291 void Eliminate() { source_ = destination_ = NULL; } | 303 void Eliminate() { source_ = destination_ = NULL; } |
| 292 bool IsEliminated() const { | 304 bool IsEliminated() const { |
| 293 ASSERT(source_ != NULL || destination_ == NULL); | 305 ASSERT(source_ != NULL || destination_ == NULL); |
| 294 return source_ == NULL; | 306 return source_ == NULL; |
| 295 } | 307 } |
| 296 | 308 |
| 297 private: | 309 private: |
| 298 LOperand* source_; | 310 LOperand* source_; |
| 299 LOperand* destination_; | 311 LOperand* destination_; |
| 300 }; | 312 }; |
| 301 | 313 |
| 302 | 314 |
| 303 template<LOperand::Kind kOperandKind, int kNumCachedOperands> | 315 template<LOperand::Kind kOperandKind, int kNumCachedOperands> |
| 304 class LSubKindOperand V8_FINAL : public LOperand { | 316 class LSubKindOperand V8_FINAL : public LOperand { |
| 305 public: | 317 public: |
| 306 static LSubKindOperand* Create(int index, Zone* zone) { | 318 static LSubKindOperand* Create(int index, Zone* zone, |
| 319 bool allow_use_cache = true) { |
| 307 ASSERT(index >= 0); | 320 ASSERT(index >= 0); |
| 308 if (index < kNumCachedOperands) return &cache[index]; | 321 if (allow_use_cache && (index < kNumCachedOperands)) return &cache[index]; |
| 309 return new(zone) LSubKindOperand(index); | 322 return new(zone) LSubKindOperand(index); |
| 310 } | 323 } |
| 311 | 324 |
| 312 static LSubKindOperand* cast(LOperand* op) { | 325 static LSubKindOperand* cast(LOperand* op) { |
| 313 ASSERT(op->kind() == kOperandKind); | 326 ASSERT(op->kind() == kOperandKind); |
| 314 return reinterpret_cast<LSubKindOperand*>(op); | 327 return reinterpret_cast<LSubKindOperand*>(op); |
| 315 } | 328 } |
| 316 | 329 |
| 317 static void SetUpCache(); | 330 static void SetUpCache(); |
| 318 static void TearDownCache(); | 331 static void TearDownCache(); |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 743 private: | 756 private: |
| 744 LChunk* chunk_; | 757 LChunk* chunk_; |
| 745 | 758 |
| 746 DISALLOW_COPY_AND_ASSIGN(LPhase); | 759 DISALLOW_COPY_AND_ASSIGN(LPhase); |
| 747 }; | 760 }; |
| 748 | 761 |
| 749 | 762 |
| 750 } } // namespace v8::internal | 763 } } // namespace v8::internal |
| 751 | 764 |
| 752 #endif // V8_LITHIUM_H_ | 765 #endif // V8_LITHIUM_H_ |
| OLD | NEW |