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 |