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_ALLOCATOR_H_ | 5 #ifndef V8_LITHIUM_ALLOCATOR_H_ |
6 #define V8_LITHIUM_ALLOCATOR_H_ | 6 #define V8_LITHIUM_ALLOCATOR_H_ |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/allocation.h" | 10 #include "src/allocation.h" |
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 } | 146 } |
147 | 147 |
148 private: | 148 private: |
149 void set_start(LifetimePosition start) { start_ = start; } | 149 void set_start(LifetimePosition start) { start_ = start; } |
150 void set_next(UseInterval* next) { next_ = next; } | 150 void set_next(UseInterval* next) { next_ = next; } |
151 | 151 |
152 LifetimePosition start_; | 152 LifetimePosition start_; |
153 LifetimePosition end_; | 153 LifetimePosition end_; |
154 UseInterval* next_; | 154 UseInterval* next_; |
155 | 155 |
| 156 friend class LAllocator; // Assigns to next_. |
| 157 friend class SpillRange; // Assigns to next_. |
156 friend class LiveRange; // Assigns to start_. | 158 friend class LiveRange; // Assigns to start_. |
157 }; | 159 }; |
158 | 160 |
159 // Representation of a use position. | 161 // Representation of a use position. |
160 class UsePosition: public ZoneObject { | 162 class UsePosition: public ZoneObject { |
161 public: | 163 public: |
162 UsePosition(LifetimePosition pos, LOperand* operand, LOperand* hint); | 164 UsePosition(LifetimePosition pos, LOperand* operand, LOperand* hint); |
163 | 165 |
164 LOperand* operand() const { return operand_; } | 166 LOperand* operand() const { return operand_; } |
165 bool HasOperand() const { return operand_ != NULL; } | 167 bool HasOperand() const { return operand_ != NULL; } |
(...skipping 12 matching lines...) Expand all Loading... |
178 LOperand* const operand_; | 180 LOperand* const operand_; |
179 LOperand* const hint_; | 181 LOperand* const hint_; |
180 LifetimePosition const pos_; | 182 LifetimePosition const pos_; |
181 UsePosition* next_; | 183 UsePosition* next_; |
182 bool requires_reg_; | 184 bool requires_reg_; |
183 bool register_beneficial_; | 185 bool register_beneficial_; |
184 | 186 |
185 friend class LiveRange; | 187 friend class LiveRange; |
186 }; | 188 }; |
187 | 189 |
| 190 class SpillRange; |
| 191 |
188 // Representation of SSA values' live ranges as a collection of (continuous) | 192 // Representation of SSA values' live ranges as a collection of (continuous) |
189 // intervals over the instruction ordering. | 193 // intervals over the instruction ordering. |
190 class LiveRange: public ZoneObject { | 194 class LiveRange: public ZoneObject { |
191 public: | 195 public: |
192 static const int kInvalidAssignment = 0x7fffffff; | 196 static const int kInvalidAssignment = 0x7fffffff; |
193 | 197 |
194 LiveRange(int id, Zone* zone); | 198 LiveRange(int id, Zone* zone); |
195 | 199 |
196 UseInterval* first_interval() const { return first_interval_; } | 200 UseInterval* first_interval() const { return first_interval_; } |
197 UsePosition* first_pos() const { return first_pos_; } | 201 UsePosition* first_pos() const { return first_pos_; } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 | 264 |
261 LifetimePosition End() const { | 265 LifetimePosition End() const { |
262 DCHECK(!IsEmpty()); | 266 DCHECK(!IsEmpty()); |
263 return last_interval_->end(); | 267 return last_interval_->end(); |
264 } | 268 } |
265 | 269 |
266 bool HasAllocatedSpillOperand() const; | 270 bool HasAllocatedSpillOperand() const; |
267 LOperand* GetSpillOperand() const { return spill_operand_; } | 271 LOperand* GetSpillOperand() const { return spill_operand_; } |
268 void SetSpillOperand(LOperand* operand); | 272 void SetSpillOperand(LOperand* operand); |
269 | 273 |
| 274 void SetSpillRange(SpillRange* spill_range) { spill_range_ = spill_range; } |
| 275 SpillRange* GetSpillRange() const { return spill_range_; } |
| 276 void CommitSpillOperand(LOperand* operand); |
| 277 |
270 void SetSpillStartIndex(int start) { | 278 void SetSpillStartIndex(int start) { |
271 spill_start_index_ = Min(start, spill_start_index_); | 279 spill_start_index_ = Min(start, spill_start_index_); |
272 } | 280 } |
273 | 281 |
274 bool ShouldBeAllocatedBefore(const LiveRange* other) const; | 282 bool ShouldBeAllocatedBefore(const LiveRange* other) const; |
275 bool CanCover(LifetimePosition position) const; | 283 bool CanCover(LifetimePosition position) const; |
276 bool Covers(LifetimePosition position); | 284 bool Covers(LifetimePosition position); |
277 LifetimePosition FirstIntersection(LiveRange* other); | 285 LifetimePosition FirstIntersection(LiveRange* other); |
278 | 286 |
279 // Add a new interval or a new use position to this live range. | 287 // Add a new interval or a new use position to this live range. |
(...skipping 12 matching lines...) Expand all Loading... |
292 void ShortenTo(LifetimePosition start); | 300 void ShortenTo(LifetimePosition start); |
293 | 301 |
294 #ifdef DEBUG | 302 #ifdef DEBUG |
295 // True if target overlaps an existing interval. | 303 // True if target overlaps an existing interval. |
296 bool HasOverlap(UseInterval* target) const; | 304 bool HasOverlap(UseInterval* target) const; |
297 void Verify() const; | 305 void Verify() const; |
298 #endif | 306 #endif |
299 | 307 |
300 private: | 308 private: |
301 void ConvertOperands(Zone* zone); | 309 void ConvertOperands(Zone* zone); |
| 310 void ConvertUsesToOperand(LOperand* op); |
302 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; | 311 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; |
303 void AdvanceLastProcessedMarker(UseInterval* to_start_of, | 312 void AdvanceLastProcessedMarker(UseInterval* to_start_of, |
304 LifetimePosition but_not_past) const; | 313 LifetimePosition but_not_past) const; |
305 | 314 |
306 int id_; | 315 int id_; |
307 bool spilled_; | 316 bool spilled_; |
308 RegisterKind kind_; | 317 RegisterKind kind_; |
309 int assigned_register_; | 318 int assigned_register_; |
310 UseInterval* last_interval_; | 319 UseInterval* last_interval_; |
311 UseInterval* first_interval_; | 320 UseInterval* first_interval_; |
312 UsePosition* first_pos_; | 321 UsePosition* first_pos_; |
313 LiveRange* parent_; | 322 LiveRange* parent_; |
314 LiveRange* next_; | 323 LiveRange* next_; |
315 // This is used as a cache, it doesn't affect correctness. | 324 // This is used as a cache, it doesn't affect correctness. |
316 mutable UseInterval* current_interval_; | 325 mutable UseInterval* current_interval_; |
317 UsePosition* last_processed_use_; | 326 UsePosition* last_processed_use_; |
318 // This is used as a cache, it's invalid outside of BuildLiveRanges. | 327 // This is used as a cache, it's invalid outside of BuildLiveRanges. |
319 LOperand* current_hint_operand_; | 328 LOperand* current_hint_operand_; |
320 LOperand* spill_operand_; | 329 LOperand* spill_operand_; |
321 int spill_start_index_; | 330 int spill_start_index_; |
| 331 SpillRange* spill_range_; |
322 | 332 |
323 friend class LAllocator; // Assigns to kind_. | 333 friend class LAllocator; // Assigns to kind_. |
324 }; | 334 }; |
325 | 335 |
326 | 336 |
| 337 class SpillRange : public ZoneObject { |
| 338 public: |
| 339 SpillRange(LiveRange* range, int id, Zone* zone); |
| 340 |
| 341 bool TryMerge(SpillRange* other, Zone* zone); |
| 342 void SetOperand(LOperand* op); |
| 343 bool IsEmpty() { return live_ranges_.length() == 0; } |
| 344 int id() const { return id_; } |
| 345 UseInterval* interval() { return use_interval_; } |
| 346 RegisterKind Kind() const { return live_ranges_.at(0)->Kind(); } |
| 347 LifetimePosition End() const { return end_position_; } |
| 348 bool IsIntersectingWith(SpillRange* other); |
| 349 |
| 350 private: |
| 351 int id_; |
| 352 ZoneList<LiveRange*> live_ranges_; |
| 353 UseInterval* use_interval_; |
| 354 LifetimePosition end_position_; |
| 355 |
| 356 // Merge intervals, making sure the use intervals are sorted |
| 357 void MergeDisjointIntervals(UseInterval* other, Zone* zone); |
| 358 }; |
| 359 |
| 360 |
327 class LAllocator BASE_EMBEDDED { | 361 class LAllocator BASE_EMBEDDED { |
328 public: | 362 public: |
329 LAllocator(int first_virtual_register, HGraph* graph); | 363 LAllocator(int first_virtual_register, HGraph* graph); |
330 | 364 |
331 static void TraceAlloc(const char* msg, ...); | 365 static void TraceAlloc(const char* msg, ...); |
332 | 366 |
333 // Checks whether the value of a given virtual register is tagged. | 367 // Checks whether the value of a given virtual register is tagged. |
334 bool HasTaggedValue(int virtual_register) const; | 368 bool HasTaggedValue(int virtual_register) const; |
335 | 369 |
336 // Returns the register kind required by the given virtual register. | 370 // Returns the register kind required by the given virtual register. |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
383 private: | 417 private: |
384 void MeetRegisterConstraints(); | 418 void MeetRegisterConstraints(); |
385 void ResolvePhis(); | 419 void ResolvePhis(); |
386 void BuildLiveRanges(); | 420 void BuildLiveRanges(); |
387 void AllocateGeneralRegisters(); | 421 void AllocateGeneralRegisters(); |
388 void AllocateDoubleRegisters(); | 422 void AllocateDoubleRegisters(); |
389 void ConnectRanges(); | 423 void ConnectRanges(); |
390 void ResolveControlFlow(); | 424 void ResolveControlFlow(); |
391 void PopulatePointerMaps(); | 425 void PopulatePointerMaps(); |
392 void AllocateRegisters(); | 426 void AllocateRegisters(); |
| 427 void ReuseSpillSlots(); |
393 bool CanEagerlyResolveControlFlow(HBasicBlock* block) const; | 428 bool CanEagerlyResolveControlFlow(HBasicBlock* block) const; |
394 inline bool SafePointsAreInOrder() const; | 429 inline bool SafePointsAreInOrder() const; |
395 | 430 |
396 // Liveness analysis support. | 431 // Liveness analysis support. |
397 void InitializeLivenessAnalysis(); | 432 void InitializeLivenessAnalysis(); |
398 BitVector* ComputeLiveOut(HBasicBlock* block); | 433 BitVector* ComputeLiveOut(HBasicBlock* block); |
399 void AddInitialIntervals(HBasicBlock* block, BitVector* live_out); | 434 void AddInitialIntervals(HBasicBlock* block, BitVector* live_out); |
400 void ProcessInstructions(HBasicBlock* block, BitVector* live); | 435 void ProcessInstructions(HBasicBlock* block, BitVector* live); |
401 void MeetRegisterConstraints(HBasicBlock* block); | 436 void MeetRegisterConstraints(HBasicBlock* block); |
402 void MeetConstraintsBetween(LInstruction* first, | 437 void MeetConstraintsBetween(LInstruction* first, |
(...skipping 15 matching lines...) Expand all Loading... |
418 void AddToActive(LiveRange* range); | 453 void AddToActive(LiveRange* range); |
419 void AddToInactive(LiveRange* range); | 454 void AddToInactive(LiveRange* range); |
420 void AddToUnhandledSorted(LiveRange* range); | 455 void AddToUnhandledSorted(LiveRange* range); |
421 void AddToUnhandledUnsorted(LiveRange* range); | 456 void AddToUnhandledUnsorted(LiveRange* range); |
422 void SortUnhandled(); | 457 void SortUnhandled(); |
423 bool UnhandledIsSorted(); | 458 bool UnhandledIsSorted(); |
424 void ActiveToHandled(LiveRange* range); | 459 void ActiveToHandled(LiveRange* range); |
425 void ActiveToInactive(LiveRange* range); | 460 void ActiveToInactive(LiveRange* range); |
426 void InactiveToHandled(LiveRange* range); | 461 void InactiveToHandled(LiveRange* range); |
427 void InactiveToActive(LiveRange* range); | 462 void InactiveToActive(LiveRange* range); |
428 void FreeSpillSlot(LiveRange* range); | 463 SpillRange* AssignSpillRangeToLiveRange(LiveRange* range); |
429 LOperand* TryReuseSpillSlot(LiveRange* range); | |
430 | 464 |
431 // Helper methods for allocating registers. | 465 // Helper methods for allocating registers. |
432 bool TryAllocateFreeReg(LiveRange* range); | 466 bool TryAllocateFreeReg(LiveRange* range); |
433 void AllocateBlockedReg(LiveRange* range); | 467 void AllocateBlockedReg(LiveRange* range); |
| 468 bool TryReuseSpillForPhi(LiveRange* range); |
434 | 469 |
435 // Live range splitting helpers. | 470 // Live range splitting helpers. |
436 | 471 |
437 // Split the given range at the given position. | 472 // Split the given range at the given position. |
438 // If range starts at or after the given position then the | 473 // If range starts at or after the given position then the |
439 // original range is returned. | 474 // original range is returned. |
440 // Otherwise returns the live range that starts at pos and contains | 475 // Otherwise returns the live range that starts at pos and contains |
441 // all uses from the original range that follow pos. Uses at pos will | 476 // all uses from the original range that follow pos. Uses at pos will |
442 // still be owned by the original range after splitting. | 477 // still be owned by the original range after splitting. |
443 LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos); | 478 LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos); |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
523 | 558 |
524 // Lists of live ranges | 559 // Lists of live ranges |
525 EmbeddedVector<LiveRange*, Register::kMaxNumAllocatableRegisters> | 560 EmbeddedVector<LiveRange*, Register::kMaxNumAllocatableRegisters> |
526 fixed_live_ranges_; | 561 fixed_live_ranges_; |
527 EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumAllocatableRegisters> | 562 EmbeddedVector<LiveRange*, DoubleRegister::kMaxNumAllocatableRegisters> |
528 fixed_double_live_ranges_; | 563 fixed_double_live_ranges_; |
529 ZoneList<LiveRange*> unhandled_live_ranges_; | 564 ZoneList<LiveRange*> unhandled_live_ranges_; |
530 ZoneList<LiveRange*> active_live_ranges_; | 565 ZoneList<LiveRange*> active_live_ranges_; |
531 ZoneList<LiveRange*> inactive_live_ranges_; | 566 ZoneList<LiveRange*> inactive_live_ranges_; |
532 ZoneList<LiveRange*> reusable_slots_; | 567 ZoneList<LiveRange*> reusable_slots_; |
| 568 ZoneList<SpillRange*> spill_ranges_; |
533 | 569 |
534 // Next virtual register number to be assigned to temporaries. | 570 // Next virtual register number to be assigned to temporaries. |
535 int next_virtual_register_; | 571 int next_virtual_register_; |
536 int first_artificial_register_; | 572 int first_artificial_register_; |
537 GrowableBitVector double_artificial_registers_; | 573 GrowableBitVector double_artificial_registers_; |
538 | 574 |
539 RegisterKind mode_; | 575 RegisterKind mode_; |
540 int num_registers_; | 576 int num_registers_; |
541 | 577 |
542 BitVector* assigned_registers_; | 578 BitVector* assigned_registers_; |
(...skipping 23 matching lines...) Expand all Loading... |
566 LAllocator* allocator_; | 602 LAllocator* allocator_; |
567 unsigned allocator_zone_start_allocation_size_; | 603 unsigned allocator_zone_start_allocation_size_; |
568 | 604 |
569 DISALLOW_COPY_AND_ASSIGN(LAllocatorPhase); | 605 DISALLOW_COPY_AND_ASSIGN(LAllocatorPhase); |
570 }; | 606 }; |
571 | 607 |
572 | 608 |
573 } } // namespace v8::internal | 609 } } // namespace v8::internal |
574 | 610 |
575 #endif // V8_LITHIUM_ALLOCATOR_H_ | 611 #endif // V8_LITHIUM_ALLOCATOR_H_ |
OLD | NEW |