| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 13 matching lines...) Expand all Loading... |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #ifndef V8_LITHIUM_ALLOCATOR_H_ | 28 #ifndef V8_LITHIUM_ALLOCATOR_H_ |
| 29 #define V8_LITHIUM_ALLOCATOR_H_ | 29 #define V8_LITHIUM_ALLOCATOR_H_ |
| 30 | 30 |
| 31 #include "v8.h" | 31 #include "v8.h" |
| 32 | 32 |
| 33 #include "data-flow.h" | 33 #include "data-flow.h" |
| 34 #include "lithium.h" |
| 34 #include "zone.h" | 35 #include "zone.h" |
| 35 | 36 |
| 36 namespace v8 { | 37 namespace v8 { |
| 37 namespace internal { | 38 namespace internal { |
| 38 | 39 |
| 39 // Forward declarations. | 40 // Forward declarations. |
| 40 class HBasicBlock; | 41 class HBasicBlock; |
| 41 class HGraph; | 42 class HGraph; |
| 42 class HInstruction; | 43 class HInstruction; |
| 43 class HPhi; | 44 class HPhi; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 | 147 |
| 147 enum RegisterKind { | 148 enum RegisterKind { |
| 148 NONE, | 149 NONE, |
| 149 GENERAL_REGISTERS, | 150 GENERAL_REGISTERS, |
| 150 DOUBLE_REGISTERS | 151 DOUBLE_REGISTERS |
| 151 }; | 152 }; |
| 152 | 153 |
| 153 | 154 |
| 154 // A register-allocator view of a Lithium instruction. It contains the id of | 155 // A register-allocator view of a Lithium instruction. It contains the id of |
| 155 // the output operand and a list of input operand uses. | 156 // the output operand and a list of input operand uses. |
| 156 class InstructionSummary: public ZoneObject { | 157 |
| 158 class LInstruction; |
| 159 class LEnvironment; |
| 160 |
| 161 // Iterator for non-null temp operands. |
| 162 class TempIterator BASE_EMBEDDED { |
| 157 public: | 163 public: |
| 158 InstructionSummary() | 164 inline explicit TempIterator(LInstruction* instr); |
| 159 : output_operand_(NULL), | 165 inline bool HasNext(); |
| 160 input_count_(0), | 166 inline LOperand* Next(); |
| 161 operands_(4), | |
| 162 is_call_(false), | |
| 163 is_save_doubles_(false) {} | |
| 164 | |
| 165 // Output operands. | |
| 166 LOperand* Output() const { return output_operand_; } | |
| 167 void SetOutput(LOperand* output) { | |
| 168 ASSERT(output_operand_ == NULL); | |
| 169 output_operand_ = output; | |
| 170 } | |
| 171 | |
| 172 // Input operands. | |
| 173 int InputCount() const { return input_count_; } | |
| 174 LOperand* InputAt(int i) const { | |
| 175 ASSERT(i < input_count_); | |
| 176 return operands_[i]; | |
| 177 } | |
| 178 void AddInput(LOperand* input) { | |
| 179 operands_.InsertAt(input_count_, input); | |
| 180 input_count_++; | |
| 181 } | |
| 182 | |
| 183 // Temporary operands. | |
| 184 int TempCount() const { return operands_.length() - input_count_; } | |
| 185 LOperand* TempAt(int i) const { return operands_[i + input_count_]; } | |
| 186 void AddTemp(LOperand* temp) { operands_.Add(temp); } | |
| 187 | |
| 188 void MarkAsCall() { is_call_ = true; } | |
| 189 bool IsCall() const { return is_call_; } | |
| 190 | |
| 191 void MarkAsSaveDoubles() { is_save_doubles_ = true; } | |
| 192 bool IsSaveDoubles() const { return is_save_doubles_; } | |
| 193 | 167 |
| 194 private: | 168 private: |
| 195 LOperand* output_operand_; | 169 inline void Advance(); |
| 196 int input_count_; | 170 LInstruction* instr_; |
| 197 ZoneList<LOperand*> operands_; | 171 int current_; |
| 198 bool is_call_; | |
| 199 bool is_save_doubles_; | |
| 200 }; | 172 }; |
| 201 | 173 |
| 174 |
| 175 // Iterator for non-constant input operands. |
| 176 class InputIterator BASE_EMBEDDED { |
| 177 public: |
| 178 inline explicit InputIterator(LInstruction* instr); |
| 179 inline bool HasNext(); |
| 180 inline LOperand* Next(); |
| 181 |
| 182 private: |
| 183 inline void Advance(); |
| 184 LInstruction* instr_; |
| 185 int current_; |
| 186 }; |
| 187 |
| 188 |
| 189 class UseIterator BASE_EMBEDDED { |
| 190 public: |
| 191 inline explicit UseIterator(LInstruction* instr); |
| 192 inline bool HasNext(); |
| 193 inline LOperand* Next(); |
| 194 private: |
| 195 InputIterator input_iterator_; |
| 196 LEnvironment::DeepIterator env_iterator_; |
| 197 }; |
| 198 |
| 199 |
| 202 // Representation of the non-empty interval [start,end[. | 200 // Representation of the non-empty interval [start,end[. |
| 203 class UseInterval: public ZoneObject { | 201 class UseInterval: public ZoneObject { |
| 204 public: | 202 public: |
| 205 UseInterval(LifetimePosition start, LifetimePosition end) | 203 UseInterval(LifetimePosition start, LifetimePosition end) |
| 206 : start_(start), end_(end), next_(NULL) { | 204 : start_(start), end_(end), next_(NULL) { |
| 207 ASSERT(start.Value() < end.Value()); | 205 ASSERT(start.Value() < end.Value()); |
| 208 } | 206 } |
| 209 | 207 |
| 210 LifetimePosition start() const { return start_; } | 208 LifetimePosition start() const { return start_; } |
| 211 LifetimePosition end() const { return end_; } | 209 LifetimePosition end() const { return end_; } |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 421 } | 419 } |
| 422 | 420 |
| 423 BitVector* bits_; | 421 BitVector* bits_; |
| 424 }; | 422 }; |
| 425 | 423 |
| 426 | 424 |
| 427 class LAllocator BASE_EMBEDDED { | 425 class LAllocator BASE_EMBEDDED { |
| 428 public: | 426 public: |
| 429 explicit LAllocator(int first_virtual_register, HGraph* graph) | 427 explicit LAllocator(int first_virtual_register, HGraph* graph) |
| 430 : chunk_(NULL), | 428 : chunk_(NULL), |
| 431 summaries_(0), | |
| 432 next_summary_(NULL), | |
| 433 summary_stack_(2), | |
| 434 live_in_sets_(0), | 429 live_in_sets_(0), |
| 435 live_ranges_(16), | 430 live_ranges_(16), |
| 436 fixed_live_ranges_(8), | 431 fixed_live_ranges_(8), |
| 437 fixed_double_live_ranges_(8), | 432 fixed_double_live_ranges_(8), |
| 438 unhandled_live_ranges_(8), | 433 unhandled_live_ranges_(8), |
| 439 active_live_ranges_(8), | 434 active_live_ranges_(8), |
| 440 inactive_live_ranges_(8), | 435 inactive_live_ranges_(8), |
| 441 reusable_slots_(8), | 436 reusable_slots_(8), |
| 442 next_virtual_register_(first_virtual_register), | 437 next_virtual_register_(first_virtual_register), |
| 443 first_artificial_register_(first_virtual_register), | 438 first_artificial_register_(first_virtual_register), |
| 444 mode_(NONE), | 439 mode_(NONE), |
| 445 num_registers_(-1), | 440 num_registers_(-1), |
| 446 graph_(graph), | 441 graph_(graph), |
| 447 has_osr_entry_(false) {} | 442 has_osr_entry_(false) {} |
| 448 | 443 |
| 449 static void Setup(); | 444 static void Setup(); |
| 450 static void TraceAlloc(const char* msg, ...); | 445 static void TraceAlloc(const char* msg, ...); |
| 451 | 446 |
| 452 // Lithium translation support. | 447 // Lithium translation support. |
| 453 // Record a use of an input operand in the current instruction. | 448 // Record a use of an input operand in the current instruction. |
| 454 void RecordUse(HValue* value, LUnallocated* operand); | 449 void RecordUse(HValue* value, LUnallocated* operand); |
| 455 // Record the definition of the output operand. | 450 // Record the definition of the output operand. |
| 456 void RecordDefinition(HInstruction* instr, LUnallocated* operand); | 451 void RecordDefinition(HInstruction* instr, LUnallocated* operand); |
| 457 // Record a temporary operand. | 452 // Record a temporary operand. |
| 458 void RecordTemporary(LUnallocated* operand); | 453 void RecordTemporary(LUnallocated* operand); |
| 459 | 454 |
| 460 // Marks the current instruction as a call. | |
| 461 void MarkAsCall(); | |
| 462 | |
| 463 // Marks the current instruction as requiring saving double registers. | |
| 464 void MarkAsSaveDoubles(); | |
| 465 | |
| 466 // Checks whether the value of a given virtual register is tagged. | 455 // Checks whether the value of a given virtual register is tagged. |
| 467 bool HasTaggedValue(int virtual_register) const; | 456 bool HasTaggedValue(int virtual_register) const; |
| 468 | 457 |
| 469 // Returns the register kind required by the given virtual register. | 458 // Returns the register kind required by the given virtual register. |
| 470 RegisterKind RequiredRegisterKind(int virtual_register) const; | 459 RegisterKind RequiredRegisterKind(int virtual_register) const; |
| 471 | 460 |
| 472 // Begin a new instruction. | |
| 473 void BeginInstruction(); | |
| 474 | |
| 475 // Summarize the current instruction. | |
| 476 void SummarizeInstruction(int index); | |
| 477 | |
| 478 // Summarize the current instruction. | |
| 479 void OmitInstruction(); | |
| 480 | |
| 481 // Control max function size. | 461 // Control max function size. |
| 482 static int max_initial_value_ids(); | 462 static int max_initial_value_ids(); |
| 483 | 463 |
| 484 void Allocate(LChunk* chunk); | 464 void Allocate(LChunk* chunk); |
| 485 | 465 |
| 486 const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; } | 466 const ZoneList<LiveRange*>* live_ranges() const { return &live_ranges_; } |
| 487 const ZoneList<LiveRange*>* fixed_live_ranges() const { | 467 const ZoneList<LiveRange*>* fixed_live_ranges() const { |
| 488 return &fixed_live_ranges_; | 468 return &fixed_live_ranges_; |
| 489 } | 469 } |
| 490 const ZoneList<LiveRange*>* fixed_double_live_ranges() const { | 470 const ZoneList<LiveRange*>* fixed_double_live_ranges() const { |
| (...skipping 27 matching lines...) Expand all Loading... |
| 518 void AllocateRegisters(); | 498 void AllocateRegisters(); |
| 519 bool CanEagerlyResolveControlFlow(HBasicBlock* block) const; | 499 bool CanEagerlyResolveControlFlow(HBasicBlock* block) const; |
| 520 inline bool SafePointsAreInOrder() const; | 500 inline bool SafePointsAreInOrder() const; |
| 521 | 501 |
| 522 // Liveness analysis support. | 502 // Liveness analysis support. |
| 523 void InitializeLivenessAnalysis(); | 503 void InitializeLivenessAnalysis(); |
| 524 BitVector* ComputeLiveOut(HBasicBlock* block); | 504 BitVector* ComputeLiveOut(HBasicBlock* block); |
| 525 void AddInitialIntervals(HBasicBlock* block, BitVector* live_out); | 505 void AddInitialIntervals(HBasicBlock* block, BitVector* live_out); |
| 526 void ProcessInstructions(HBasicBlock* block, BitVector* live); | 506 void ProcessInstructions(HBasicBlock* block, BitVector* live); |
| 527 void MeetRegisterConstraints(HBasicBlock* block); | 507 void MeetRegisterConstraints(HBasicBlock* block); |
| 528 void MeetConstraintsBetween(InstructionSummary* first, | 508 void MeetConstraintsBetween(LInstruction* first, |
| 529 InstructionSummary* second, | 509 LInstruction* second, |
| 530 int gap_index); | 510 int gap_index); |
| 531 void ResolvePhis(HBasicBlock* block); | 511 void ResolvePhis(HBasicBlock* block); |
| 532 | 512 |
| 533 // Helper methods for building intervals. | 513 // Helper methods for building intervals. |
| 534 LOperand* AllocateFixed(LUnallocated* operand, int pos, bool is_tagged); | 514 LOperand* AllocateFixed(LUnallocated* operand, int pos, bool is_tagged); |
| 535 LiveRange* LiveRangeFor(LOperand* operand); | 515 LiveRange* LiveRangeFor(LOperand* operand); |
| 536 void Define(LifetimePosition position, LOperand* operand, LOperand* hint); | 516 void Define(LifetimePosition position, LOperand* operand, LOperand* hint); |
| 537 void Use(LifetimePosition block_start, | 517 void Use(LifetimePosition block_start, |
| 538 LifetimePosition position, | 518 LifetimePosition position, |
| 539 LOperand* operand, | 519 LOperand* operand, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 598 HBasicBlock* block, | 578 HBasicBlock* block, |
| 599 HBasicBlock* pred); | 579 HBasicBlock* pred); |
| 600 | 580 |
| 601 // Return parallel move that should be used to connect ranges split at the | 581 // Return parallel move that should be used to connect ranges split at the |
| 602 // given position. | 582 // given position. |
| 603 LParallelMove* GetConnectingParallelMove(LifetimePosition pos); | 583 LParallelMove* GetConnectingParallelMove(LifetimePosition pos); |
| 604 | 584 |
| 605 // Return the block which contains give lifetime position. | 585 // Return the block which contains give lifetime position. |
| 606 HBasicBlock* GetBlock(LifetimePosition pos); | 586 HBasicBlock* GetBlock(LifetimePosition pos); |
| 607 | 587 |
| 608 // Current active summary. | |
| 609 InstructionSummary* current_summary() const { return summary_stack_.last(); } | |
| 610 | |
| 611 // Get summary for given instruction index. | |
| 612 InstructionSummary* GetSummary(int index) const { return summaries_[index]; } | |
| 613 | |
| 614 // Helper methods for the fixed registers. | 588 // Helper methods for the fixed registers. |
| 615 int RegisterCount() const; | 589 int RegisterCount() const; |
| 616 static int FixedLiveRangeID(int index) { return -index - 1; } | 590 static int FixedLiveRangeID(int index) { return -index - 1; } |
| 617 static int FixedDoubleLiveRangeID(int index); | 591 static int FixedDoubleLiveRangeID(int index); |
| 618 LiveRange* FixedLiveRangeFor(int index); | 592 LiveRange* FixedLiveRangeFor(int index); |
| 619 LiveRange* FixedDoubleLiveRangeFor(int index); | 593 LiveRange* FixedDoubleLiveRangeFor(int index); |
| 620 LiveRange* LiveRangeFor(int index); | 594 LiveRange* LiveRangeFor(int index); |
| 621 HPhi* LookupPhi(LOperand* operand) const; | 595 HPhi* LookupPhi(LOperand* operand) const; |
| 622 LGap* GetLastGap(HBasicBlock* block) const; | 596 LGap* GetLastGap(HBasicBlock* block) const; |
| 623 | 597 |
| 624 const char* RegisterName(int allocation_index); | 598 const char* RegisterName(int allocation_index); |
| 625 | 599 |
| 626 LChunk* chunk_; | 600 LChunk* chunk_; |
| 627 ZoneList<InstructionSummary*> summaries_; | |
| 628 InstructionSummary* next_summary_; | |
| 629 | |
| 630 ZoneList<InstructionSummary*> summary_stack_; | |
| 631 | 601 |
| 632 // During liveness analysis keep a mapping from block id to live_in sets | 602 // During liveness analysis keep a mapping from block id to live_in sets |
| 633 // for blocks already analyzed. | 603 // for blocks already analyzed. |
| 634 ZoneList<BitVector*> live_in_sets_; | 604 ZoneList<BitVector*> live_in_sets_; |
| 635 | 605 |
| 636 // Liveness analysis results. | 606 // Liveness analysis results. |
| 637 ZoneList<LiveRange*> live_ranges_; | 607 ZoneList<LiveRange*> live_ranges_; |
| 638 | 608 |
| 639 // Lists of live ranges | 609 // Lists of live ranges |
| 640 ZoneList<LiveRange*> fixed_live_ranges_; | 610 ZoneList<LiveRange*> fixed_live_ranges_; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 656 | 626 |
| 657 bool has_osr_entry_; | 627 bool has_osr_entry_; |
| 658 | 628 |
| 659 DISALLOW_COPY_AND_ASSIGN(LAllocator); | 629 DISALLOW_COPY_AND_ASSIGN(LAllocator); |
| 660 }; | 630 }; |
| 661 | 631 |
| 662 | 632 |
| 663 } } // namespace v8::internal | 633 } } // namespace v8::internal |
| 664 | 634 |
| 665 #endif // V8_LITHIUM_ALLOCATOR_H_ | 635 #endif // V8_LITHIUM_ALLOCATOR_H_ |
| OLD | NEW |