OLD | NEW |
1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===// | 1 //===- subzero/src/IceRegAlloc.cpp - Linear-scan implementation -----------===// |
2 // | 2 // |
3 // The Subzero Code Generator | 3 // The Subzero Code Generator |
4 // | 4 // |
5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
7 // | 7 // |
8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
9 /// | 9 /// |
10 /// \file | 10 /// \file |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 if (!BuildDefs::dump()) | 69 if (!BuildDefs::dump()) |
70 return; | 70 return; |
71 Ostream &Str = Func->getContext()->getStrDump(); | 71 Ostream &Str = Func->getContext()->getStrDump(); |
72 char buf[30]; | 72 char buf[30]; |
73 snprintf(buf, llvm::array_lengthof(buf), "%2d", Var->getRegNumTmp()); | 73 snprintf(buf, llvm::array_lengthof(buf), "%2d", Var->getRegNumTmp()); |
74 Str << "R=" << buf << " V="; | 74 Str << "R=" << buf << " V="; |
75 Var->dump(Func); | 75 Var->dump(Func); |
76 Str << " Range=" << Var->getLiveRange(); | 76 Str << " Range=" << Var->getLiveRange(); |
77 } | 77 } |
78 | 78 |
| 79 int32_t findMinWeightIndex( |
| 80 const llvm::SmallBitVector &RegMask, |
| 81 const llvm::SmallVector<RegWeight, LinearScan::REGS_SIZE> &Weights) { |
| 82 int32_t MinWeightIndex = RegMask.find_first(); |
| 83 assert(MinWeightIndex >= 0); |
| 84 for (int32_t i = RegMask.find_next(MinWeightIndex); i != -1; |
| 85 i = RegMask.find_next(i)) { |
| 86 if (Weights[i] < Weights[MinWeightIndex]) |
| 87 MinWeightIndex = i; |
| 88 } |
| 89 return MinWeightIndex; |
| 90 } |
| 91 |
79 } // end of anonymous namespace | 92 } // end of anonymous namespace |
80 | 93 |
81 LinearScan::LinearScan(Cfg *Func) | 94 LinearScan::LinearScan(Cfg *Func) |
82 : Func(Func), Ctx(Func->getContext()), Target(Func->getTarget()), | 95 : Func(Func), Ctx(Func->getContext()), Target(Func->getTarget()), |
83 Verbose(BuildDefs::dump() && Func->isVerbose(IceV_LinearScan)) {} | 96 Verbose(BuildDefs::dump() && Func->isVerbose(IceV_LinearScan)), |
| 97 UseReserve(Ctx->getFlags().getRegAllocReserve()) {} |
84 | 98 |
85 // Prepare for full register allocation of all variables. We depend on liveness | 99 // Prepare for full register allocation of all variables. We depend on liveness |
86 // analysis to have calculated live ranges. | 100 // analysis to have calculated live ranges. |
87 void LinearScan::initForGlobal() { | 101 void LinearScan::initForGlobal() { |
88 TimerMarker T(TimerStack::TT_initUnhandled, Func); | 102 TimerMarker T(TimerStack::TT_initUnhandled, Func); |
89 FindPreference = true; | 103 FindPreference = true; |
90 // For full register allocation, normally we want to enable FindOverlap | 104 // For full register allocation, normally we want to enable FindOverlap |
91 // (meaning we look for opportunities for two overlapping live ranges to | 105 // (meaning we look for opportunities for two overlapping live ranges to |
92 // safely share the same register). However, we disable it for phi-lowering | 106 // safely share the same register). However, we disable it for phi-lowering |
93 // register allocation since no overlap opportunities should be available and | 107 // register allocation since no overlap opportunities should be available and |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
538 } | 552 } |
539 if (BuildDefs::dump() && Verbose && Iter.Prefer) { | 553 if (BuildDefs::dump() && Verbose && Iter.Prefer) { |
540 Ostream &Str = Ctx->getStrDump(); | 554 Ostream &Str = Ctx->getStrDump(); |
541 Str << "Initial Iter.Prefer="; | 555 Str << "Initial Iter.Prefer="; |
542 Iter.Prefer->dump(Func); | 556 Iter.Prefer->dump(Func); |
543 Str << " R=" << Iter.PreferReg << " LIVE=" << Iter.Prefer->getLiveRange() | 557 Str << " R=" << Iter.PreferReg << " LIVE=" << Iter.Prefer->getLiveRange() |
544 << " Overlap=" << Iter.AllowOverlap << "\n"; | 558 << " Overlap=" << Iter.AllowOverlap << "\n"; |
545 } | 559 } |
546 } | 560 } |
547 | 561 |
548 // Remove registers from the Free[] list where an Inactive range overlaps with | 562 // Remove registers from the Iter.Free[] list where an Inactive range overlaps |
549 // the current range. | 563 // with the current range. |
550 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { | 564 void LinearScan::filterFreeWithInactiveRanges(IterationState &Iter) { |
551 for (const Variable *Item : Inactive) { | 565 for (const Variable *Item : Inactive) { |
552 if (!Item->rangeOverlaps(Iter.Cur)) | 566 if (!Item->rangeOverlaps(Iter.Cur)) |
553 continue; | 567 continue; |
554 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; | 568 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
555 // TODO(stichnot): Do this with bitvector ops, not a loop, for efficiency. | 569 // TODO(stichnot): Do this with bitvector ops, not a loop, for efficiency. |
556 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | 570 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
557 RegAlias = Aliases.find_next(RegAlias)) { | 571 RegAlias = Aliases.find_next(RegAlias)) { |
558 // Don't assert(Free[RegNum]) because in theory (though probably never in | 572 // Don't assert(Iter.Free[RegNum]) because in theory (though probably |
559 // practice) there could be two inactive variables that were marked with | 573 // never in practice) there could be two inactive variables that were |
560 // AllowOverlap. | 574 // marked with AllowOverlap. |
561 Iter.Free[RegAlias] = false; | 575 Iter.Free[RegAlias] = false; |
| 576 Iter.FreeUnfiltered[RegAlias] = false; |
562 // Disable AllowOverlap if an Inactive variable, which is not Prefer, | 577 // Disable AllowOverlap if an Inactive variable, which is not Prefer, |
563 // shares Prefer's register, and has a definition within Cur's live range. | 578 // shares Prefer's register, and has a definition within Cur's live range. |
564 if (Iter.AllowOverlap && Item != Iter.Prefer && | 579 if (Iter.AllowOverlap && Item != Iter.Prefer && |
565 RegAlias == Iter.PreferReg && overlapsDefs(Func, Iter.Cur, Item)) { | 580 RegAlias == Iter.PreferReg && overlapsDefs(Func, Iter.Cur, Item)) { |
566 Iter.AllowOverlap = false; | 581 Iter.AllowOverlap = false; |
567 dumpDisableOverlap(Func, Item, "Inactive"); | 582 dumpDisableOverlap(Func, Item, "Inactive"); |
568 } | 583 } |
569 } | 584 } |
570 } | 585 } |
571 } | 586 } |
572 | 587 |
573 // Remove registers from the Free[] list where an Unhandled pre-colored range | 588 // Remove registers from the Iter.Free[] list where an Unhandled pre-colored |
574 // overlaps with the current range, and set those registers to infinite weight | 589 // range overlaps with the current range, and set those registers to infinite |
575 // so that they aren't candidates for eviction. Cur->rangeEndsBefore(Item) is an | 590 // weight so that they aren't candidates for eviction. |
576 // early exit check that turns a guaranteed O(N^2) algorithm into expected | 591 // Cur->rangeEndsBefore(Item) is an early exit check that turns a guaranteed |
577 // linear complexity. | 592 // O(N^2) algorithm into expected linear complexity. |
578 void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) { | 593 void LinearScan::filterFreeWithPrecoloredRanges(IterationState &Iter) { |
579 // TODO(stichnot): Partition UnhandledPrecolored according to register class, | 594 // TODO(stichnot): Partition UnhandledPrecolored according to register class, |
580 // to restrict the number of overlap comparisons needed. | 595 // to restrict the number of overlap comparisons needed. |
581 for (Variable *Item : reverse_range(UnhandledPrecolored)) { | 596 for (Variable *Item : reverse_range(UnhandledPrecolored)) { |
582 assert(Item->hasReg()); | 597 assert(Item->hasReg()); |
583 if (Iter.Cur->rangeEndsBefore(Item)) | 598 if (Iter.Cur->rangeEndsBefore(Item)) |
584 break; | 599 break; |
585 if (!Item->rangeOverlaps(Iter.Cur)) | 600 if (!Item->rangeOverlaps(Iter.Cur)) |
586 continue; | 601 continue; |
587 const llvm::SmallBitVector &Aliases = | 602 const llvm::SmallBitVector &Aliases = |
588 *RegAliases[Item->getRegNum()]; // Note: not getRegNumTmp() | 603 *RegAliases[Item->getRegNum()]; // Note: not getRegNumTmp() |
589 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | 604 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
590 RegAlias = Aliases.find_next(RegAlias)) { | 605 RegAlias = Aliases.find_next(RegAlias)) { |
591 Iter.Weights[RegAlias].setWeight(RegWeight::Inf); | 606 Iter.Weights[RegAlias].setWeight(RegWeight::Inf); |
592 Iter.Free[RegAlias] = false; | 607 Iter.Free[RegAlias] = false; |
| 608 Iter.FreeUnfiltered[RegAlias] = false; |
593 Iter.PrecoloredUnhandledMask[RegAlias] = true; | 609 Iter.PrecoloredUnhandledMask[RegAlias] = true; |
594 // Disable Iter.AllowOverlap if the preferred register is one of these | 610 // Disable Iter.AllowOverlap if the preferred register is one of these |
595 // pre-colored unhandled overlapping ranges. | 611 // pre-colored unhandled overlapping ranges. |
596 if (Iter.AllowOverlap && RegAlias == Iter.PreferReg) { | 612 if (Iter.AllowOverlap && RegAlias == Iter.PreferReg) { |
597 Iter.AllowOverlap = false; | 613 Iter.AllowOverlap = false; |
598 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled"); | 614 dumpDisableOverlap(Func, Item, "PrecoloredUnhandled"); |
599 } | 615 } |
600 } | 616 } |
601 } | 617 } |
602 } | 618 } |
(...skipping 20 matching lines...) Expand all Loading... |
623 dumpLiveRangeTrace("Preferring ", Iter.Cur); | 639 dumpLiveRangeTrace("Preferring ", Iter.Cur); |
624 const llvm::SmallBitVector &Aliases = *RegAliases[Iter.PreferReg]; | 640 const llvm::SmallBitVector &Aliases = *RegAliases[Iter.PreferReg]; |
625 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | 641 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
626 RegAlias = Aliases.find_next(RegAlias)) { | 642 RegAlias = Aliases.find_next(RegAlias)) { |
627 assert(RegUses[RegAlias] >= 0); | 643 assert(RegUses[RegAlias] >= 0); |
628 ++RegUses[RegAlias]; | 644 ++RegUses[RegAlias]; |
629 } | 645 } |
630 Active.push_back(Iter.Cur); | 646 Active.push_back(Iter.Cur); |
631 } | 647 } |
632 | 648 |
633 void LinearScan::allocateFreeRegister(IterationState &Iter) { | 649 void LinearScan::allocateFreeRegister(IterationState &Iter, bool Filtered) { |
634 int32_t RegNum = Iter.Free.find_first(); | 650 const int32_t RegNum = |
| 651 Filtered ? Iter.Free.find_first() : Iter.FreeUnfiltered.find_first(); |
635 Iter.Cur->setRegNumTmp(RegNum); | 652 Iter.Cur->setRegNumTmp(RegNum); |
636 dumpLiveRangeTrace("Allocating ", Iter.Cur); | 653 if (Filtered) |
| 654 dumpLiveRangeTrace("Allocating ", Iter.Cur); |
| 655 else |
| 656 dumpLiveRangeTrace("Allocating X ", Iter.Cur); |
637 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; | 657 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; |
638 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | 658 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
639 RegAlias = Aliases.find_next(RegAlias)) { | 659 RegAlias = Aliases.find_next(RegAlias)) { |
640 assert(RegUses[RegAlias] >= 0); | 660 assert(RegUses[RegAlias] >= 0); |
641 ++RegUses[RegAlias]; | 661 ++RegUses[RegAlias]; |
642 } | 662 } |
643 Active.push_back(Iter.Cur); | 663 Active.push_back(Iter.Cur); |
644 } | 664 } |
645 | 665 |
646 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { | 666 void LinearScan::handleNoFreeRegisters(IterationState &Iter) { |
(...skipping 18 matching lines...) Expand all Loading... |
665 assert(Item->hasRegTmp()); | 685 assert(Item->hasRegTmp()); |
666 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; | 686 const llvm::SmallBitVector &Aliases = *RegAliases[Item->getRegNumTmp()]; |
667 RegWeight W = Item->getWeight(Func); | 687 RegWeight W = Item->getWeight(Func); |
668 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | 688 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
669 RegAlias = Aliases.find_next(RegAlias)) { | 689 RegAlias = Aliases.find_next(RegAlias)) { |
670 Iter.Weights[RegAlias].addWeight(W); | 690 Iter.Weights[RegAlias].addWeight(W); |
671 } | 691 } |
672 } | 692 } |
673 | 693 |
674 // All the weights are now calculated. Find the register with smallest weight. | 694 // All the weights are now calculated. Find the register with smallest weight. |
675 int32_t MinWeightIndex = Iter.RegMask.find_first(); | 695 int32_t MinWeightIndex = findMinWeightIndex(Iter.RegMask, Iter.Weights); |
676 // MinWeightIndex must be valid because of the initial RegMask.any() test. | 696 |
677 assert(MinWeightIndex >= 0); | 697 if (Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) { |
678 for (SizeT i = MinWeightIndex + 1; i < Iter.Weights.size(); ++i) { | 698 if (!Iter.Cur->mustHaveReg()) { |
679 if (Iter.RegMask[i] && Iter.Weights[i] < Iter.Weights[MinWeightIndex]) | 699 // Iter.Cur doesn't have priority over any other live ranges, so don't |
680 MinWeightIndex = i; | 700 // allocate any register to it, and move it to the Handled state. |
| 701 Handled.push_back(Iter.Cur); |
| 702 return; |
| 703 } |
| 704 if (Kind == RAK_Phi) { |
| 705 // Iter.Cur is infinite-weight but all physical registers are already |
| 706 // taken, so we need to force one to be temporarily available. |
| 707 addSpillFill(Iter); |
| 708 Handled.push_back(Iter.Cur); |
| 709 return; |
| 710 } |
| 711 // The remaining portion of the enclosing "if" block should only be |
| 712 // reachable if we are manually limiting physical registers for testing. |
| 713 if (UseReserve) { |
| 714 if (Iter.FreeUnfiltered.any()) { |
| 715 // There is some available physical register held in reserve, so use it. |
| 716 constexpr bool NotFiltered = false; |
| 717 allocateFreeRegister(Iter, NotFiltered); |
| 718 // Iter.Cur is now on the Active list. |
| 719 return; |
| 720 } |
| 721 // At this point, we need to find some reserve register that is already |
| 722 // assigned to a non-infinite-weight variable. This could happen if some |
| 723 // variable was previously assigned an alias of such a register. |
| 724 MinWeightIndex = findMinWeightIndex(Iter.RegMaskUnfiltered, Iter.Weights); |
| 725 } |
| 726 if (Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) { |
| 727 dumpLiveRangeTrace("Failing ", Iter.Cur); |
| 728 Func->setError("Unable to find a physical register for an " |
| 729 "infinite-weight live range " |
| 730 "(consider using -reg-reserve): " + |
| 731 Iter.Cur->getName(Func)); |
| 732 Handled.push_back(Iter.Cur); |
| 733 return; |
| 734 } |
| 735 // At this point, MinWeightIndex points to a valid reserve register to |
| 736 // reallocate to Iter.Cur, so drop into the eviction code. |
681 } | 737 } |
682 | 738 |
683 if (Iter.Cur->getWeight(Func) <= Iter.Weights[MinWeightIndex]) { | 739 // Evict all live ranges in Active that register number MinWeightIndex is |
684 // Cur doesn't have priority over any other live ranges, so don't allocate | 740 // assigned to. |
685 // any register to it, and move it to the Handled state. | 741 const llvm::SmallBitVector &Aliases = *RegAliases[MinWeightIndex]; |
686 Handled.push_back(Iter.Cur); | 742 for (SizeT I = Active.size(); I > 0; --I) { |
687 if (Iter.Cur->mustHaveReg()) { | 743 const SizeT Index = I - 1; |
688 if (Kind == RAK_Phi) { | 744 Variable *Item = Active[Index]; |
689 addSpillFill(Iter); | 745 int32_t RegNum = Item->getRegNumTmp(); |
690 } else { | 746 if (Aliases[RegNum]) { |
691 dumpLiveRangeTrace("Failing ", Iter.Cur); | 747 dumpLiveRangeTrace("Evicting A ", Item); |
692 Func->setError("Unable to find a physical register for an " | 748 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; |
693 "infinite-weight live range: " + | 749 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
694 Iter.Cur->getName(Func)); | 750 RegAlias = Aliases.find_next(RegAlias)) { |
| 751 --RegUses[RegAlias]; |
| 752 assert(RegUses[RegAlias] >= 0); |
695 } | 753 } |
| 754 Item->setRegNumTmp(Variable::NoRegister); |
| 755 moveItem(Active, Index, Handled); |
| 756 Evicted.push_back(Item); |
696 } | 757 } |
697 } else { | 758 } |
698 // Evict all live ranges in Active that register number MinWeightIndex is | 759 // Do the same for Inactive. |
699 // assigned to. | 760 for (SizeT I = Inactive.size(); I > 0; --I) { |
700 const llvm::SmallBitVector &Aliases = *RegAliases[MinWeightIndex]; | 761 const SizeT Index = I - 1; |
701 for (SizeT I = Active.size(); I > 0; --I) { | 762 Variable *Item = Inactive[Index]; |
702 const SizeT Index = I - 1; | 763 // Note: The Item->rangeOverlaps(Cur) clause is not part of the description |
703 Variable *Item = Active[Index]; | 764 // of AssignMemLoc() in the original paper. But there doesn't seem to be any |
704 int32_t RegNum = Item->getRegNumTmp(); | 765 // need to evict an inactive live range that doesn't overlap with the live |
705 if (Aliases[RegNum]) { | 766 // range currently being considered. It's especially bad if we would end up |
706 dumpLiveRangeTrace("Evicting A ", Item); | 767 // evicting an infinite-weight but currently-inactive live range. The most |
707 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; | 768 // common situation for this would be a scratch register kill set for call |
708 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | 769 // instructions. |
709 RegAlias = Aliases.find_next(RegAlias)) { | 770 if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) { |
710 --RegUses[RegAlias]; | 771 dumpLiveRangeTrace("Evicting I ", Item); |
711 assert(RegUses[RegAlias] >= 0); | 772 Item->setRegNumTmp(Variable::NoRegister); |
712 } | 773 moveItem(Inactive, Index, Handled); |
713 Item->setRegNumTmp(Variable::NoRegister); | 774 Evicted.push_back(Item); |
714 moveItem(Active, Index, Handled); | |
715 Evicted.push_back(Item); | |
716 } | |
717 } | 775 } |
718 // Do the same for Inactive. | |
719 for (SizeT I = Inactive.size(); I > 0; --I) { | |
720 const SizeT Index = I - 1; | |
721 Variable *Item = Inactive[Index]; | |
722 // Note: The Item->rangeOverlaps(Cur) clause is not part of the | |
723 // description of AssignMemLoc() in the original paper. But there doesn't | |
724 // seem to be any need to evict an inactive live range that doesn't | |
725 // overlap with the live range currently being considered. It's especially | |
726 // bad if we would end up evicting an infinite-weight but | |
727 // currently-inactive live range. The most common situation for this would | |
728 // be a scratch register kill set for call instructions. | |
729 if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) { | |
730 dumpLiveRangeTrace("Evicting I ", Item); | |
731 Item->setRegNumTmp(Variable::NoRegister); | |
732 moveItem(Inactive, Index, Handled); | |
733 Evicted.push_back(Item); | |
734 } | |
735 } | |
736 // Assign the register to Cur. | |
737 Iter.Cur->setRegNumTmp(MinWeightIndex); | |
738 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; | |
739 RegAlias = Aliases.find_next(RegAlias)) { | |
740 assert(RegUses[RegAlias] >= 0); | |
741 ++RegUses[RegAlias]; | |
742 } | |
743 Active.push_back(Iter.Cur); | |
744 dumpLiveRangeTrace("Allocating ", Iter.Cur); | |
745 } | 776 } |
| 777 // Assign the register to Cur. |
| 778 Iter.Cur->setRegNumTmp(MinWeightIndex); |
| 779 for (int32_t RegAlias = Aliases.find_first(); RegAlias >= 0; |
| 780 RegAlias = Aliases.find_next(RegAlias)) { |
| 781 assert(RegUses[RegAlias] >= 0); |
| 782 ++RegUses[RegAlias]; |
| 783 } |
| 784 Active.push_back(Iter.Cur); |
| 785 dumpLiveRangeTrace("Allocating ", Iter.Cur); |
746 } | 786 } |
747 | 787 |
748 void LinearScan::assignFinalRegisters( | 788 void LinearScan::assignFinalRegisters( |
749 const llvm::SmallBitVector &RegMaskFull, | 789 const llvm::SmallBitVector &RegMaskFull, |
750 const llvm::SmallBitVector &PreDefinedRegisters, bool Randomized) { | 790 const llvm::SmallBitVector &PreDefinedRegisters, bool Randomized) { |
751 const size_t NumRegisters = RegMaskFull.size(); | 791 const size_t NumRegisters = RegMaskFull.size(); |
752 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); | 792 llvm::SmallVector<int32_t, REGS_SIZE> Permutation(NumRegisters); |
753 if (Randomized) { | 793 if (Randomized) { |
754 // Create a random number generator for regalloc randomization. Merge | 794 // Create a random number generator for regalloc randomization. Merge |
755 // function's sequence and Kind value as the Salt. Because regAlloc() is | 795 // function's sequence and Kind value as the Salt. Because regAlloc() is |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
836 IterationState Iter; | 876 IterationState Iter; |
837 Iter.Weights.reserve(NumRegisters); | 877 Iter.Weights.reserve(NumRegisters); |
838 Iter.PrecoloredUnhandledMask.reserve(NumRegisters); | 878 Iter.PrecoloredUnhandledMask.reserve(NumRegisters); |
839 | 879 |
840 while (!Unhandled.empty()) { | 880 while (!Unhandled.empty()) { |
841 Iter.Cur = Unhandled.back(); | 881 Iter.Cur = Unhandled.back(); |
842 Unhandled.pop_back(); | 882 Unhandled.pop_back(); |
843 dumpLiveRangeTrace("\nConsidering ", Iter.Cur); | 883 dumpLiveRangeTrace("\nConsidering ", Iter.Cur); |
844 assert(Target->getRegistersForVariable(Iter.Cur).any()); | 884 assert(Target->getRegistersForVariable(Iter.Cur).any()); |
845 Iter.RegMask = RegMaskFull & Target->getRegistersForVariable(Iter.Cur); | 885 Iter.RegMask = RegMaskFull & Target->getRegistersForVariable(Iter.Cur); |
| 886 Iter.RegMaskUnfiltered = |
| 887 RegMaskFull & Target->getAllRegistersForVariable(Iter.Cur); |
846 KillsRange.trim(Iter.Cur->getLiveRange().getStart()); | 888 KillsRange.trim(Iter.Cur->getLiveRange().getStart()); |
847 | 889 |
848 // Check for pre-colored ranges. If Cur is pre-colored, it definitely gets | 890 // Check for pre-colored ranges. If Cur is pre-colored, it definitely gets |
849 // that register. Previously processed live ranges would have avoided that | 891 // that register. Previously processed live ranges would have avoided that |
850 // register due to it being pre-colored. Future processed live ranges won't | 892 // register due to it being pre-colored. Future processed live ranges won't |
851 // evict that register because the live range has infinite weight. | 893 // evict that register because the live range has infinite weight. |
852 if (Iter.Cur->hasReg()) { | 894 if (Iter.Cur->hasReg()) { |
853 allocatePrecoloredRegister(Iter.Cur); | 895 allocatePrecoloredRegister(Iter.Cur); |
854 continue; | 896 continue; |
855 } | 897 } |
856 | 898 |
857 handleActiveRangeExpiredOrInactive(Iter.Cur); | 899 handleActiveRangeExpiredOrInactive(Iter.Cur); |
858 handleInactiveRangeExpiredOrReactivated(Iter.Cur); | 900 handleInactiveRangeExpiredOrReactivated(Iter.Cur); |
859 | 901 |
860 // Calculate available registers into Free[]. | 902 // Calculate available registers into Iter.Free[] and Iter.FreeUnfiltered[]. |
861 Iter.Free = Iter.RegMask; | 903 Iter.Free = Iter.RegMask; |
| 904 Iter.FreeUnfiltered = Iter.RegMaskUnfiltered; |
862 for (SizeT i = 0; i < Iter.RegMask.size(); ++i) { | 905 for (SizeT i = 0; i < Iter.RegMask.size(); ++i) { |
863 if (RegUses[i] > 0) | 906 if (RegUses[i] > 0) { |
864 Iter.Free[i] = false; | 907 Iter.Free[i] = false; |
| 908 Iter.FreeUnfiltered[i] = false; |
| 909 } |
865 } | 910 } |
866 | 911 |
867 findRegisterPreference(Iter); | 912 findRegisterPreference(Iter); |
868 filterFreeWithInactiveRanges(Iter); | 913 filterFreeWithInactiveRanges(Iter); |
869 | 914 |
870 // Disable AllowOverlap if an Active variable, which is not Prefer, shares | 915 // Disable AllowOverlap if an Active variable, which is not Prefer, shares |
871 // Prefer's register, and has a definition within Cur's live range. | 916 // Prefer's register, and has a definition within Cur's live range. |
872 if (Iter.AllowOverlap) { | 917 if (Iter.AllowOverlap) { |
873 const llvm::SmallBitVector &Aliases = *RegAliases[Iter.PreferReg]; | 918 const llvm::SmallBitVector &Aliases = *RegAliases[Iter.PreferReg]; |
874 for (const Variable *Item : Active) { | 919 for (const Variable *Item : Active) { |
875 int32_t RegNum = Item->getRegNumTmp(); | 920 int32_t RegNum = Item->getRegNumTmp(); |
876 if (Item != Iter.Prefer && Aliases[RegNum] && | 921 if (Item != Iter.Prefer && Aliases[RegNum] && |
877 overlapsDefs(Func, Iter.Cur, Item)) { | 922 overlapsDefs(Func, Iter.Cur, Item)) { |
878 Iter.AllowOverlap = false; | 923 Iter.AllowOverlap = false; |
879 dumpDisableOverlap(Func, Item, "Active"); | 924 dumpDisableOverlap(Func, Item, "Active"); |
880 } | 925 } |
881 } | 926 } |
882 } | 927 } |
883 | 928 |
884 Iter.Weights.resize(Iter.RegMask.size()); | 929 Iter.Weights.resize(Iter.RegMask.size()); |
885 std::fill(Iter.Weights.begin(), Iter.Weights.end(), RegWeight()); | 930 std::fill(Iter.Weights.begin(), Iter.Weights.end(), RegWeight()); |
886 | 931 |
887 Iter.PrecoloredUnhandledMask.resize(Iter.RegMask.size()); | 932 Iter.PrecoloredUnhandledMask.resize(Iter.RegMask.size()); |
888 Iter.PrecoloredUnhandledMask.reset(); | 933 Iter.PrecoloredUnhandledMask.reset(); |
889 | 934 |
890 filterFreeWithPrecoloredRanges(Iter); | 935 filterFreeWithPrecoloredRanges(Iter); |
891 | 936 |
892 // Remove scratch registers from the Free[] list, and mark their Weights[] | 937 // Remove scratch registers from the Iter.Free[] list, and mark their |
893 // as infinite, if KillsRange overlaps Cur's live range. | 938 // Iter.Weights[] as infinite, if KillsRange overlaps Cur's live range. |
894 constexpr bool UseTrimmed = true; | 939 constexpr bool UseTrimmed = true; |
895 if (Iter.Cur->getLiveRange().overlaps(KillsRange, UseTrimmed)) { | 940 if (Iter.Cur->getLiveRange().overlaps(KillsRange, UseTrimmed)) { |
896 Iter.Free.reset(KillsMask); | 941 Iter.Free.reset(KillsMask); |
| 942 Iter.FreeUnfiltered.reset(KillsMask); |
897 for (int i = KillsMask.find_first(); i != -1; | 943 for (int i = KillsMask.find_first(); i != -1; |
898 i = KillsMask.find_next(i)) { | 944 i = KillsMask.find_next(i)) { |
899 Iter.Weights[i].setWeight(RegWeight::Inf); | 945 Iter.Weights[i].setWeight(RegWeight::Inf); |
900 if (Iter.PreferReg == i) | 946 if (Iter.PreferReg == i) |
901 Iter.AllowOverlap = false; | 947 Iter.AllowOverlap = false; |
902 } | 948 } |
903 } | 949 } |
904 | 950 |
905 // Print info about physical register availability. | 951 // Print info about physical register availability. |
906 if (BuildDefs::dump() && Verbose) { | 952 if (BuildDefs::dump() && Verbose) { |
907 Ostream &Str = Ctx->getStrDump(); | 953 Ostream &Str = Ctx->getStrDump(); |
908 for (SizeT i = 0; i < Iter.RegMask.size(); ++i) { | 954 for (SizeT i = 0; i < Iter.RegMask.size(); ++i) { |
909 if (Iter.RegMask[i]) { | 955 if (Iter.RegMaskUnfiltered[i]) { |
910 Str << Target->getRegName(i, Iter.Cur->getType()) | 956 Str << Target->getRegName(i, Iter.Cur->getType()) |
911 << "(U=" << RegUses[i] << ",F=" << Iter.Free[i] | 957 << "(U=" << RegUses[i] << ",F=" << Iter.Free[i] |
912 << ",P=" << Iter.PrecoloredUnhandledMask[i] << ") "; | 958 << ",P=" << Iter.PrecoloredUnhandledMask[i] << ") "; |
913 } | 959 } |
914 } | 960 } |
915 Str << "\n"; | 961 Str << "\n"; |
916 } | 962 } |
917 | 963 |
918 if (Iter.Prefer && (Iter.AllowOverlap || Iter.Free[Iter.PreferReg])) { | 964 if (Iter.Prefer && (Iter.AllowOverlap || Iter.Free[Iter.PreferReg])) { |
919 // First choice: a preferred register that is either free or is allowed to | 965 // First choice: a preferred register that is either free or is allowed to |
920 // overlap with its linked variable. | 966 // overlap with its linked variable. |
921 allocatePreferredRegister(Iter); | 967 allocatePreferredRegister(Iter); |
922 } else if (Iter.Free.any()) { | 968 } else if (Iter.Free.any()) { |
923 // Second choice: any free register. | 969 // Second choice: any free register. |
924 allocateFreeRegister(Iter); | 970 constexpr bool Filtered = true; |
| 971 allocateFreeRegister(Iter, Filtered); |
925 } else { | 972 } else { |
926 // Fallback: there are no free registers, so we look for the lowest-weight | 973 // Fallback: there are no free registers, so we look for the lowest-weight |
927 // register and see if Cur has higher weight. | 974 // register and see if Cur has higher weight. |
928 handleNoFreeRegisters(Iter); | 975 handleNoFreeRegisters(Iter); |
929 } | 976 } |
930 dump(Func); | 977 dump(Func); |
931 } | 978 } |
932 | 979 |
933 // Move anything Active or Inactive to Handled for easier handling. | 980 // Move anything Active or Inactive to Handled for easier handling. |
934 Handled.insert(Handled.end(), Active.begin(), Active.end()); | 981 Handled.insert(Handled.end(), Active.begin(), Active.end()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
981 Str << "\n"; | 1028 Str << "\n"; |
982 } | 1029 } |
983 Str << "++++++ Inactive:\n"; | 1030 Str << "++++++ Inactive:\n"; |
984 for (const Variable *Item : Inactive) { | 1031 for (const Variable *Item : Inactive) { |
985 dumpLiveRange(Item, Func); | 1032 dumpLiveRange(Item, Func); |
986 Str << "\n"; | 1033 Str << "\n"; |
987 } | 1034 } |
988 } | 1035 } |
989 | 1036 |
990 } // end of namespace Ice | 1037 } // end of namespace Ice |
OLD | NEW |