OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_REGISTER_ALLOCATOR_H_ | 5 #ifndef V8_REGISTER_ALLOCATOR_H_ |
6 #define V8_REGISTER_ALLOCATOR_H_ | 6 #define V8_REGISTER_ALLOCATOR_H_ |
7 | 7 |
8 #include "src/compiler/instruction.h" | 8 #include "src/compiler/instruction.h" |
9 #include "src/zone-containers.h" | 9 #include "src/zone-containers.h" |
10 | 10 |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
134 | 134 |
135 LifetimePosition start_; | 135 LifetimePosition start_; |
136 LifetimePosition end_; | 136 LifetimePosition end_; |
137 UseInterval* next_; | 137 UseInterval* next_; |
138 | 138 |
139 private: | 139 private: |
140 DISALLOW_COPY_AND_ASSIGN(UseInterval); | 140 DISALLOW_COPY_AND_ASSIGN(UseInterval); |
141 }; | 141 }; |
142 | 142 |
143 | 143 |
| 144 enum class UsePositionType : uint8_t { kAny, kRequiresRegister, kRequiresSlot }; |
| 145 |
| 146 |
144 // Representation of a use position. | 147 // Representation of a use position. |
145 class UsePosition FINAL : public ZoneObject { | 148 class UsePosition FINAL : public ZoneObject { |
146 public: | 149 public: |
147 UsePosition(LifetimePosition pos, InstructionOperand* operand, | 150 UsePosition(LifetimePosition pos, InstructionOperand* operand, |
148 InstructionOperand* hint); | 151 InstructionOperand* hint); |
149 | 152 |
150 InstructionOperand* operand() const { return operand_; } | 153 InstructionOperand* operand() const { return operand_; } |
151 bool HasOperand() const { return operand_ != nullptr; } | 154 bool HasOperand() const { return operand_ != nullptr; } |
152 | 155 |
153 InstructionOperand* hint() const { return hint_; } | 156 InstructionOperand* hint() const { return hint_; } |
154 bool HasHint() const; | 157 bool HasHint() const; |
155 bool RequiresRegister() const; | 158 bool RegisterIsBeneficial() const { |
156 bool RegisterIsBeneficial() const; | 159 return RegisterBeneficialField::decode(flags_); |
| 160 } |
| 161 UsePositionType type() const { return TypeField::decode(flags_); } |
157 | 162 |
158 LifetimePosition pos() const { return pos_; } | 163 LifetimePosition pos() const { return pos_; } |
159 UsePosition* next() const { return next_; } | 164 UsePosition* next() const { return next_; } |
160 | 165 |
161 void set_next(UsePosition* next) { next_ = next; } | 166 void set_next(UsePosition* next) { next_ = next; } |
| 167 void set_type(UsePositionType type, bool register_beneficial); |
162 | 168 |
163 InstructionOperand* const operand_; | 169 InstructionOperand* const operand_; |
164 InstructionOperand* const hint_; | 170 InstructionOperand* const hint_; |
165 LifetimePosition const pos_; | 171 LifetimePosition const pos_; |
166 UsePosition* next_; | 172 UsePosition* next_; |
167 bool requires_reg_ : 1; | |
168 bool register_beneficial_ : 1; | |
169 | 173 |
170 private: | 174 private: |
| 175 typedef BitField8<UsePositionType, 0, 2> TypeField; |
| 176 typedef BitField8<bool, 2, 1> RegisterBeneficialField; |
| 177 uint8_t flags_; |
| 178 |
171 DISALLOW_COPY_AND_ASSIGN(UsePosition); | 179 DISALLOW_COPY_AND_ASSIGN(UsePosition); |
172 }; | 180 }; |
173 | 181 |
174 class SpillRange; | 182 class SpillRange; |
175 | 183 |
176 | 184 |
177 // TODO(dcarney): remove this cache. | 185 // TODO(dcarney): remove this cache. |
178 class InstructionOperandCache FINAL : public ZoneObject { | 186 class InstructionOperandCache FINAL : public ZoneObject { |
179 public: | 187 public: |
180 InstructionOperandCache(); | 188 InstructionOperandCache(); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
226 int assigned_register() const { return assigned_register_; } | 234 int assigned_register() const { return assigned_register_; } |
227 int spill_start_index() const { return spill_start_index_; } | 235 int spill_start_index() const { return spill_start_index_; } |
228 void set_assigned_register(int reg, InstructionOperandCache* cache); | 236 void set_assigned_register(int reg, InstructionOperandCache* cache); |
229 void MakeSpilled(); | 237 void MakeSpilled(); |
230 bool is_phi() const { return is_phi_; } | 238 bool is_phi() const { return is_phi_; } |
231 void set_is_phi(bool is_phi) { is_phi_ = is_phi; } | 239 void set_is_phi(bool is_phi) { is_phi_ = is_phi; } |
232 bool is_non_loop_phi() const { return is_non_loop_phi_; } | 240 bool is_non_loop_phi() const { return is_non_loop_phi_; } |
233 void set_is_non_loop_phi(bool is_non_loop_phi) { | 241 void set_is_non_loop_phi(bool is_non_loop_phi) { |
234 is_non_loop_phi_ = is_non_loop_phi; | 242 is_non_loop_phi_ = is_non_loop_phi; |
235 } | 243 } |
| 244 bool has_slot_use() const { return has_slot_use_; } |
| 245 void set_has_slot_use(bool has_slot_use) { has_slot_use_ = has_slot_use; } |
236 | 246 |
237 // Returns use position in this live range that follows both start | 247 // Returns use position in this live range that follows both start |
238 // and last processed use position. | 248 // and last processed use position. |
239 // Modifies internal state of live range! | 249 // Modifies internal state of live range! |
240 UsePosition* NextUsePosition(LifetimePosition start); | 250 UsePosition* NextUsePosition(LifetimePosition start); |
241 | 251 |
242 // Returns use position for which register is required in this live | 252 // Returns use position for which register is required in this live |
243 // range and which follows both start and last processed use position | 253 // range and which follows both start and last processed use position |
244 // Modifies internal state of live range! | 254 // Modifies internal state of live range! |
245 UsePosition* NextRegisterPosition(LifetimePosition start); | 255 UsePosition* NextRegisterPosition(LifetimePosition start); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
302 return spill_type_ == SpillType::kSpillOperand; | 312 return spill_type_ == SpillType::kSpillOperand; |
303 } | 313 } |
304 bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; } | 314 bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; } |
305 | 315 |
306 void SpillAtDefinition(Zone* zone, int gap_index, | 316 void SpillAtDefinition(Zone* zone, int gap_index, |
307 InstructionOperand* operand); | 317 InstructionOperand* operand); |
308 void SetSpillOperand(InstructionOperand* operand); | 318 void SetSpillOperand(InstructionOperand* operand); |
309 void SetSpillRange(SpillRange* spill_range); | 319 void SetSpillRange(SpillRange* spill_range); |
310 void CommitSpillOperand(InstructionOperand* operand); | 320 void CommitSpillOperand(InstructionOperand* operand); |
311 void CommitSpillsAtDefinition(InstructionSequence* sequence, | 321 void CommitSpillsAtDefinition(InstructionSequence* sequence, |
312 InstructionOperand* operand); | 322 InstructionOperand* operand, |
| 323 bool might_be_duplicated); |
313 | 324 |
314 void SetSpillStartIndex(int start) { | 325 void SetSpillStartIndex(int start) { |
315 spill_start_index_ = Min(start, spill_start_index_); | 326 spill_start_index_ = Min(start, spill_start_index_); |
316 } | 327 } |
317 | 328 |
318 bool ShouldBeAllocatedBefore(const LiveRange* other) const; | 329 bool ShouldBeAllocatedBefore(const LiveRange* other) const; |
319 bool CanCover(LifetimePosition position) const; | 330 bool CanCover(LifetimePosition position) const; |
320 bool Covers(LifetimePosition position); | 331 bool Covers(LifetimePosition position); |
321 LifetimePosition FirstIntersection(LiveRange* other); | 332 LifetimePosition FirstIntersection(LiveRange* other); |
322 | 333 |
323 // Add a new interval or a new use position to this live range. | 334 // Add a new interval or a new use position to this live range. |
324 void EnsureInterval(LifetimePosition start, LifetimePosition end, Zone* zone); | 335 void EnsureInterval(LifetimePosition start, LifetimePosition end, Zone* zone); |
325 void AddUseInterval(LifetimePosition start, LifetimePosition end, Zone* zone); | 336 void AddUseInterval(LifetimePosition start, LifetimePosition end, Zone* zone); |
326 void AddUsePosition(LifetimePosition pos, InstructionOperand* operand, | 337 void AddUsePosition(LifetimePosition pos, InstructionOperand* operand, |
327 InstructionOperand* hint, Zone* zone); | 338 InstructionOperand* hint, Zone* zone); |
328 | 339 |
329 // Shorten the most recently added interval by setting a new start. | 340 // Shorten the most recently added interval by setting a new start. |
330 void ShortenTo(LifetimePosition start); | 341 void ShortenTo(LifetimePosition start); |
331 | 342 |
332 #ifdef DEBUG | 343 #ifdef DEBUG |
333 // True if target overlaps an existing interval. | 344 // True if target overlaps an existing interval. |
334 bool HasOverlap(UseInterval* target) const; | 345 bool HasOverlap(UseInterval* target) const; |
335 void Verify() const; | 346 void Verify() const; |
336 #endif | 347 #endif |
337 | 348 |
338 private: | 349 private: |
339 struct SpillAtDefinitionList; | 350 struct SpillAtDefinitionList; |
340 | 351 |
341 void ConvertUsesToOperand(InstructionOperand* op); | 352 void ConvertUsesToOperand(InstructionOperand* op, |
| 353 InstructionOperand* spill_op); |
342 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; | 354 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; |
343 void AdvanceLastProcessedMarker(UseInterval* to_start_of, | 355 void AdvanceLastProcessedMarker(UseInterval* to_start_of, |
344 LifetimePosition but_not_past) const; | 356 LifetimePosition but_not_past) const; |
345 | 357 |
346 // TODO(dcarney): pack this structure better. | 358 // TODO(dcarney): pack this structure better. |
347 int id_; | 359 int id_; |
348 bool spilled_; | 360 bool spilled_ : 1; |
349 bool is_phi_; | 361 bool has_slot_use_ : 1; // Relevant only for parent. |
350 bool is_non_loop_phi_; | 362 bool is_phi_ : 1; |
| 363 bool is_non_loop_phi_ : 1; |
351 RegisterKind kind_; | 364 RegisterKind kind_; |
352 int assigned_register_; | 365 int assigned_register_; |
353 UseInterval* last_interval_; | 366 UseInterval* last_interval_; |
354 UseInterval* first_interval_; | 367 UseInterval* first_interval_; |
355 UsePosition* first_pos_; | 368 UsePosition* first_pos_; |
356 LiveRange* parent_; | 369 LiveRange* parent_; |
357 LiveRange* next_; | 370 LiveRange* next_; |
358 // This is used as a cache, it doesn't affect correctness. | 371 // This is used as a cache, it doesn't affect correctness. |
359 mutable UseInterval* current_interval_; | 372 mutable UseInterval* current_interval_; |
360 UsePosition* last_processed_use_; | 373 UsePosition* last_processed_use_; |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
641 #endif | 654 #endif |
642 | 655 |
643 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); | 656 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); |
644 }; | 657 }; |
645 | 658 |
646 } // namespace compiler | 659 } // namespace compiler |
647 } // namespace internal | 660 } // namespace internal |
648 } // namespace v8 | 661 } // namespace v8 |
649 | 662 |
650 #endif // V8_REGISTER_ALLOCATOR_H_ | 663 #endif // V8_REGISTER_ALLOCATOR_H_ |
OLD | NEW |