Chromium Code Reviews| 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 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 283 UsePosition* first_pos() const { return first_pos_; } | 283 UsePosition* first_pos() const { return first_pos_; } |
| 284 LiveRange* parent() const { return parent_; } | 284 LiveRange* parent() const { return parent_; } |
| 285 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } | 285 LiveRange* TopLevel() { return (parent_ == NULL) ? this : parent_; } |
| 286 LiveRange* next() const { return next_; } | 286 LiveRange* next() const { return next_; } |
| 287 bool IsChild() const { return parent() != NULL; } | 287 bool IsChild() const { return parent() != NULL; } |
| 288 int id() const { return id_; } | 288 int id() const { return id_; } |
| 289 bool IsFixed() const { return id_ < 0; } | 289 bool IsFixed() const { return id_ < 0; } |
| 290 bool IsEmpty() const { return first_interval() == NULL; } | 290 bool IsEmpty() const { return first_interval() == NULL; } |
| 291 LOperand* CreateAssignedOperand(Zone* zone); | 291 LOperand* CreateAssignedOperand(Zone* zone); |
| 292 int assigned_register() const { return assigned_register_; } | 292 int assigned_register() const { return assigned_register_; } |
| 293 | |
| 293 int spill_start_index() const { return spill_start_index_; } | 294 int spill_start_index() const { return spill_start_index_; } |
| 295 void set_spill_start_index(int start) { spill_start_index_ = start; } | |
| 296 | |
| 294 void set_assigned_register(int reg, | 297 void set_assigned_register(int reg, |
| 295 RegisterKind register_kind, | 298 RegisterKind register_kind, |
| 296 Zone* zone); | 299 Zone* zone); |
| 297 void MakeSpilled(Zone* zone); | 300 void MakeSpilled(Zone* zone); |
| 298 | 301 |
| 299 // Returns use position in this live range that follows both start | 302 // Returns use position in this live range that follows both start |
| 300 // and last processed use position. | 303 // and last processed use position. |
| 301 // Modifies internal state of live range! | 304 // Modifies internal state of live range! |
| 302 UsePosition* NextUsePosition(LifetimePosition start); | 305 UsePosition* NextUsePosition(LifetimePosition start); |
| 303 | 306 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 340 | 343 |
| 341 LifetimePosition End() const { | 344 LifetimePosition End() const { |
| 342 ASSERT(!IsEmpty()); | 345 ASSERT(!IsEmpty()); |
| 343 return last_interval_->end(); | 346 return last_interval_->end(); |
| 344 } | 347 } |
| 345 | 348 |
| 346 bool HasAllocatedSpillOperand() const; | 349 bool HasAllocatedSpillOperand() const; |
| 347 LOperand* GetSpillOperand() const { return spill_operand_; } | 350 LOperand* GetSpillOperand() const { return spill_operand_; } |
| 348 void SetSpillOperand(LOperand* operand); | 351 void SetSpillOperand(LOperand* operand); |
| 349 | 352 |
| 350 void SetSpillStartIndex(int start) { | |
| 351 spill_start_index_ = Min(start, spill_start_index_); | |
| 352 } | |
| 353 | |
| 354 bool ShouldBeAllocatedBefore(const LiveRange* other) const; | 353 bool ShouldBeAllocatedBefore(const LiveRange* other) const; |
| 355 bool CanCover(LifetimePosition position) const; | 354 bool CanCover(LifetimePosition position) const; |
| 356 bool Covers(LifetimePosition position); | 355 bool Covers(LifetimePosition position); |
| 357 LifetimePosition FirstIntersection(LiveRange* other); | 356 LifetimePosition FirstIntersection(LiveRange* other); |
| 358 | 357 |
| 359 // Add a new interval or a new use position to this live range. | 358 // Add a new interval or a new use position to this live range. |
| 360 void EnsureInterval(LifetimePosition start, | 359 void EnsureInterval(LifetimePosition start, |
| 361 LifetimePosition end, | 360 LifetimePosition end, |
| 362 Zone* zone); | 361 Zone* zone); |
| 363 void AddUseInterval(LifetimePosition start, | 362 void AddUseInterval(LifetimePosition start, |
| 364 LifetimePosition end, | 363 LifetimePosition end, |
| 365 Zone* zone); | 364 Zone* zone); |
| 366 UsePosition* AddUsePosition(LifetimePosition pos, | 365 UsePosition* AddUsePosition(LifetimePosition pos, |
| 367 LOperand* operand, | 366 LOperand* operand, |
| 368 Zone* zone); | 367 Zone* zone); |
| 369 | 368 |
| 370 // Shorten the most recently added interval by setting a new start. | 369 // Shorten the most recently added interval by setting a new start. |
| 371 void ShortenTo(LifetimePosition start); | 370 void ShortenTo(LifetimePosition start); |
| 372 | 371 |
| 373 #ifdef DEBUG | 372 #ifdef DEBUG |
| 374 // True if target overlaps an existing interval. | 373 // True if target overlaps an existing interval. |
| 375 bool HasOverlap(UseInterval* target) const; | 374 bool HasOverlap(UseInterval* target) const; |
| 376 void Verify() const; | 375 void Verify() const; |
| 377 #endif | 376 #endif |
| 378 | 377 |
| 378 static const intptr_t kDisabledSpillStoreSinkingMarker = -1; | |
| 379 | |
| 380 LOperand* spill_source() { return spill_source_; } | |
| 381 void set_spill_source(LOperand* spill_source) { | |
| 382 spill_source_ = spill_source; | |
| 383 } | |
| 384 | |
| 385 bool HasPendingSpillStore() { | |
| 386 return (spill_source() != | |
| 387 reinterpret_cast<LOperand*>(kDisabledSpillStoreSinkingMarker)) && | |
| 388 (spill_source() != NULL); | |
| 389 } | |
| 390 | |
| 391 void DisableSpillStoreSinking() { | |
| 392 set_spill_source( | |
| 393 reinterpret_cast<LOperand*>(kDisabledSpillStoreSinkingMarker)); | |
| 394 } | |
| 395 | |
| 379 private: | 396 private: |
| 380 void ConvertOperands(Zone* zone); | 397 void ConvertOperands(Zone* zone); |
| 381 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; | 398 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; |
| 382 void AdvanceLastProcessedMarker(UseInterval* to_start_of, | 399 void AdvanceLastProcessedMarker(UseInterval* to_start_of, |
| 383 LifetimePosition but_not_past) const; | 400 LifetimePosition but_not_past) const; |
| 384 | 401 |
| 385 int id_; | 402 int id_; |
| 386 bool spilled_; | 403 bool spilled_; |
| 387 bool is_double_; | 404 bool is_double_; |
| 388 int assigned_register_; | 405 int assigned_register_; |
| 389 UseInterval* last_interval_; | 406 UseInterval* last_interval_; |
| 390 UseInterval* first_interval_; | 407 UseInterval* first_interval_; |
| 391 UsePosition* first_pos_; | 408 UsePosition* first_pos_; |
| 392 LiveRange* parent_; | 409 LiveRange* parent_; |
| 393 LiveRange* next_; | 410 LiveRange* next_; |
| 394 // This is used as a cache, it doesn't affect correctness. | 411 // This is used as a cache, it doesn't affect correctness. |
| 395 mutable UseInterval* current_interval_; | 412 mutable UseInterval* current_interval_; |
| 396 UsePosition* last_processed_use_; | 413 UsePosition* last_processed_use_; |
| 397 LOperand* spill_operand_; | 414 LOperand* spill_operand_; |
| 398 int spill_start_index_; | 415 int spill_start_index_; |
| 416 LOperand* spill_source_; | |
| 399 }; | 417 }; |
| 400 | 418 |
| 401 | 419 |
| 402 class GrowableBitVector BASE_EMBEDDED { | 420 class GrowableBitVector BASE_EMBEDDED { |
| 403 public: | 421 public: |
| 404 GrowableBitVector() : bits_(NULL) { } | 422 GrowableBitVector() : bits_(NULL) { } |
| 405 | 423 |
| 406 bool Contains(int value) const { | 424 bool Contains(int value) const { |
| 407 if (!InBitsRange(value)) return false; | 425 if (!InBitsRange(value)) return false; |
| 408 return bits_->Contains(value); | 426 return bits_->Contains(value); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 557 void SpillAfter(LiveRange* range, LifetimePosition pos); | 575 void SpillAfter(LiveRange* range, LifetimePosition pos); |
| 558 | 576 |
| 559 // Spill the given life range after position start and up to position end. | 577 // Spill the given life range after position start and up to position end. |
| 560 void SpillBetween(LiveRange* range, | 578 void SpillBetween(LiveRange* range, |
| 561 LifetimePosition start, | 579 LifetimePosition start, |
| 562 LifetimePosition end); | 580 LifetimePosition end); |
| 563 | 581 |
| 564 void SplitAndSpillIntersecting(LiveRange* range); | 582 void SplitAndSpillIntersecting(LiveRange* range); |
| 565 | 583 |
| 566 void Spill(LiveRange* range); | 584 void Spill(LiveRange* range); |
| 585 | |
| 586 // Emit spill store for the given range that moves value from the register | |
| 587 // where it was produced (spill source) to the allocated spill slot. | |
| 588 void EmitSpillStore(LiveRange* range); | |
| 589 void EmitSpillStore(int pos, LOperand* source, LOperand* spill); | |
| 590 | |
| 591 // Try sink spill store for the given range down to the beginning of the | |
| 592 // given block. This is done only if the block dominates all spilled split | |
| 593 // siblings. | |
| 594 void TrySinkSpillStoreTo(LiveRange* range, HBasicBlock* block); | |
| 595 | |
| 567 bool IsBlockBoundary(LifetimePosition pos); | 596 bool IsBlockBoundary(LifetimePosition pos); |
| 568 | 597 |
| 569 // Helper methods for resolving control flow. | 598 // Helper methods for resolving control flow. |
| 570 void ResolveControlFlow(LiveRange* range, | 599 void ResolveControlFlow(LiveRange* range, |
| 571 HBasicBlock* block, | 600 HBasicBlock* block, |
| 572 HBasicBlock* pred); | 601 HBasicBlock* pred); |
| 573 | 602 |
| 603 // Emit all pending spill stores for ranged that have spilled siblings sinking | |
|
danno
2013/01/10 15:33:27
nit: ranges
Vyacheslav Egorov (Google)
2013/01/25 13:49:17
Done.
| |
| 604 // stores down to loop exits whenever possible. | |
| 605 void SinkSpillStores(); | |
| 606 | |
| 574 // Return parallel move that should be used to connect ranges split at the | 607 // Return parallel move that should be used to connect ranges split at the |
| 575 // given position. | 608 // given position. |
| 576 LParallelMove* GetConnectingParallelMove(LifetimePosition pos); | 609 LParallelMove* GetConnectingParallelMove(LifetimePosition pos); |
| 577 | 610 |
| 578 // Return the block which contains give lifetime position. | 611 // Return the block which contains give lifetime position. |
| 579 HBasicBlock* GetBlock(LifetimePosition pos); | 612 HBasicBlock* GetBlock(LifetimePosition pos); |
| 580 | 613 |
| 581 // Helper methods for the fixed registers. | 614 // Helper methods for the fixed registers. |
| 582 int RegisterCount() const; | 615 int RegisterCount() const; |
| 583 static int FixedLiveRangeID(int index) { return -index - 1; } | 616 static int FixedLiveRangeID(int index) { return -index - 1; } |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 610 // Lists of live ranges | 643 // Lists of live ranges |
| 611 EmbeddedVector<LiveRange*, Register::kNumAllocatableRegisters> | 644 EmbeddedVector<LiveRange*, Register::kNumAllocatableRegisters> |
| 612 fixed_live_ranges_; | 645 fixed_live_ranges_; |
| 613 EmbeddedVector<LiveRange*, DoubleRegister::kNumAllocatableRegisters> | 646 EmbeddedVector<LiveRange*, DoubleRegister::kNumAllocatableRegisters> |
| 614 fixed_double_live_ranges_; | 647 fixed_double_live_ranges_; |
| 615 ZoneList<LiveRange*> unhandled_live_ranges_; | 648 ZoneList<LiveRange*> unhandled_live_ranges_; |
| 616 ZoneList<LiveRange*> active_live_ranges_; | 649 ZoneList<LiveRange*> active_live_ranges_; |
| 617 ZoneList<LiveRange*> inactive_live_ranges_; | 650 ZoneList<LiveRange*> inactive_live_ranges_; |
| 618 ZoneList<LiveRange*> reusable_slots_; | 651 ZoneList<LiveRange*> reusable_slots_; |
| 619 | 652 |
| 653 // List of live ranges that were spilled but did not have | |
| 654 // spill store emitted eagerly. | |
| 655 ZoneList<LiveRange*> pending_spilled_; | |
| 656 | |
| 620 // Next virtual register number to be assigned to temporaries. | 657 // Next virtual register number to be assigned to temporaries. |
| 621 int next_virtual_register_; | 658 int next_virtual_register_; |
| 622 int first_artificial_register_; | 659 int first_artificial_register_; |
| 623 GrowableBitVector double_artificial_registers_; | 660 GrowableBitVector double_artificial_registers_; |
| 624 | 661 |
| 625 RegisterKind mode_; | 662 RegisterKind mode_; |
| 626 int num_registers_; | 663 int num_registers_; |
| 627 | 664 |
| 628 HGraph* graph_; | 665 HGraph* graph_; |
| 629 | 666 |
| 630 bool has_osr_entry_; | 667 bool has_osr_entry_; |
| 631 | 668 |
| 632 // Indicates success or failure during register allocation. | 669 // Indicates success or failure during register allocation. |
| 633 bool allocation_ok_; | 670 bool allocation_ok_; |
| 634 | 671 |
| 635 DISALLOW_COPY_AND_ASSIGN(LAllocator); | 672 DISALLOW_COPY_AND_ASSIGN(LAllocator); |
| 636 }; | 673 }; |
| 637 | 674 |
| 638 | 675 |
| 639 } } // namespace v8::internal | 676 } } // namespace v8::internal |
| 640 | 677 |
| 641 #endif // V8_LITHIUM_ALLOCATOR_H_ | 678 #endif // V8_LITHIUM_ALLOCATOR_H_ |
| OLD | NEW |