1c8fbf6ffSEugene Zelenko //===- GCNRegPressure.cpp -------------------------------------------------===//
2fd4c410fSValery Pykhtin //
32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fd4c410fSValery Pykhtin //
7fd4c410fSValery Pykhtin //===----------------------------------------------------------------------===//
81d9e08ecShsmahesha ///
91d9e08ecShsmahesha /// \file
101d9e08ecShsmahesha /// This file implements the GCNRegPressure class.
111d9e08ecShsmahesha ///
121d9e08ecShsmahesha //===----------------------------------------------------------------------===//
13fd4c410fSValery Pykhtin 
14fd4c410fSValery Pykhtin #include "GCNRegPressure.h"
1574cb9c88SValery Pykhtin #include "llvm/CodeGen/RegisterPressure.h"
16fd4c410fSValery Pykhtin 
17fd4c410fSValery Pykhtin using namespace llvm;
18fd4c410fSValery Pykhtin 
190cd23f56SEvandro Menezes #define DEBUG_TYPE "machine-scheduler"
20fd4c410fSValery Pykhtin 
21615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
22fd4c410fSValery Pykhtin LLVM_DUMP_METHOD
printLivesAt(SlotIndex SI,const LiveIntervals & LIS,const MachineRegisterInfo & MRI)23fd4c410fSValery Pykhtin void llvm::printLivesAt(SlotIndex SI,
24fd4c410fSValery Pykhtin                         const LiveIntervals &LIS,
25fd4c410fSValery Pykhtin                         const MachineRegisterInfo &MRI) {
26fd4c410fSValery Pykhtin   dbgs() << "Live regs at " << SI << ": "
27fd4c410fSValery Pykhtin          << *LIS.getInstructionFromIndex(SI);
28fd4c410fSValery Pykhtin   unsigned Num = 0;
29fd4c410fSValery Pykhtin   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
30*d6b07348SJim Lin     const Register Reg = Register::index2VirtReg(I);
31464cecf8SStanislav Mekhanoshin     if (!LIS.hasInterval(Reg))
32fd4c410fSValery Pykhtin       continue;
33fd4c410fSValery Pykhtin     const auto &LI = LIS.getInterval(Reg);
34fd4c410fSValery Pykhtin     if (LI.hasSubRanges()) {
35fd4c410fSValery Pykhtin       bool firstTime = true;
36fd4c410fSValery Pykhtin       for (const auto &S : LI.subranges()) {
37fd4c410fSValery Pykhtin         if (!S.liveAt(SI)) continue;
38fd4c410fSValery Pykhtin         if (firstTime) {
399d419d3bSFrancis Visoiu Mistrih           dbgs() << "  " << printReg(Reg, MRI.getTargetRegisterInfo())
40fd4c410fSValery Pykhtin                  << '\n';
41fd4c410fSValery Pykhtin           firstTime = false;
42fd4c410fSValery Pykhtin         }
43fd4c410fSValery Pykhtin         dbgs() << "  " << S << '\n';
44fd4c410fSValery Pykhtin         ++Num;
45fd4c410fSValery Pykhtin       }
46fd4c410fSValery Pykhtin     } else if (LI.liveAt(SI)) {
47fd4c410fSValery Pykhtin       dbgs() << "  " << LI << '\n';
48fd4c410fSValery Pykhtin       ++Num;
49fd4c410fSValery Pykhtin     }
50fd4c410fSValery Pykhtin   }
51fd4c410fSValery Pykhtin   if (!Num) dbgs() << "  <none>\n";
52fd4c410fSValery Pykhtin }
537e854e1cSValery Pykhtin #endif
54fd4c410fSValery Pykhtin 
isEqual(const GCNRPTracker::LiveRegSet & S1,const GCNRPTracker::LiveRegSet & S2)557e854e1cSValery Pykhtin bool llvm::isEqual(const GCNRPTracker::LiveRegSet &S1,
56fd4c410fSValery Pykhtin                    const GCNRPTracker::LiveRegSet &S2) {
57fd4c410fSValery Pykhtin   if (S1.size() != S2.size())
58fd4c410fSValery Pykhtin     return false;
59fd4c410fSValery Pykhtin 
60fd4c410fSValery Pykhtin   for (const auto &P : S1) {
61fd4c410fSValery Pykhtin     auto I = S2.find(P.first);
62fd4c410fSValery Pykhtin     if (I == S2.end() || I->second != P.second)
63fd4c410fSValery Pykhtin       return false;
64fd4c410fSValery Pykhtin   }
65fd4c410fSValery Pykhtin   return true;
66fd4c410fSValery Pykhtin }
677e854e1cSValery Pykhtin 
68fd4c410fSValery Pykhtin 
69fd4c410fSValery Pykhtin ///////////////////////////////////////////////////////////////////////////////
70fd4c410fSValery Pykhtin // GCNRegPressure
71fd4c410fSValery Pykhtin 
getRegKind(Register Reg,const MachineRegisterInfo & MRI)7234978602SJay Foad unsigned GCNRegPressure::getRegKind(Register Reg,
73fd4c410fSValery Pykhtin                                     const MachineRegisterInfo &MRI) {
7434978602SJay Foad   assert(Reg.isVirtual());
75fd4c410fSValery Pykhtin   const auto RC = MRI.getRegClass(Reg);
76fd4c410fSValery Pykhtin   auto STI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo());
77654c89d8SChristudasan Devadasan   return STI->isSGPRClass(RC)
78654c89d8SChristudasan Devadasan              ? (STI->getRegSizeInBits(*RC) == 32 ? SGPR32 : SGPR_TUPLE)
79654c89d8SChristudasan Devadasan          : STI->isAGPRClass(RC)
80654c89d8SChristudasan Devadasan              ? (STI->getRegSizeInBits(*RC) == 32 ? AGPR32 : AGPR_TUPLE)
81654c89d8SChristudasan Devadasan              : (STI->getRegSizeInBits(*RC) == 32 ? VGPR32 : VGPR_TUPLE);
82fd4c410fSValery Pykhtin }
83fd4c410fSValery Pykhtin 
inc(unsigned Reg,LaneBitmask PrevMask,LaneBitmask NewMask,const MachineRegisterInfo & MRI)84fd4c410fSValery Pykhtin void GCNRegPressure::inc(unsigned Reg,
85fd4c410fSValery Pykhtin                          LaneBitmask PrevMask,
86fd4c410fSValery Pykhtin                          LaneBitmask NewMask,
87fd4c410fSValery Pykhtin                          const MachineRegisterInfo &MRI) {
88ada205e9SStanislav Mekhanoshin   if (SIRegisterInfo::getNumCoveredRegs(NewMask) ==
89ada205e9SStanislav Mekhanoshin       SIRegisterInfo::getNumCoveredRegs(PrevMask))
90fd4c410fSValery Pykhtin     return;
91fd4c410fSValery Pykhtin 
92fd4c410fSValery Pykhtin   int Sign = 1;
93fd4c410fSValery Pykhtin   if (NewMask < PrevMask) {
94fd4c410fSValery Pykhtin     std::swap(NewMask, PrevMask);
95fd4c410fSValery Pykhtin     Sign = -1;
96fd4c410fSValery Pykhtin   }
97ada205e9SStanislav Mekhanoshin 
98fd4c410fSValery Pykhtin   switch (auto Kind = getRegKind(Reg, MRI)) {
99fd4c410fSValery Pykhtin   case SGPR32:
100fd4c410fSValery Pykhtin   case VGPR32:
101e67cc380SStanislav Mekhanoshin   case AGPR32:
102fd4c410fSValery Pykhtin     Value[Kind] += Sign;
103fd4c410fSValery Pykhtin     break;
104fd4c410fSValery Pykhtin 
105fd4c410fSValery Pykhtin   case SGPR_TUPLE:
106fd4c410fSValery Pykhtin   case VGPR_TUPLE:
107e67cc380SStanislav Mekhanoshin   case AGPR_TUPLE:
108fd4c410fSValery Pykhtin     assert(PrevMask < NewMask);
109fd4c410fSValery Pykhtin 
110e67cc380SStanislav Mekhanoshin     Value[Kind == SGPR_TUPLE ? SGPR32 : Kind == AGPR_TUPLE ? AGPR32 : VGPR32] +=
111cacc3b7aSStanislav Mekhanoshin       Sign * SIRegisterInfo::getNumCoveredRegs(~PrevMask & NewMask);
112fd4c410fSValery Pykhtin 
113fd4c410fSValery Pykhtin     if (PrevMask.none()) {
114fd4c410fSValery Pykhtin       assert(NewMask.any());
115fd4c410fSValery Pykhtin       Value[Kind] += Sign * MRI.getPressureSets(Reg).getWeight();
116fd4c410fSValery Pykhtin     }
117fd4c410fSValery Pykhtin     break;
118fd4c410fSValery Pykhtin 
119fd4c410fSValery Pykhtin   default: llvm_unreachable("Unknown register kind");
120fd4c410fSValery Pykhtin   }
121fd4c410fSValery Pykhtin }
122fd4c410fSValery Pykhtin 
less(const GCNSubtarget & ST,const GCNRegPressure & O,unsigned MaxOccupancy) const1235bfbae5cSTom Stellard bool GCNRegPressure::less(const GCNSubtarget &ST,
124fd4c410fSValery Pykhtin                           const GCNRegPressure& O,
125fd4c410fSValery Pykhtin                           unsigned MaxOccupancy) const {
126fd4c410fSValery Pykhtin   const auto SGPROcc = std::min(MaxOccupancy,
1277e3794d5SStanislav Mekhanoshin                                 ST.getOccupancyWithNumSGPRs(getSGPRNum()));
128a8d9d507SStanislav Mekhanoshin   const auto VGPROcc =
129a8d9d507SStanislav Mekhanoshin     std::min(MaxOccupancy,
130a8d9d507SStanislav Mekhanoshin              ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts())));
131fd4c410fSValery Pykhtin   const auto OtherSGPROcc = std::min(MaxOccupancy,
1327e3794d5SStanislav Mekhanoshin                                 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
133a8d9d507SStanislav Mekhanoshin   const auto OtherVGPROcc =
134a8d9d507SStanislav Mekhanoshin     std::min(MaxOccupancy,
135a8d9d507SStanislav Mekhanoshin              ST.getOccupancyWithNumVGPRs(O.getVGPRNum(ST.hasGFX90AInsts())));
136fd4c410fSValery Pykhtin 
137fd4c410fSValery Pykhtin   const auto Occ = std::min(SGPROcc, VGPROcc);
138fd4c410fSValery Pykhtin   const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
139fd4c410fSValery Pykhtin   if (Occ != OtherOcc)
140fd4c410fSValery Pykhtin     return Occ > OtherOcc;
141fd4c410fSValery Pykhtin 
142fd4c410fSValery Pykhtin   bool SGPRImportant = SGPROcc < VGPROcc;
143fd4c410fSValery Pykhtin   const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
144fd4c410fSValery Pykhtin 
145fd4c410fSValery Pykhtin   // if both pressures disagree on what is more important compare vgprs
146fd4c410fSValery Pykhtin   if (SGPRImportant != OtherSGPRImportant) {
147fd4c410fSValery Pykhtin     SGPRImportant = false;
148fd4c410fSValery Pykhtin   }
149fd4c410fSValery Pykhtin 
150fd4c410fSValery Pykhtin   // compare large regs pressure
151fd4c410fSValery Pykhtin   bool SGPRFirst = SGPRImportant;
152fd4c410fSValery Pykhtin   for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
153fd4c410fSValery Pykhtin     if (SGPRFirst) {
154fd4c410fSValery Pykhtin       auto SW = getSGPRTuplesWeight();
155fd4c410fSValery Pykhtin       auto OtherSW = O.getSGPRTuplesWeight();
156fd4c410fSValery Pykhtin       if (SW != OtherSW)
157fd4c410fSValery Pykhtin         return SW < OtherSW;
158fd4c410fSValery Pykhtin     } else {
159fd4c410fSValery Pykhtin       auto VW = getVGPRTuplesWeight();
160fd4c410fSValery Pykhtin       auto OtherVW = O.getVGPRTuplesWeight();
161fd4c410fSValery Pykhtin       if (VW != OtherVW)
162fd4c410fSValery Pykhtin         return VW < OtherVW;
163fd4c410fSValery Pykhtin     }
164fd4c410fSValery Pykhtin   }
1657e3794d5SStanislav Mekhanoshin   return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
166a8d9d507SStanislav Mekhanoshin                          (getVGPRNum(ST.hasGFX90AInsts()) <
167a8d9d507SStanislav Mekhanoshin                           O.getVGPRNum(ST.hasGFX90AInsts()));
168fd4c410fSValery Pykhtin }
169fd4c410fSValery Pykhtin 
170615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
171fd4c410fSValery Pykhtin LLVM_DUMP_METHOD
print(raw_ostream & OS,const GCNSubtarget * ST) const1725bfbae5cSTom Stellard void GCNRegPressure::print(raw_ostream &OS, const GCNSubtarget *ST) const {
1739aff33bbSStanislav Mekhanoshin   OS << "VGPRs: " << Value[VGPR32] << ' ';
1749aff33bbSStanislav Mekhanoshin   OS << "AGPRs: " << Value[AGPR32];
175a8d9d507SStanislav Mekhanoshin   if (ST) OS << "(O"
176a8d9d507SStanislav Mekhanoshin              << ST->getOccupancyWithNumVGPRs(getVGPRNum(ST->hasGFX90AInsts()))
177a8d9d507SStanislav Mekhanoshin              << ')';
1787e3794d5SStanislav Mekhanoshin   OS << ", SGPRs: " << getSGPRNum();
1797e3794d5SStanislav Mekhanoshin   if (ST) OS << "(O" << ST->getOccupancyWithNumSGPRs(getSGPRNum()) << ')';
180fd4c410fSValery Pykhtin   OS << ", LVGPR WT: " << getVGPRTuplesWeight()
181fd4c410fSValery Pykhtin      << ", LSGPR WT: " << getSGPRTuplesWeight();
182fd4c410fSValery Pykhtin   if (ST) OS << " -> Occ: " << getOccupancy(*ST);
183fd4c410fSValery Pykhtin   OS << '\n';
184fd4c410fSValery Pykhtin }
185fd4c410fSValery Pykhtin #endif
186fd4c410fSValery Pykhtin 
getDefRegMask(const MachineOperand & MO,const MachineRegisterInfo & MRI)18774cb9c88SValery Pykhtin static LaneBitmask getDefRegMask(const MachineOperand &MO,
18874cb9c88SValery Pykhtin                                  const MachineRegisterInfo &MRI) {
18934978602SJay Foad   assert(MO.isDef() && MO.isReg() && MO.getReg().isVirtual());
19074cb9c88SValery Pykhtin 
19174cb9c88SValery Pykhtin   // We don't rely on read-undef flag because in case of tentative schedule
19274cb9c88SValery Pykhtin   // tracking it isn't set correctly yet. This works correctly however since
19374cb9c88SValery Pykhtin   // use mask has been tracked before using LIS.
19474cb9c88SValery Pykhtin   return MO.getSubReg() == 0 ?
19574cb9c88SValery Pykhtin     MRI.getMaxLaneMaskForVReg(MO.getReg()) :
19674cb9c88SValery Pykhtin     MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
19774cb9c88SValery Pykhtin }
19874cb9c88SValery Pykhtin 
getUsedRegMask(const MachineOperand & MO,const MachineRegisterInfo & MRI,const LiveIntervals & LIS)19974cb9c88SValery Pykhtin static LaneBitmask getUsedRegMask(const MachineOperand &MO,
20074cb9c88SValery Pykhtin                                   const MachineRegisterInfo &MRI,
20174cb9c88SValery Pykhtin                                   const LiveIntervals &LIS) {
20234978602SJay Foad   assert(MO.isUse() && MO.isReg() && MO.getReg().isVirtual());
20374cb9c88SValery Pykhtin 
20474cb9c88SValery Pykhtin   if (auto SubReg = MO.getSubReg())
20574cb9c88SValery Pykhtin     return MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(SubReg);
20674cb9c88SValery Pykhtin 
20774cb9c88SValery Pykhtin   auto MaxMask = MRI.getMaxLaneMaskForVReg(MO.getReg());
208cacc3b7aSStanislav Mekhanoshin   if (SIRegisterInfo::getNumCoveredRegs(MaxMask) > 1) // cannot have subregs
20974cb9c88SValery Pykhtin     return MaxMask;
21074cb9c88SValery Pykhtin 
21174cb9c88SValery Pykhtin   // For a tentative schedule LIS isn't updated yet but livemask should remain
21274cb9c88SValery Pykhtin   // the same on any schedule. Subreg defs can be reordered but they all must
21374cb9c88SValery Pykhtin   // dominate uses anyway.
21474cb9c88SValery Pykhtin   auto SI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex();
21574cb9c88SValery Pykhtin   return getLiveLaneMask(MO.getReg(), SI, LIS, MRI);
21674cb9c88SValery Pykhtin }
21774cb9c88SValery Pykhtin 
218debb3c35SBenjamin Kramer static SmallVector<RegisterMaskPair, 8>
collectVirtualRegUses(const MachineInstr & MI,const LiveIntervals & LIS,const MachineRegisterInfo & MRI)219debb3c35SBenjamin Kramer collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS,
22074cb9c88SValery Pykhtin                       const MachineRegisterInfo &MRI) {
22174cb9c88SValery Pykhtin   SmallVector<RegisterMaskPair, 8> Res;
22274cb9c88SValery Pykhtin   for (const auto &MO : MI.operands()) {
22334978602SJay Foad     if (!MO.isReg() || !MO.getReg().isVirtual())
22474cb9c88SValery Pykhtin       continue;
22574cb9c88SValery Pykhtin     if (!MO.isUse() || !MO.readsReg())
22674cb9c88SValery Pykhtin       continue;
22774cb9c88SValery Pykhtin 
22874cb9c88SValery Pykhtin     auto const UsedMask = getUsedRegMask(MO, MRI, LIS);
22974cb9c88SValery Pykhtin 
23074cb9c88SValery Pykhtin     auto Reg = MO.getReg();
231b934160aSKazu Hirata     auto I = llvm::find_if(
232b934160aSKazu Hirata         Res, [Reg](const RegisterMaskPair &RM) { return RM.RegUnit == Reg; });
23374cb9c88SValery Pykhtin     if (I != Res.end())
23474cb9c88SValery Pykhtin       I->LaneMask |= UsedMask;
23574cb9c88SValery Pykhtin     else
23674cb9c88SValery Pykhtin       Res.push_back(RegisterMaskPair(Reg, UsedMask));
23774cb9c88SValery Pykhtin   }
23874cb9c88SValery Pykhtin   return Res;
23974cb9c88SValery Pykhtin }
24074cb9c88SValery Pykhtin 
241fd4c410fSValery Pykhtin ///////////////////////////////////////////////////////////////////////////////
242fd4c410fSValery Pykhtin // GCNRPTracker
243fd4c410fSValery Pykhtin 
getLiveLaneMask(unsigned Reg,SlotIndex SI,const LiveIntervals & LIS,const MachineRegisterInfo & MRI)244fd4c410fSValery Pykhtin LaneBitmask llvm::getLiveLaneMask(unsigned Reg,
245fd4c410fSValery Pykhtin                                   SlotIndex SI,
246fd4c410fSValery Pykhtin                                   const LiveIntervals &LIS,
247fd4c410fSValery Pykhtin                                   const MachineRegisterInfo &MRI) {
248fd4c410fSValery Pykhtin   LaneBitmask LiveMask;
249fd4c410fSValery Pykhtin   const auto &LI = LIS.getInterval(Reg);
250fd4c410fSValery Pykhtin   if (LI.hasSubRanges()) {
251fd4c410fSValery Pykhtin     for (const auto &S : LI.subranges())
252fd4c410fSValery Pykhtin       if (S.liveAt(SI)) {
253fd4c410fSValery Pykhtin         LiveMask |= S.LaneMask;
254fd4c410fSValery Pykhtin         assert(LiveMask < MRI.getMaxLaneMaskForVReg(Reg) ||
255fd4c410fSValery Pykhtin                LiveMask == MRI.getMaxLaneMaskForVReg(Reg));
256fd4c410fSValery Pykhtin       }
257fd4c410fSValery Pykhtin   } else if (LI.liveAt(SI)) {
258fd4c410fSValery Pykhtin     LiveMask = MRI.getMaxLaneMaskForVReg(Reg);
259fd4c410fSValery Pykhtin   }
260fd4c410fSValery Pykhtin   return LiveMask;
261fd4c410fSValery Pykhtin }
262fd4c410fSValery Pykhtin 
getLiveRegs(SlotIndex SI,const LiveIntervals & LIS,const MachineRegisterInfo & MRI)263fd4c410fSValery Pykhtin GCNRPTracker::LiveRegSet llvm::getLiveRegs(SlotIndex SI,
264fd4c410fSValery Pykhtin                                            const LiveIntervals &LIS,
265fd4c410fSValery Pykhtin                                            const MachineRegisterInfo &MRI) {
266fd4c410fSValery Pykhtin   GCNRPTracker::LiveRegSet LiveRegs;
267fd4c410fSValery Pykhtin   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
2682bea69bfSDaniel Sanders     auto Reg = Register::index2VirtReg(I);
269464cecf8SStanislav Mekhanoshin     if (!LIS.hasInterval(Reg))
270fd4c410fSValery Pykhtin       continue;
271fd4c410fSValery Pykhtin     auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
272fd4c410fSValery Pykhtin     if (LiveMask.any())
273fd4c410fSValery Pykhtin       LiveRegs[Reg] = LiveMask;
274fd4c410fSValery Pykhtin   }
275fd4c410fSValery Pykhtin   return LiveRegs;
276fd4c410fSValery Pykhtin }
277fd4c410fSValery Pykhtin 
reset(const MachineInstr & MI,const LiveRegSet * LiveRegsCopy,bool After)27828624f94SStanislav Mekhanoshin void GCNRPTracker::reset(const MachineInstr &MI,
27928624f94SStanislav Mekhanoshin                          const LiveRegSet *LiveRegsCopy,
28028624f94SStanislav Mekhanoshin                          bool After) {
28128624f94SStanislav Mekhanoshin   const MachineFunction &MF = *MI.getMF();
28228624f94SStanislav Mekhanoshin   MRI = &MF.getRegInfo();
283464cecf8SStanislav Mekhanoshin   if (LiveRegsCopy) {
284464cecf8SStanislav Mekhanoshin     if (&LiveRegs != LiveRegsCopy)
285464cecf8SStanislav Mekhanoshin       LiveRegs = *LiveRegsCopy;
286464cecf8SStanislav Mekhanoshin   } else {
28728624f94SStanislav Mekhanoshin     LiveRegs = After ? getLiveRegsAfter(MI, LIS)
28828624f94SStanislav Mekhanoshin                      : getLiveRegsBefore(MI, LIS);
289464cecf8SStanislav Mekhanoshin   }
29028624f94SStanislav Mekhanoshin 
291464cecf8SStanislav Mekhanoshin   MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs);
292464cecf8SStanislav Mekhanoshin }
293464cecf8SStanislav Mekhanoshin 
reset(const MachineInstr & MI,const LiveRegSet * LiveRegsCopy)29428624f94SStanislav Mekhanoshin void GCNUpwardRPTracker::reset(const MachineInstr &MI,
29528624f94SStanislav Mekhanoshin                                const LiveRegSet *LiveRegsCopy) {
29628624f94SStanislav Mekhanoshin   GCNRPTracker::reset(MI, LiveRegsCopy, true);
29728624f94SStanislav Mekhanoshin }
29828624f94SStanislav Mekhanoshin 
recede(const MachineInstr & MI)299fd4c410fSValery Pykhtin void GCNUpwardRPTracker::recede(const MachineInstr &MI) {
300fd4c410fSValery Pykhtin   assert(MRI && "call reset first");
301fd4c410fSValery Pykhtin 
302fd4c410fSValery Pykhtin   LastTrackedMI = &MI;
303fd4c410fSValery Pykhtin 
304801bf7ebSShiva Chen   if (MI.isDebugInstr())
305fd4c410fSValery Pykhtin     return;
306fd4c410fSValery Pykhtin 
30774cb9c88SValery Pykhtin   auto const RegUses = collectVirtualRegUses(MI, LIS, *MRI);
30874cb9c88SValery Pykhtin 
30974cb9c88SValery Pykhtin   // calc pressure at the MI (defs + uses)
31074cb9c88SValery Pykhtin   auto AtMIPressure = CurPressure;
31174cb9c88SValery Pykhtin   for (const auto &U : RegUses) {
31274cb9c88SValery Pykhtin     auto LiveMask = LiveRegs[U.RegUnit];
31374cb9c88SValery Pykhtin     AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *MRI);
31474cb9c88SValery Pykhtin   }
31574cb9c88SValery Pykhtin   // update max pressure
31674cb9c88SValery Pykhtin   MaxPressure = max(AtMIPressure, MaxPressure);
31774cb9c88SValery Pykhtin 
3184332f1a4Svpykhtin   for (const auto &MO : MI.operands()) {
31934978602SJay Foad     if (!MO.isReg() || !MO.isDef() || !MO.getReg().isVirtual() || MO.isDead())
320fd4c410fSValery Pykhtin       continue;
321fd4c410fSValery Pykhtin 
322fd4c410fSValery Pykhtin     auto Reg = MO.getReg();
32374cb9c88SValery Pykhtin     auto I = LiveRegs.find(Reg);
32474cb9c88SValery Pykhtin     if (I == LiveRegs.end())
325fd4c410fSValery Pykhtin       continue;
32674cb9c88SValery Pykhtin     auto &LiveMask = I->second;
327fd4c410fSValery Pykhtin     auto PrevMask = LiveMask;
32874cb9c88SValery Pykhtin     LiveMask &= ~getDefRegMask(MO, *MRI);
329fd4c410fSValery Pykhtin     CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
33074cb9c88SValery Pykhtin     if (LiveMask.none())
33174cb9c88SValery Pykhtin       LiveRegs.erase(I);
332fd4c410fSValery Pykhtin   }
33374cb9c88SValery Pykhtin   for (const auto &U : RegUses) {
33474cb9c88SValery Pykhtin     auto &LiveMask = LiveRegs[U.RegUnit];
33574cb9c88SValery Pykhtin     auto PrevMask = LiveMask;
33674cb9c88SValery Pykhtin     LiveMask |= U.LaneMask;
33774cb9c88SValery Pykhtin     CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
33874cb9c88SValery Pykhtin   }
33974cb9c88SValery Pykhtin   assert(CurPressure == getRegPressure(*MRI, LiveRegs));
340fd4c410fSValery Pykhtin }
341fd4c410fSValery Pykhtin 
reset(const MachineInstr & MI,const LiveRegSet * LiveRegsCopy)342464cecf8SStanislav Mekhanoshin bool GCNDownwardRPTracker::reset(const MachineInstr &MI,
343464cecf8SStanislav Mekhanoshin                                  const LiveRegSet *LiveRegsCopy) {
344464cecf8SStanislav Mekhanoshin   MRI = &MI.getParent()->getParent()->getRegInfo();
345464cecf8SStanislav Mekhanoshin   LastTrackedMI = nullptr;
346464cecf8SStanislav Mekhanoshin   MBBEnd = MI.getParent()->end();
347464cecf8SStanislav Mekhanoshin   NextMI = &MI;
348464cecf8SStanislav Mekhanoshin   NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
349464cecf8SStanislav Mekhanoshin   if (NextMI == MBBEnd)
350464cecf8SStanislav Mekhanoshin     return false;
35128624f94SStanislav Mekhanoshin   GCNRPTracker::reset(*NextMI, LiveRegsCopy, false);
352464cecf8SStanislav Mekhanoshin   return true;
353464cecf8SStanislav Mekhanoshin }
354464cecf8SStanislav Mekhanoshin 
advanceBeforeNext()355464cecf8SStanislav Mekhanoshin bool GCNDownwardRPTracker::advanceBeforeNext() {
356464cecf8SStanislav Mekhanoshin   assert(MRI && "call reset first");
357464cecf8SStanislav Mekhanoshin 
358464cecf8SStanislav Mekhanoshin   NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
359464cecf8SStanislav Mekhanoshin   if (NextMI == MBBEnd)
360464cecf8SStanislav Mekhanoshin     return false;
361464cecf8SStanislav Mekhanoshin 
362464cecf8SStanislav Mekhanoshin   SlotIndex SI = LIS.getInstructionIndex(*NextMI).getBaseIndex();
363464cecf8SStanislav Mekhanoshin   assert(SI.isValid());
364464cecf8SStanislav Mekhanoshin 
365464cecf8SStanislav Mekhanoshin   // Remove dead registers or mask bits.
366464cecf8SStanislav Mekhanoshin   for (auto &It : LiveRegs) {
367464cecf8SStanislav Mekhanoshin     const LiveInterval &LI = LIS.getInterval(It.first);
368464cecf8SStanislav Mekhanoshin     if (LI.hasSubRanges()) {
369464cecf8SStanislav Mekhanoshin       for (const auto &S : LI.subranges()) {
370464cecf8SStanislav Mekhanoshin         if (!S.liveAt(SI)) {
371464cecf8SStanislav Mekhanoshin           auto PrevMask = It.second;
372464cecf8SStanislav Mekhanoshin           It.second &= ~S.LaneMask;
373464cecf8SStanislav Mekhanoshin           CurPressure.inc(It.first, PrevMask, It.second, *MRI);
374464cecf8SStanislav Mekhanoshin         }
375464cecf8SStanislav Mekhanoshin       }
376464cecf8SStanislav Mekhanoshin     } else if (!LI.liveAt(SI)) {
377464cecf8SStanislav Mekhanoshin       auto PrevMask = It.second;
378464cecf8SStanislav Mekhanoshin       It.second = LaneBitmask::getNone();
379464cecf8SStanislav Mekhanoshin       CurPressure.inc(It.first, PrevMask, It.second, *MRI);
380464cecf8SStanislav Mekhanoshin     }
381464cecf8SStanislav Mekhanoshin     if (It.second.none())
382464cecf8SStanislav Mekhanoshin       LiveRegs.erase(It.first);
383464cecf8SStanislav Mekhanoshin   }
384464cecf8SStanislav Mekhanoshin 
385464cecf8SStanislav Mekhanoshin   MaxPressure = max(MaxPressure, CurPressure);
386464cecf8SStanislav Mekhanoshin 
387464cecf8SStanislav Mekhanoshin   return true;
388464cecf8SStanislav Mekhanoshin }
389464cecf8SStanislav Mekhanoshin 
advanceToNext()390464cecf8SStanislav Mekhanoshin void GCNDownwardRPTracker::advanceToNext() {
391464cecf8SStanislav Mekhanoshin   LastTrackedMI = &*NextMI++;
39241877b82SMatt Arsenault   NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
393464cecf8SStanislav Mekhanoshin 
394464cecf8SStanislav Mekhanoshin   // Add new registers or mask bits.
3954332f1a4Svpykhtin   for (const auto &MO : LastTrackedMI->operands()) {
3964332f1a4Svpykhtin     if (!MO.isReg() || !MO.isDef())
397464cecf8SStanislav Mekhanoshin       continue;
3980c476111SDaniel Sanders     Register Reg = MO.getReg();
39934978602SJay Foad     if (!Reg.isVirtual())
400464cecf8SStanislav Mekhanoshin       continue;
401464cecf8SStanislav Mekhanoshin     auto &LiveMask = LiveRegs[Reg];
402464cecf8SStanislav Mekhanoshin     auto PrevMask = LiveMask;
40374cb9c88SValery Pykhtin     LiveMask |= getDefRegMask(MO, *MRI);
404464cecf8SStanislav Mekhanoshin     CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
405464cecf8SStanislav Mekhanoshin   }
406464cecf8SStanislav Mekhanoshin 
407464cecf8SStanislav Mekhanoshin   MaxPressure = max(MaxPressure, CurPressure);
408464cecf8SStanislav Mekhanoshin }
409464cecf8SStanislav Mekhanoshin 
advance()410464cecf8SStanislav Mekhanoshin bool GCNDownwardRPTracker::advance() {
411464cecf8SStanislav Mekhanoshin   // If we have just called reset live set is actual.
412464cecf8SStanislav Mekhanoshin   if ((NextMI == MBBEnd) || (LastTrackedMI && !advanceBeforeNext()))
413464cecf8SStanislav Mekhanoshin     return false;
414464cecf8SStanislav Mekhanoshin   advanceToNext();
415464cecf8SStanislav Mekhanoshin   return true;
416464cecf8SStanislav Mekhanoshin }
417464cecf8SStanislav Mekhanoshin 
advance(MachineBasicBlock::const_iterator End)418464cecf8SStanislav Mekhanoshin bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator End) {
419464cecf8SStanislav Mekhanoshin   while (NextMI != End)
420464cecf8SStanislav Mekhanoshin     if (!advance()) return false;
421464cecf8SStanislav Mekhanoshin   return true;
422464cecf8SStanislav Mekhanoshin }
423464cecf8SStanislav Mekhanoshin 
advance(MachineBasicBlock::const_iterator Begin,MachineBasicBlock::const_iterator End,const LiveRegSet * LiveRegsCopy)424464cecf8SStanislav Mekhanoshin bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator Begin,
425464cecf8SStanislav Mekhanoshin                                    MachineBasicBlock::const_iterator End,
426464cecf8SStanislav Mekhanoshin                                    const LiveRegSet *LiveRegsCopy) {
427464cecf8SStanislav Mekhanoshin   reset(*Begin, LiveRegsCopy);
428464cecf8SStanislav Mekhanoshin   return advance(End);
429464cecf8SStanislav Mekhanoshin }
430464cecf8SStanislav Mekhanoshin 
431615eb470SAaron Ballman #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
432fd4c410fSValery Pykhtin LLVM_DUMP_METHOD
reportMismatch(const GCNRPTracker::LiveRegSet & LISLR,const GCNRPTracker::LiveRegSet & TrackedLR,const TargetRegisterInfo * TRI)433fd4c410fSValery Pykhtin static void reportMismatch(const GCNRPTracker::LiveRegSet &LISLR,
434fd4c410fSValery Pykhtin                            const GCNRPTracker::LiveRegSet &TrackedLR,
435fd4c410fSValery Pykhtin                            const TargetRegisterInfo *TRI) {
436fd4c410fSValery Pykhtin   for (auto const &P : TrackedLR) {
437fd4c410fSValery Pykhtin     auto I = LISLR.find(P.first);
438fd4c410fSValery Pykhtin     if (I == LISLR.end()) {
4399d419d3bSFrancis Visoiu Mistrih       dbgs() << "  " << printReg(P.first, TRI)
440fd4c410fSValery Pykhtin              << ":L" << PrintLaneMask(P.second)
441fd4c410fSValery Pykhtin              << " isn't found in LIS reported set\n";
442fd4c410fSValery Pykhtin     }
443fd4c410fSValery Pykhtin     else if (I->second != P.second) {
4449d419d3bSFrancis Visoiu Mistrih       dbgs() << "  " << printReg(P.first, TRI)
445fd4c410fSValery Pykhtin         << " masks doesn't match: LIS reported "
446fd4c410fSValery Pykhtin         << PrintLaneMask(I->second)
447fd4c410fSValery Pykhtin         << ", tracked "
448fd4c410fSValery Pykhtin         << PrintLaneMask(P.second)
449fd4c410fSValery Pykhtin         << '\n';
450fd4c410fSValery Pykhtin     }
451fd4c410fSValery Pykhtin   }
452fd4c410fSValery Pykhtin   for (auto const &P : LISLR) {
453fd4c410fSValery Pykhtin     auto I = TrackedLR.find(P.first);
454fd4c410fSValery Pykhtin     if (I == TrackedLR.end()) {
4559d419d3bSFrancis Visoiu Mistrih       dbgs() << "  " << printReg(P.first, TRI)
456fd4c410fSValery Pykhtin              << ":L" << PrintLaneMask(P.second)
457fd4c410fSValery Pykhtin              << " isn't found in tracked set\n";
458fd4c410fSValery Pykhtin     }
459fd4c410fSValery Pykhtin   }
460fd4c410fSValery Pykhtin }
461fd4c410fSValery Pykhtin 
isValid() const462fd4c410fSValery Pykhtin bool GCNUpwardRPTracker::isValid() const {
463fd4c410fSValery Pykhtin   const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
464fd4c410fSValery Pykhtin   const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
46574cb9c88SValery Pykhtin   const auto &TrackedLR = LiveRegs;
466fd4c410fSValery Pykhtin 
467fd4c410fSValery Pykhtin   if (!isEqual(LISLR, TrackedLR)) {
468fd4c410fSValery Pykhtin     dbgs() << "\nGCNUpwardRPTracker error: Tracked and"
469fd4c410fSValery Pykhtin               " LIS reported livesets mismatch:\n";
470fd4c410fSValery Pykhtin     printLivesAt(SI, LIS, *MRI);
471fd4c410fSValery Pykhtin     reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo());
472fd4c410fSValery Pykhtin     return false;
473fd4c410fSValery Pykhtin   }
474fd4c410fSValery Pykhtin 
475fd4c410fSValery Pykhtin   auto LISPressure = getRegPressure(*MRI, LISLR);
476fd4c410fSValery Pykhtin   if (LISPressure != CurPressure) {
477fd4c410fSValery Pykhtin     dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: ";
478fd4c410fSValery Pykhtin     CurPressure.print(dbgs());
479fd4c410fSValery Pykhtin     dbgs() << "LIS rpt: ";
480fd4c410fSValery Pykhtin     LISPressure.print(dbgs());
481fd4c410fSValery Pykhtin     return false;
482fd4c410fSValery Pykhtin   }
483fd4c410fSValery Pykhtin   return true;
484fd4c410fSValery Pykhtin }
485fd4c410fSValery Pykhtin 
printLiveRegs(raw_ostream & OS,const LiveRegSet & LiveRegs,const MachineRegisterInfo & MRI)486acca0f5cSStanislav Mekhanoshin void GCNRPTracker::printLiveRegs(raw_ostream &OS, const LiveRegSet& LiveRegs,
487acca0f5cSStanislav Mekhanoshin                                  const MachineRegisterInfo &MRI) {
488acca0f5cSStanislav Mekhanoshin   const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
489acca0f5cSStanislav Mekhanoshin   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
490*d6b07348SJim Lin     Register Reg = Register::index2VirtReg(I);
491acca0f5cSStanislav Mekhanoshin     auto It = LiveRegs.find(Reg);
492acca0f5cSStanislav Mekhanoshin     if (It != LiveRegs.end() && It->second.any())
4939d419d3bSFrancis Visoiu Mistrih       OS << ' ' << printVRegOrUnit(Reg, TRI) << ':'
494acca0f5cSStanislav Mekhanoshin          << PrintLaneMask(It->second);
495acca0f5cSStanislav Mekhanoshin   }
496acca0f5cSStanislav Mekhanoshin   OS << '\n';
497acca0f5cSStanislav Mekhanoshin }
498fd4c410fSValery Pykhtin #endif
499