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

Side by Side Diff: src/IceRegAlloc.cpp

Issue 1641653004: Subzero: Make the register allocator more robust with -reg-use and -reg-exclude. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Test code accidentally left in Created 4 years, 10 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
« no previous file with comments | « src/IceRegAlloc.h ('k') | src/IceTargetLowering.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/IceRegAlloc.h ('k') | src/IceTargetLowering.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698