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 484 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 // the current Variable has an unambiguous "first" definition. The preference is | 495 // the current Variable has an unambiguous "first" definition. The preference is |
496 // some source Variable of the defining instruction that either is assigned a | 496 // some source Variable of the defining instruction that either is assigned a |
497 // register that is currently free, or that is assigned a register that is not | 497 // register that is currently free, or that is assigned a register that is not |
498 // free but overlap is allowed. Overlap is allowed when the Variable under | 498 // free but overlap is allowed. Overlap is allowed when the Variable under |
499 // consideration is single-definition, and its definition is a simple assignment | 499 // consideration is single-definition, and its definition is a simple assignment |
500 // - i.e., the register gets copied/aliased but is never modified. Furthermore, | 500 // - i.e., the register gets copied/aliased but is never modified. Furthermore, |
501 // overlap is only allowed when preferred Variable definition instructions do | 501 // overlap is only allowed when preferred Variable definition instructions do |
502 // not appear within the current Variable's live range. | 502 // not appear within the current Variable's live range. |
503 void LinearScan::findRegisterPreference(IterationState &Iter) { | 503 void LinearScan::findRegisterPreference(IterationState &Iter) { |
504 Iter.Prefer = nullptr; | 504 Iter.Prefer = nullptr; |
505 Iter.PreferReg = RegNumT::NoRegister; | 505 Iter.PreferReg = RegNumT(); |
506 Iter.AllowOverlap = false; | 506 Iter.AllowOverlap = false; |
507 | 507 |
508 if (!FindPreference) | 508 if (!FindPreference) |
509 return; | 509 return; |
510 | 510 |
511 VariablesMetadata *VMetadata = Func->getVMetadata(); | 511 VariablesMetadata *VMetadata = Func->getVMetadata(); |
512 const Inst *DefInst = VMetadata->getFirstDefinitionSingleBlock(Iter.Cur); | 512 const Inst *DefInst = VMetadata->getFirstDefinitionSingleBlock(Iter.Cur); |
513 if (DefInst == nullptr) | 513 if (DefInst == nullptr) |
514 return; | 514 return; |
515 | 515 |
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
731 const SizeT Index = I - 1; | 731 const SizeT Index = I - 1; |
732 Variable *Item = Active[Index]; | 732 Variable *Item = Active[Index]; |
733 const auto RegNum = Item->getRegNumTmp(); | 733 const auto RegNum = Item->getRegNumTmp(); |
734 if (Aliases[RegNum]) { | 734 if (Aliases[RegNum]) { |
735 dumpLiveRangeTrace("Evicting A ", Item); | 735 dumpLiveRangeTrace("Evicting A ", Item); |
736 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; | 736 const llvm::SmallBitVector &Aliases = *RegAliases[RegNum]; |
737 for (RegNumT RegAlias : RegNumBVIter(Aliases)) { | 737 for (RegNumT RegAlias : RegNumBVIter(Aliases)) { |
738 --RegUses[RegAlias]; | 738 --RegUses[RegAlias]; |
739 assert(RegUses[RegAlias] >= 0); | 739 assert(RegUses[RegAlias] >= 0); |
740 } | 740 } |
741 Item->setRegNumTmp(RegNumT::NoRegister); | 741 Item->setRegNumTmp(RegNumT()); |
742 moveItem(Active, Index, Handled); | 742 moveItem(Active, Index, Handled); |
743 Evicted.push_back(Item); | 743 Evicted.push_back(Item); |
744 } | 744 } |
745 } | 745 } |
746 // Do the same for Inactive. | 746 // Do the same for Inactive. |
747 for (SizeT I = Inactive.size(); I > 0; --I) { | 747 for (SizeT I = Inactive.size(); I > 0; --I) { |
748 const SizeT Index = I - 1; | 748 const SizeT Index = I - 1; |
749 Variable *Item = Inactive[Index]; | 749 Variable *Item = Inactive[Index]; |
750 // Note: The Item->rangeOverlaps(Cur) clause is not part of the description | 750 // Note: The Item->rangeOverlaps(Cur) clause is not part of the description |
751 // of AssignMemLoc() in the original paper. But there doesn't seem to be any | 751 // of AssignMemLoc() in the original paper. But there doesn't seem to be any |
752 // need to evict an inactive live range that doesn't overlap with the live | 752 // need to evict an inactive live range that doesn't overlap with the live |
753 // range currently being considered. It's especially bad if we would end up | 753 // range currently being considered. It's especially bad if we would end up |
754 // evicting an infinite-weight but currently-inactive live range. The most | 754 // evicting an infinite-weight but currently-inactive live range. The most |
755 // common situation for this would be a scratch register kill set for call | 755 // common situation for this would be a scratch register kill set for call |
756 // instructions. | 756 // instructions. |
757 if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) { | 757 if (Aliases[Item->getRegNumTmp()] && Item->rangeOverlaps(Iter.Cur)) { |
758 dumpLiveRangeTrace("Evicting I ", Item); | 758 dumpLiveRangeTrace("Evicting I ", Item); |
759 Item->setRegNumTmp(RegNumT::NoRegister); | 759 Item->setRegNumTmp(RegNumT()); |
760 moveItem(Inactive, Index, Handled); | 760 moveItem(Inactive, Index, Handled); |
761 Evicted.push_back(Item); | 761 Evicted.push_back(Item); |
762 } | 762 } |
763 } | 763 } |
764 // Assign the register to Cur. | 764 // Assign the register to Cur. |
765 Iter.Cur->setRegNumTmp(RegNumT::fromInt(MinWeightIndex)); | 765 Iter.Cur->setRegNumTmp(RegNumT::fromInt(MinWeightIndex)); |
766 for (RegNumT RegAlias : RegNumBVIter(Aliases)) { | 766 for (RegNumT RegAlias : RegNumBVIter(Aliases)) { |
767 assert(RegUses[RegAlias] >= 0); | 767 assert(RegUses[RegAlias] >= 0); |
768 ++RegUses[RegAlias]; | 768 ++RegUses[RegAlias]; |
769 } | 769 } |
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1011 Str << "\n"; | 1011 Str << "\n"; |
1012 } | 1012 } |
1013 Str << "++++++ Inactive:\n"; | 1013 Str << "++++++ Inactive:\n"; |
1014 for (const Variable *Item : Inactive) { | 1014 for (const Variable *Item : Inactive) { |
1015 dumpLiveRange(Item, Func); | 1015 dumpLiveRange(Item, Func); |
1016 Str << "\n"; | 1016 Str << "\n"; |
1017 } | 1017 } |
1018 } | 1018 } |
1019 | 1019 |
1020 } // end of namespace Ice | 1020 } // end of namespace Ice |
OLD | NEW |