Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: src/compiler/register-allocator.h

Issue 1061923005: Reland: Introducing the LLVM greedy register allocator. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 394 matching lines...) Expand 10 before | Expand all | Expand 10 after
405 void MergeDisjointIntervals(UseInterval* other); 405 void MergeDisjointIntervals(UseInterval* other);
406 406
407 ZoneVector<LiveRange*> live_ranges_; 407 ZoneVector<LiveRange*> live_ranges_;
408 UseInterval* use_interval_; 408 UseInterval* use_interval_;
409 LifetimePosition end_position_; 409 LifetimePosition end_position_;
410 410
411 DISALLOW_COPY_AND_ASSIGN(SpillRange); 411 DISALLOW_COPY_AND_ASSIGN(SpillRange);
412 }; 412 };
413 413
414 414
415 class RegisterAllocator FINAL : public ZoneObject { 415 class RegisterAllocator : public ZoneObject {
416 public: 416 public:
417 explicit RegisterAllocator(const RegisterConfiguration* config, 417 explicit RegisterAllocator(const RegisterConfiguration* config,
418 Zone* local_zone, Frame* frame, 418 Zone* local_zone, Frame* frame,
419 InstructionSequence* code, 419 InstructionSequence* code,
420 const char* debug_name = nullptr); 420 const char* debug_name = nullptr);
421 421
422 const ZoneVector<LiveRange*>& live_ranges() const { return live_ranges_; } 422 const ZoneVector<LiveRange*>& live_ranges() const { return live_ranges_; }
423 const ZoneVector<LiveRange*>& fixed_live_ranges() const { 423 const ZoneVector<LiveRange*>& fixed_live_ranges() const {
424 return fixed_live_ranges_; 424 return fixed_live_ranges_;
425 } 425 }
426 const ZoneVector<LiveRange*>& fixed_double_live_ranges() const { 426 const ZoneVector<LiveRange*>& fixed_double_live_ranges() const {
427 return fixed_double_live_ranges_; 427 return fixed_double_live_ranges_;
428 } 428 }
429 InstructionSequence* code() const { return code_; } 429 InstructionSequence* code() const { return code_; }
430 // This zone is for datastructures only needed during register allocation. 430 // This zone is for datastructures only needed during register allocation.
431 Zone* local_zone() const { return local_zone_; } 431 Zone* local_zone() const { return local_zone_; }
432 432
433 // Phase 1 : insert moves to account for fixed register operands. 433 // Phase 1 : insert moves to account for fixed register operands.
434 void MeetRegisterConstraints(); 434 void MeetRegisterConstraints();
435 435
436 // Phase 2: deconstruct SSA by inserting moves in successors and the headers 436 // Phase 2: deconstruct SSA by inserting moves in successors and the headers
437 // of blocks containing phis. 437 // of blocks containing phis.
438 void ResolvePhis(); 438 void ResolvePhis();
439 439
440 // Phase 3: compute liveness of all virtual register. 440 // Phase 3: compute liveness of all virtual register.
441 void BuildLiveRanges(); 441 void BuildLiveRanges();
442 bool ExistsUseWithoutDefinition(); 442 bool ExistsUseWithoutDefinition();
443 443
444 // Phase 4: compute register assignments. 444 // Phase 4: compute register assignments.
445 void AllocateGeneralRegisters(); 445 virtual void AllocateGeneralRegisters() = 0;
446 void AllocateDoubleRegisters(); 446 virtual void AllocateDoubleRegisters() = 0;
447 447
448 // Phase 5: assign spill splots. 448 // Phase 5: assign spill splots.
449 void AssignSpillSlots(); 449 void AssignSpillSlots();
450 450
451 // Phase 6: commit assignment. 451 // Phase 6: commit assignment.
452 void CommitAssignment(); 452 void CommitAssignment();
453 453
454 // Phase 7: compute values for pointer maps. 454 // Phase 7: compute values for pointer maps.
455 void PopulateReferenceMaps(); 455 void PopulateReferenceMaps();
456 456
457 // Phase 8: reconnect split ranges with moves. 457 // Phase 8: reconnect split ranges with moves.
458 void ConnectRanges(); 458 void ConnectRanges();
459 459
460 // Phase 9: insert moves to connect ranges across basic blocks. 460 // Phase 9: insert moves to connect ranges across basic blocks.
461 void ResolveControlFlow(); 461 void ResolveControlFlow();
462 462
463 private: 463 protected:
464 int GetVirtualRegister() { return code()->NextVirtualRegister(); } 464 virtual ~RegisterAllocator() {}
465 class PhiMapValue : public ZoneObject {
466 public:
467 PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone)
468 : phi(phi), block(block), incoming_moves(zone) {
469 incoming_moves.reserve(phi->operands().size());
470 }
471 PhiInstruction* const phi;
472 const InstructionBlock* const block;
473 ZoneVector<MoveOperands*> incoming_moves;
474 };
475 typedef ZoneMap<int, PhiMapValue*> PhiMap;
476 PhiMap& phi_map() { return phi_map_; }
465 477
478 ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; }
479 ZoneVector<LiveRange*>& fixed_live_ranges() { return fixed_live_ranges_; }
480 ZoneVector<LiveRange*>& fixed_double_live_ranges() {
481 return fixed_double_live_ranges_;
482 }
483
484 BitVector* assigned_registers() const { return assigned_registers_; }
485 BitVector* assigned_double_registers() const {
486 return assigned_double_registers_;
487 }
488
489 Frame* frame() const { return frame_; }
490 const char* debug_name() const { return debug_name_; }
491 const RegisterConfiguration* config() const { return config_; }
492 ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; }
493
494 // This zone is for InstructionOperands and moves that live beyond register
495 // allocation.
496 Zone* code_zone() const { return code()->zone(); }
497 Instruction* InstructionAt(int index) { return code()->InstructionAt(index); }
498 // Creates a new live range.
499 LiveRange* NewLiveRange(int index);
500
501 LiveRange* LiveRangeFor(int index);
502 LiveRange* LiveRangeFor(InstructionOperand* operand);
503 LiveRange* FixedLiveRangeFor(int index);
504 LiveRange* FixedDoubleLiveRangeFor(int index);
505 static int FixedLiveRangeID(int index) { return -index - 1; }
506 int FixedDoubleLiveRangeID(int index);
507 void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
508
509 // Helper methods for building intervals.
510 InstructionOperand* AllocateFixed(UnallocatedOperand* operand, int pos,
511 bool is_tagged);
512
513 MoveOperands* AddGapMove(int index, Instruction::GapPosition position,
514 const InstructionOperand& from,
515 const InstructionOperand& to);
466 // Checks whether the value of a given virtual register is a reference. 516 // Checks whether the value of a given virtual register is a reference.
467 // TODO(titzer): rename this to IsReference. 517 // TODO(titzer): rename this to IsReference.
468 bool HasTaggedValue(int virtual_register) const; 518 bool HasTaggedValue(int virtual_register) const;
469 519
520 bool IsBlockBoundary(LifetimePosition pos);
521 bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const;
522
523 // Return the block which contains give lifetime position.
524 const InstructionBlock* GetInstructionBlock(LifetimePosition pos);
525 SpillRange* AssignSpillRangeToLiveRange(LiveRange* range);
526 void Spill(LiveRange* range);
527
528 // Live range splitting helpers.
529 // Split the given range at the given position.
530 // If range starts at or after the given position then the
531 // original range is returned.
532 // Otherwise returns the live range that starts at pos and contains
533 // all uses from the original range that follow pos. Uses at pos will
534 // still be owned by the original range after splitting.
535 LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos);
536
537 // Split the given range in a position from the interval [start, end].
538 LiveRange* SplitBetween(LiveRange* range, LifetimePosition start,
539 LifetimePosition end);
540
541 // Find a lifetime position in the interval [start, end] which
542 // is optimal for splitting: it is either header of the outermost
543 // loop covered by this interval or the latest possible position.
544 LifetimePosition FindOptimalSplitPos(LifetimePosition start,
545 LifetimePosition end);
546
547
548 private:
549 void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out);
550 void AssignPhiInput(LiveRange* range, const InstructionOperand& assignment);
551 void ProcessInstructions(const InstructionBlock* block, BitVector* live);
552 Instruction* GetLastInstruction(const InstructionBlock* block);
553 void Define(LifetimePosition position, InstructionOperand* operand,
554 InstructionOperand* hint);
555 int GetVirtualRegister() { return code()->NextVirtualRegister(); }
556 void Use(LifetimePosition block_start, LifetimePosition position,
557 InstructionOperand* operand, InstructionOperand* hint);
470 // Returns the register kind required by the given virtual register. 558 // Returns the register kind required by the given virtual register.
471 RegisterKind RequiredRegisterKind(int virtual_register) const; 559 RegisterKind RequiredRegisterKind(int virtual_register) const;
472 560
473 // Creates a new live range. 561 bool IsOutputRegisterOf(Instruction* instr, int index);
474 LiveRange* NewLiveRange(int index); 562 bool IsOutputDoubleRegisterOf(Instruction* instr, int index);
475 563
476 // This zone is for InstructionOperands and moves that live beyond register 564 void ResolvePhis(const InstructionBlock* block);
477 // allocation. 565 void MeetRegisterConstraints(const InstructionBlock* block);
478 Zone* code_zone() const { return code()->zone(); } 566 void MeetConstraintsBefore(int index);
567 void MeetConstraintsAfter(int index);
568 void MeetRegisterConstraintsForLastInstructionInBlock(
569 const InstructionBlock* block);
479 570
480 BitVector* assigned_registers() { return assigned_registers_; } 571 // Helper methods for resolving control flow.
481 BitVector* assigned_double_registers() { return assigned_double_registers_; } 572 void ResolveControlFlow(const InstructionBlock* block,
573 const InstructionOperand& cur_op,
574 const InstructionBlock* pred,
575 const InstructionOperand& pred_op);
576 bool SafePointsAreInOrder() const;
482 577
578 // Liveness analysis support.
579 BitVector* ComputeLiveOut(const InstructionBlock* block);
580
581 Zone* const local_zone_;
582 Frame* const frame_;
583 InstructionSequence* const code_;
584 const char* const debug_name_;
585 const RegisterConfiguration* config_;
586 PhiMap phi_map_;
587
588 // Liveness analysis results.
589 ZoneVector<LiveRange*> live_ranges_;
590
591 // Lists of live ranges.
592 ZoneVector<LiveRange*> fixed_live_ranges_;
593 ZoneVector<LiveRange*> fixed_double_live_ranges_;
594 ZoneVector<SpillRange*> spill_ranges_;
595
596 // During liveness analysis keep a mapping from block id to live_in sets
597 // for blocks already analyzed.
598 ZoneVector<BitVector*> live_in_sets_;
599
600 BitVector* assigned_registers_;
601 BitVector* assigned_double_registers_;
602 };
603
604
605 class RegisterAllocatorLinear FINAL : public RegisterAllocator {
606 public:
607 explicit RegisterAllocatorLinear(const RegisterConfiguration* config,
608 Zone* local_zone, Frame* frame,
609 InstructionSequence* code,
610 const char* debug_name = nullptr);
611 void AllocateGeneralRegisters() override;
612 void AllocateDoubleRegisters() override;
613
614 private:
483 #ifdef DEBUG 615 #ifdef DEBUG
484 void Verify() const; 616 void Verify() const;
485 #endif 617 #endif
486 618
487 void AllocateRegisters(); 619 void AllocateRegisters();
488 bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const;
489 bool SafePointsAreInOrder() const;
490
491 // Liveness analysis support.
492 BitVector* ComputeLiveOut(const InstructionBlock* block);
493 void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out);
494 bool IsOutputRegisterOf(Instruction* instr, int index);
495 bool IsOutputDoubleRegisterOf(Instruction* instr, int index);
496 void ProcessInstructions(const InstructionBlock* block, BitVector* live);
497 void MeetRegisterConstraints(const InstructionBlock* block);
498 void MeetConstraintsBefore(int index);
499 void MeetConstraintsAfter(int index);
500 void MeetRegisterConstraintsForLastInstructionInBlock(
501 const InstructionBlock* block);
502 void ResolvePhis(const InstructionBlock* block);
503
504 // Helper methods for building intervals.
505 InstructionOperand* AllocateFixed(UnallocatedOperand* operand, int pos,
506 bool is_tagged);
507 LiveRange* LiveRangeFor(InstructionOperand* operand);
508 void Define(LifetimePosition position, InstructionOperand* operand,
509 InstructionOperand* hint);
510 void Use(LifetimePosition block_start, LifetimePosition position,
511 InstructionOperand* operand, InstructionOperand* hint);
512 MoveOperands* AddGapMove(int index, Instruction::GapPosition position,
513 const InstructionOperand& from,
514 const InstructionOperand& to);
515 620
516 // Helper methods for updating the life range lists. 621 // Helper methods for updating the life range lists.
517 void AddToActive(LiveRange* range); 622 void AddToActive(LiveRange* range);
518 void AddToInactive(LiveRange* range); 623 void AddToInactive(LiveRange* range);
519 void AddToUnhandledSorted(LiveRange* range); 624 void AddToUnhandledSorted(LiveRange* range);
520 void AddToUnhandledUnsorted(LiveRange* range); 625 void AddToUnhandledUnsorted(LiveRange* range);
521 void SortUnhandled(); 626 void SortUnhandled();
522 bool UnhandledIsSorted(); 627 bool UnhandledIsSorted();
523 void ActiveToHandled(LiveRange* range); 628 void ActiveToHandled(LiveRange* range);
524 void ActiveToInactive(LiveRange* range); 629 void ActiveToInactive(LiveRange* range);
525 void InactiveToHandled(LiveRange* range); 630 void InactiveToHandled(LiveRange* range);
526 void InactiveToActive(LiveRange* range); 631 void InactiveToActive(LiveRange* range);
527 632
528 // Helper methods for allocating registers. 633 // Helper methods for allocating registers.
529 bool TryReuseSpillForPhi(LiveRange* range); 634 bool TryReuseSpillForPhi(LiveRange* range);
530 bool TryAllocateFreeReg(LiveRange* range); 635 bool TryAllocateFreeReg(LiveRange* range);
531 void AllocateBlockedReg(LiveRange* range); 636 void AllocateBlockedReg(LiveRange* range);
532 SpillRange* AssignSpillRangeToLiveRange(LiveRange* range);
533
534 // Live range splitting helpers.
535
536 // Split the given range at the given position.
537 // If range starts at or after the given position then the
538 // original range is returned.
539 // Otherwise returns the live range that starts at pos and contains
540 // all uses from the original range that follow pos. Uses at pos will
541 // still be owned by the original range after splitting.
542 LiveRange* SplitRangeAt(LiveRange* range, LifetimePosition pos);
543
544 // Split the given range in a position from the interval [start, end].
545 LiveRange* SplitBetween(LiveRange* range, LifetimePosition start,
546 LifetimePosition end);
547
548 // Find a lifetime position in the interval [start, end] which
549 // is optimal for splitting: it is either header of the outermost
550 // loop covered by this interval or the latest possible position.
551 LifetimePosition FindOptimalSplitPos(LifetimePosition start,
552 LifetimePosition end);
553 637
554 // Spill the given life range after position pos. 638 // Spill the given life range after position pos.
555 void SpillAfter(LiveRange* range, LifetimePosition pos); 639 void SpillAfter(LiveRange* range, LifetimePosition pos);
556 640
557 // Spill the given life range after position [start] and up to position [end]. 641 // Spill the given life range after position [start] and up to position [end].
558 void SpillBetween(LiveRange* range, LifetimePosition start, 642 void SpillBetween(LiveRange* range, LifetimePosition start,
559 LifetimePosition end); 643 LifetimePosition end);
560 644
561 // Spill the given life range after position [start] and up to position [end]. 645 // Spill the given life range after position [start] and up to position [end].
562 // Range is guaranteed to be spilled at least until position [until]. 646 // Range is guaranteed to be spilled at least until position [until].
563 void SpillBetweenUntil(LiveRange* range, LifetimePosition start, 647 void SpillBetweenUntil(LiveRange* range, LifetimePosition start,
564 LifetimePosition until, LifetimePosition end); 648 LifetimePosition until, LifetimePosition end);
565 649
566 void SplitAndSpillIntersecting(LiveRange* range); 650 void SplitAndSpillIntersecting(LiveRange* range);
567 651
568 // If we are trying to spill a range inside the loop try to 652 // If we are trying to spill a range inside the loop try to
569 // hoist spill position out to the point just before the loop. 653 // hoist spill position out to the point just before the loop.
570 LifetimePosition FindOptimalSpillingPos(LiveRange* range, 654 LifetimePosition FindOptimalSpillingPos(LiveRange* range,
571 LifetimePosition pos); 655 LifetimePosition pos);
572 656
573 void Spill(LiveRange* range);
574 bool IsBlockBoundary(LifetimePosition pos);
575
576 // Helper methods for resolving control flow.
577 void ResolveControlFlow(const InstructionBlock* block,
578 const InstructionOperand& cur_op,
579 const InstructionBlock* pred,
580 const InstructionOperand& pred_op);
581
582 void SetLiveRangeAssignedRegister(LiveRange* range, int reg);
583
584 // Return the block which contains give lifetime position.
585 const InstructionBlock* GetInstructionBlock(LifetimePosition pos);
586
587 // Helper methods for the fixed registers. 657 // Helper methods for the fixed registers.
588 int RegisterCount() const; 658 int RegisterCount() const;
589 static int FixedLiveRangeID(int index) { return -index - 1; }
590 int FixedDoubleLiveRangeID(int index);
591 LiveRange* FixedLiveRangeFor(int index);
592 LiveRange* FixedDoubleLiveRangeFor(int index);
593 LiveRange* LiveRangeFor(int index);
594 Instruction* GetLastInstruction(const InstructionBlock* block);
595 659
596 const char* RegisterName(int allocation_index); 660 const char* RegisterName(int allocation_index);
597
598 Instruction* InstructionAt(int index) { return code()->InstructionAt(index); }
599 void AssignPhiInput(LiveRange* range, const InstructionOperand& assignment);
600
601 Frame* frame() const { return frame_; }
602 const char* debug_name() const { return debug_name_; }
603 const RegisterConfiguration* config() const { return config_; }
604 ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; }
605 ZoneVector<LiveRange*>& fixed_live_ranges() { return fixed_live_ranges_; }
606 ZoneVector<LiveRange*>& fixed_double_live_ranges() {
607 return fixed_double_live_ranges_;
608 }
609 ZoneVector<LiveRange*>& unhandled_live_ranges() { 661 ZoneVector<LiveRange*>& unhandled_live_ranges() {
610 return unhandled_live_ranges_; 662 return unhandled_live_ranges_;
611 } 663 }
612 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; } 664 ZoneVector<LiveRange*>& active_live_ranges() { return active_live_ranges_; }
613 ZoneVector<LiveRange*>& inactive_live_ranges() { 665 ZoneVector<LiveRange*>& inactive_live_ranges() {
614 return inactive_live_ranges_; 666 return inactive_live_ranges_;
615 } 667 }
616 ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; }
617 668
618 class PhiMapValue : public ZoneObject {
619 public:
620 PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone)
621 : phi(phi), block(block), incoming_moves(zone) {
622 incoming_moves.reserve(phi->operands().size());
623 }
624 PhiInstruction* const phi;
625 const InstructionBlock* const block;
626 ZoneVector<MoveOperands*> incoming_moves;
627 };
628 typedef ZoneMap<int, PhiMapValue*> PhiMap;
629 669
630 Zone* const local_zone_;
631 Frame* const frame_;
632 InstructionSequence* const code_;
633 const char* const debug_name_;
634
635 const RegisterConfiguration* config_;
636 PhiMap phi_map_;
637
638 // During liveness analysis keep a mapping from block id to live_in sets
639 // for blocks already analyzed.
640 ZoneVector<BitVector*> live_in_sets_;
641
642 // Liveness analysis results.
643 ZoneVector<LiveRange*> live_ranges_;
644
645 // Lists of live ranges
646 ZoneVector<LiveRange*> fixed_live_ranges_;
647 ZoneVector<LiveRange*> fixed_double_live_ranges_;
648 ZoneVector<LiveRange*> unhandled_live_ranges_; 670 ZoneVector<LiveRange*> unhandled_live_ranges_;
649 ZoneVector<LiveRange*> active_live_ranges_; 671 ZoneVector<LiveRange*> active_live_ranges_;
650 ZoneVector<LiveRange*> inactive_live_ranges_; 672 ZoneVector<LiveRange*> inactive_live_ranges_;
651 ZoneVector<SpillRange*> spill_ranges_;
652 673
653 RegisterKind mode_; 674 RegisterKind mode_;
654 int num_registers_; 675 int num_registers_;
655 676
656 BitVector* assigned_registers_;
657 BitVector* assigned_double_registers_;
658
659 #ifdef DEBUG 677 #ifdef DEBUG
660 LifetimePosition allocation_finger_; 678 LifetimePosition allocation_finger_;
661 #endif 679 #endif
662 680
663 DISALLOW_COPY_AND_ASSIGN(RegisterAllocator); 681 DISALLOW_COPY_AND_ASSIGN(RegisterAllocatorLinear);
682 };
683
684 class RegisterAllocatorGreedy FINAL : public RegisterAllocator {
685 public:
686 explicit RegisterAllocatorGreedy(const RegisterConfiguration* config,
687 Zone* local_zone, Frame* frame,
688 InstructionSequence* code,
689 const char* debug_name = nullptr);
690
691 void AllocateGeneralRegisters() override;
692 void AllocateDoubleRegisters() override;
693
694 private:
695 void AllocateRegisters(RegisterKind mode);
696 class RegisterAllocationInfo {
dcarney 2015/04/17 07:22:45 make ZoneObject
Mircea Trofin 2015/04/17 19:23:33 Done.
697 public:
698 explicit RegisterAllocationInfo(Zone* zone) : _storage(zone) {}
dcarney 2015/04/17 07:22:46 this class doesn't need to be in the header. also
Mircea Trofin 2015/04/17 19:23:34 Done.
699
700 bool find(UseInterval* query, LiveRange*& result) {
dcarney 2015/04/17 07:22:46 here and all over the place: functions in v8 start
Mircea Trofin 2015/04/17 19:23:34 Done.
701 ZoneSplayTree<Config>::Locator locator;
702 bool ret = _storage.Find(GetKey(query), &locator);
703 if (ret) result = locator.value();
704 return ret;
705 }
706
707 bool insert(LiveRange* range) {
708 auto* interval = range->first_interval();
709 while (interval) {
710 if (!insert(interval, range)) return false;
711 interval = interval->next();
712 }
713 return true;
714 }
715
716 bool remove(UseInterval* key) { return _storage.Remove(GetKey(key)); }
717
718 bool remove(LiveRange* range) {
719 bool ret = false;
720 auto* segment = range->first_interval();
721 while (segment) {
722 ret |= remove(segment);
723 segment = segment->next();
724 }
725 return ret;
726 }
727 int isEmpty() { return _storage.is_empty(); }
728
729 private:
730 struct Config {
731 typedef std::pair<int, int> Key;
732 typedef LiveRange* Value;
733 static const Key kNoKey;
734 static Value NoValue() { return nullptr; }
735 static int Compare(const Key& a, const Key& b) {
736 if (a.second <= b.first) return -1;
737 if (a.first >= b.second) return 1;
738 return 0;
739 }
740 };
741
742 Config::Key GetKey(UseInterval* interval) {
743 if (!interval) return std::make_pair(0, 0);
744 return std::make_pair(interval->start().Value(), interval->end().Value());
745 }
746 bool insert(UseInterval* interval, LiveRange* range) {
747 ZoneSplayTree<Config>::Locator locator;
748 bool ret = _storage.Insert(GetKey(interval), &locator);
749 if (ret) locator.set_value(range);
750 return ret;
751 }
752
753 ZoneSplayTree<Config> _storage;
dcarney 2015/04/17 07:22:45 in v8 this must be called storage_
Mircea Trofin 2015/04/17 19:23:34 Done.
754 };
dcarney 2015/04/17 07:22:45 the chromium style guide was DISALLOW_COPY_AND_ASS
Mircea Trofin 2015/04/17 19:23:33 Done.
755
756 typedef std::priority_queue<std::pair<unsigned, LiveRange*>> PQueue;
757
758 unsigned GetLiveRangeSize(LiveRange* range);
759 void Enqueue(LiveRange* range);
760
761 void Evict(LiveRange* range);
762 float CalculateSpillWeight(LiveRange* range);
763 float CalculateMaxSpillWeight(ZoneSet<LiveRange*> ranges);
dcarney 2015/04/17 07:22:46 you want ZoneSet<LiveRange*>* here to avoid epic l
Mircea Trofin 2015/04/17 19:23:34 Good catch, thanks! It was meant to be ZoneSet<Liv
764
765
766 bool TryAllocate(LiveRange* current, ZoneSet<LiveRange*>& conflicting);
dcarney 2015/04/17 07:22:45 ZoneSet<LiveRange*>* here as well, only const ref
Mircea Trofin 2015/04/17 19:23:34 Done.
767 bool TryAllocatePhysicalRegister(unsigned regId, LiveRange* range,
768 ZoneSet<LiveRange*>& conflicting);
769 bool HandleSpillOperands(LiveRange* range);
770 bool AllocateBlockedRange(LiveRange*, ZoneSet<LiveRange*>&);
771
772 LiveRange* SpillBetweenUntil(LiveRange* range, LifetimePosition start,
773 LifetimePosition until, LifetimePosition end);
774 void AssignRangeToRegister(unsigned regId, LiveRange* range);
775 PQueue queue_;
776 ZoneVector<RegisterAllocationInfo*> allocations_;
777 DISALLOW_COPY_AND_ASSIGN(RegisterAllocatorGreedy);
664 }; 778 };
665 779
666 } // namespace compiler 780 } // namespace compiler
667 } // namespace internal 781 } // namespace internal
668 } // namespace v8 782 } // namespace v8
669 783
670 #endif // V8_REGISTER_ALLOCATOR_H_ 784 #endif // V8_REGISTER_ALLOCATOR_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698