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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 | 52 |
53 Kind kind() const { return KindField::decode(value_); } | 53 Kind kind() const { return KindField::decode(value_); } |
54 int index() const { return static_cast<int>(value_) >> kKindFieldWidth; } | 54 int index() const { return static_cast<int>(value_) >> kKindFieldWidth; } |
55 bool IsConstantOperand() const { return kind() == CONSTANT_OPERAND; } | 55 bool IsConstantOperand() const { return kind() == CONSTANT_OPERAND; } |
56 bool IsStackSlot() const { return kind() == STACK_SLOT; } | 56 bool IsStackSlot() const { return kind() == STACK_SLOT; } |
57 bool IsDoubleStackSlot() const { return kind() == DOUBLE_STACK_SLOT; } | 57 bool IsDoubleStackSlot() const { return kind() == DOUBLE_STACK_SLOT; } |
58 bool IsRegister() const { return kind() == REGISTER; } | 58 bool IsRegister() const { return kind() == REGISTER; } |
59 bool IsDoubleRegister() const { return kind() == DOUBLE_REGISTER; } | 59 bool IsDoubleRegister() const { return kind() == DOUBLE_REGISTER; } |
60 bool IsArgument() const { return kind() == ARGUMENT; } | 60 bool IsArgument() const { return kind() == ARGUMENT; } |
61 bool IsUnallocated() const { return kind() == UNALLOCATED; } | 61 bool IsUnallocated() const { return kind() == UNALLOCATED; } |
| 62 bool IsIgnored() const { return kind() == INVALID; } |
62 bool Equals(LOperand* other) const { return value_ == other->value_; } | 63 bool Equals(LOperand* other) const { return value_ == other->value_; } |
63 int VirtualRegister(); | 64 int VirtualRegister(); |
64 | 65 |
65 void PrintTo(StringStream* stream); | 66 void PrintTo(StringStream* stream); |
66 void ConvertTo(Kind kind, int index) { | 67 void ConvertTo(Kind kind, int index) { |
67 value_ = KindField::encode(kind); | 68 value_ = KindField::encode(kind); |
68 value_ |= index << kKindFieldWidth; | 69 value_ |= index << kKindFieldWidth; |
69 ASSERT(this->index() == index); | 70 ASSERT(this->index() == index); |
70 } | 71 } |
71 | 72 |
(...skipping 10 matching lines...) Expand all Loading... |
82 class LUnallocated: public LOperand { | 83 class LUnallocated: public LOperand { |
83 public: | 84 public: |
84 enum Policy { | 85 enum Policy { |
85 NONE, | 86 NONE, |
86 ANY, | 87 ANY, |
87 FIXED_REGISTER, | 88 FIXED_REGISTER, |
88 FIXED_DOUBLE_REGISTER, | 89 FIXED_DOUBLE_REGISTER, |
89 FIXED_SLOT, | 90 FIXED_SLOT, |
90 MUST_HAVE_REGISTER, | 91 MUST_HAVE_REGISTER, |
91 WRITABLE_REGISTER, | 92 WRITABLE_REGISTER, |
92 SAME_AS_FIRST_INPUT, | 93 SAME_AS_FIRST_INPUT |
93 IGNORE | |
94 }; | 94 }; |
95 | 95 |
96 // Lifetime of operand inside the instruction. | 96 // Lifetime of operand inside the instruction. |
97 enum Lifetime { | 97 enum Lifetime { |
98 // USED_AT_START operand is guaranteed to be live only at | 98 // USED_AT_START operand is guaranteed to be live only at |
99 // instruction start. Register allocator is free to assign the same register | 99 // instruction start. Register allocator is free to assign the same register |
100 // to some other operand used inside instruction (i.e. temporary or | 100 // to some other operand used inside instruction (i.e. temporary or |
101 // output). | 101 // output). |
102 USED_AT_START, | 102 USED_AT_START, |
103 | 103 |
(...skipping 10 matching lines...) Expand all Loading... |
114 LUnallocated(Policy policy, int fixed_index) : LOperand(UNALLOCATED, 0) { | 114 LUnallocated(Policy policy, int fixed_index) : LOperand(UNALLOCATED, 0) { |
115 Initialize(policy, fixed_index, USED_AT_END); | 115 Initialize(policy, fixed_index, USED_AT_END); |
116 } | 116 } |
117 | 117 |
118 LUnallocated(Policy policy, Lifetime lifetime) : LOperand(UNALLOCATED, 0) { | 118 LUnallocated(Policy policy, Lifetime lifetime) : LOperand(UNALLOCATED, 0) { |
119 Initialize(policy, 0, lifetime); | 119 Initialize(policy, 0, lifetime); |
120 } | 120 } |
121 | 121 |
122 // The superclass has a KindField. Some policies have a signed fixed | 122 // The superclass has a KindField. Some policies have a signed fixed |
123 // index in the upper bits. | 123 // index in the upper bits. |
124 static const int kPolicyWidth = 4; | 124 static const int kPolicyWidth = 3; |
125 static const int kLifetimeWidth = 1; | 125 static const int kLifetimeWidth = 1; |
126 static const int kVirtualRegisterWidth = 17; | 126 static const int kVirtualRegisterWidth = 18; |
127 | 127 |
128 static const int kPolicyShift = kKindFieldWidth; | 128 static const int kPolicyShift = kKindFieldWidth; |
129 static const int kLifetimeShift = kPolicyShift + kPolicyWidth; | 129 static const int kLifetimeShift = kPolicyShift + kPolicyWidth; |
130 static const int kVirtualRegisterShift = kLifetimeShift + kLifetimeWidth; | 130 static const int kVirtualRegisterShift = kLifetimeShift + kLifetimeWidth; |
131 static const int kFixedIndexShift = | 131 static const int kFixedIndexShift = |
132 kVirtualRegisterShift + kVirtualRegisterWidth; | 132 kVirtualRegisterShift + kVirtualRegisterWidth; |
133 | 133 |
134 class PolicyField : public BitField<Policy, kPolicyShift, kPolicyWidth> { }; | 134 class PolicyField : public BitField<Policy, kPolicyShift, kPolicyWidth> { }; |
135 | 135 |
136 class LifetimeField | 136 class LifetimeField |
137 : public BitField<Lifetime, kLifetimeShift, kLifetimeWidth> { | 137 : public BitField<Lifetime, kLifetimeShift, kLifetimeWidth> { |
138 }; | 138 }; |
139 | 139 |
140 class VirtualRegisterField | 140 class VirtualRegisterField |
141 : public BitField<unsigned, | 141 : public BitField<unsigned, |
142 kVirtualRegisterShift, | 142 kVirtualRegisterShift, |
143 kVirtualRegisterWidth> { | 143 kVirtualRegisterWidth> { |
144 }; | 144 }; |
145 | 145 |
146 static const int kMaxVirtualRegisters = 1 << (kVirtualRegisterWidth + 1); | 146 static const int kMaxVirtualRegisters = 1 << kVirtualRegisterWidth; |
147 static const int kMaxFixedIndex = 63; | 147 static const int kMaxFixedIndex = 63; |
148 static const int kMinFixedIndex = -64; | 148 static const int kMinFixedIndex = -64; |
149 | 149 |
150 bool HasIgnorePolicy() const { return policy() == IGNORE; } | |
151 bool HasNoPolicy() const { return policy() == NONE; } | |
152 bool HasAnyPolicy() const { | 150 bool HasAnyPolicy() const { |
153 return policy() == ANY; | 151 return policy() == ANY; |
154 } | 152 } |
155 bool HasFixedPolicy() const { | 153 bool HasFixedPolicy() const { |
156 return policy() == FIXED_REGISTER || | 154 return policy() == FIXED_REGISTER || |
157 policy() == FIXED_DOUBLE_REGISTER || | 155 policy() == FIXED_DOUBLE_REGISTER || |
158 policy() == FIXED_SLOT; | 156 policy() == FIXED_SLOT; |
159 } | 157 } |
160 bool HasRegisterPolicy() const { | 158 bool HasRegisterPolicy() const { |
161 return policy() == WRITABLE_REGISTER || policy() == MUST_HAVE_REGISTER; | 159 return policy() == WRITABLE_REGISTER || policy() == MUST_HAVE_REGISTER; |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
227 return !IsEliminated() && source()->Equals(operand); | 225 return !IsEliminated() && source()->Equals(operand); |
228 } | 226 } |
229 | 227 |
230 // A move is redundant if it's been eliminated, if its source and | 228 // A move is redundant if it's been eliminated, if its source and |
231 // destination are the same, or if its destination is unneeded. | 229 // destination are the same, or if its destination is unneeded. |
232 bool IsRedundant() const { | 230 bool IsRedundant() const { |
233 return IsEliminated() || source_->Equals(destination_) || IsIgnored(); | 231 return IsEliminated() || source_->Equals(destination_) || IsIgnored(); |
234 } | 232 } |
235 | 233 |
236 bool IsIgnored() const { | 234 bool IsIgnored() const { |
237 return destination_ != NULL && | 235 return destination_ != NULL && destination_->IsIgnored(); |
238 destination_->IsUnallocated() && | |
239 LUnallocated::cast(destination_)->HasIgnorePolicy(); | |
240 } | 236 } |
241 | 237 |
242 // We clear both operands to indicate move that's been eliminated. | 238 // We clear both operands to indicate move that's been eliminated. |
243 void Eliminate() { source_ = destination_ = NULL; } | 239 void Eliminate() { source_ = destination_ = NULL; } |
244 bool IsEliminated() const { | 240 bool IsEliminated() const { |
245 ASSERT(source_ != NULL || destination_ == NULL); | 241 ASSERT(source_ != NULL || destination_ == NULL); |
246 return source_ == NULL; | 242 return source_ == NULL; |
247 } | 243 } |
248 | 244 |
249 private: | 245 private: |
(...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 ShallowIterator current_iterator_; | 595 ShallowIterator current_iterator_; |
600 }; | 596 }; |
601 | 597 |
602 | 598 |
603 int ElementsKindToShiftSize(ElementsKind elements_kind); | 599 int ElementsKindToShiftSize(ElementsKind elements_kind); |
604 | 600 |
605 | 601 |
606 } } // namespace v8::internal | 602 } } // namespace v8::internal |
607 | 603 |
608 #endif // V8_LITHIUM_H_ | 604 #endif // V8_LITHIUM_H_ |
OLD | NEW |