109467b48Spatrick //===- GCNRegPressure.cpp -------------------------------------------------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
8097a140dSpatrick ///
9097a140dSpatrick /// \file
10097a140dSpatrick /// This file implements the GCNRegPressure class.
11097a140dSpatrick ///
12097a140dSpatrick //===----------------------------------------------------------------------===//
1309467b48Spatrick
1409467b48Spatrick #include "GCNRegPressure.h"
1509467b48Spatrick #include "llvm/CodeGen/RegisterPressure.h"
1609467b48Spatrick
1709467b48Spatrick using namespace llvm;
1809467b48Spatrick
1909467b48Spatrick #define DEBUG_TYPE "machine-scheduler"
2009467b48Spatrick
isEqual(const GCNRPTracker::LiveRegSet & S1,const GCNRPTracker::LiveRegSet & S2)2109467b48Spatrick bool llvm::isEqual(const GCNRPTracker::LiveRegSet &S1,
2209467b48Spatrick const GCNRPTracker::LiveRegSet &S2) {
2309467b48Spatrick if (S1.size() != S2.size())
2409467b48Spatrick return false;
2509467b48Spatrick
2609467b48Spatrick for (const auto &P : S1) {
2709467b48Spatrick auto I = S2.find(P.first);
2809467b48Spatrick if (I == S2.end() || I->second != P.second)
2909467b48Spatrick return false;
3009467b48Spatrick }
3109467b48Spatrick return true;
3209467b48Spatrick }
3309467b48Spatrick
3409467b48Spatrick
3509467b48Spatrick ///////////////////////////////////////////////////////////////////////////////
3609467b48Spatrick // GCNRegPressure
3709467b48Spatrick
getRegKind(Register Reg,const MachineRegisterInfo & MRI)3873471bf0Spatrick unsigned GCNRegPressure::getRegKind(Register Reg,
3909467b48Spatrick const MachineRegisterInfo &MRI) {
4073471bf0Spatrick assert(Reg.isVirtual());
4109467b48Spatrick const auto RC = MRI.getRegClass(Reg);
4209467b48Spatrick auto STI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo());
43*d415bd75Srobert return STI->isSGPRClass(RC)
44*d415bd75Srobert ? (STI->getRegSizeInBits(*RC) == 32 ? SGPR32 : SGPR_TUPLE)
45*d415bd75Srobert : STI->isAGPRClass(RC)
46*d415bd75Srobert ? (STI->getRegSizeInBits(*RC) == 32 ? AGPR32 : AGPR_TUPLE)
47*d415bd75Srobert : (STI->getRegSizeInBits(*RC) == 32 ? VGPR32 : VGPR_TUPLE);
4809467b48Spatrick }
4909467b48Spatrick
inc(unsigned Reg,LaneBitmask PrevMask,LaneBitmask NewMask,const MachineRegisterInfo & MRI)5009467b48Spatrick void GCNRegPressure::inc(unsigned Reg,
5109467b48Spatrick LaneBitmask PrevMask,
5209467b48Spatrick LaneBitmask NewMask,
5309467b48Spatrick const MachineRegisterInfo &MRI) {
54097a140dSpatrick if (SIRegisterInfo::getNumCoveredRegs(NewMask) ==
55097a140dSpatrick SIRegisterInfo::getNumCoveredRegs(PrevMask))
5609467b48Spatrick return;
5709467b48Spatrick
5809467b48Spatrick int Sign = 1;
5909467b48Spatrick if (NewMask < PrevMask) {
6009467b48Spatrick std::swap(NewMask, PrevMask);
6109467b48Spatrick Sign = -1;
6209467b48Spatrick }
63097a140dSpatrick
6409467b48Spatrick switch (auto Kind = getRegKind(Reg, MRI)) {
6509467b48Spatrick case SGPR32:
6609467b48Spatrick case VGPR32:
6709467b48Spatrick case AGPR32:
6809467b48Spatrick Value[Kind] += Sign;
6909467b48Spatrick break;
7009467b48Spatrick
7109467b48Spatrick case SGPR_TUPLE:
7209467b48Spatrick case VGPR_TUPLE:
7309467b48Spatrick case AGPR_TUPLE:
7409467b48Spatrick assert(PrevMask < NewMask);
7509467b48Spatrick
7609467b48Spatrick Value[Kind == SGPR_TUPLE ? SGPR32 : Kind == AGPR_TUPLE ? AGPR32 : VGPR32] +=
77097a140dSpatrick Sign * SIRegisterInfo::getNumCoveredRegs(~PrevMask & NewMask);
7809467b48Spatrick
7909467b48Spatrick if (PrevMask.none()) {
8009467b48Spatrick assert(NewMask.any());
8109467b48Spatrick Value[Kind] += Sign * MRI.getPressureSets(Reg).getWeight();
8209467b48Spatrick }
8309467b48Spatrick break;
8409467b48Spatrick
8509467b48Spatrick default: llvm_unreachable("Unknown register kind");
8609467b48Spatrick }
8709467b48Spatrick }
8809467b48Spatrick
less(const GCNSubtarget & ST,const GCNRegPressure & O,unsigned MaxOccupancy) const8909467b48Spatrick bool GCNRegPressure::less(const GCNSubtarget &ST,
9009467b48Spatrick const GCNRegPressure& O,
9109467b48Spatrick unsigned MaxOccupancy) const {
9209467b48Spatrick const auto SGPROcc = std::min(MaxOccupancy,
9309467b48Spatrick ST.getOccupancyWithNumSGPRs(getSGPRNum()));
9473471bf0Spatrick const auto VGPROcc =
9573471bf0Spatrick std::min(MaxOccupancy,
9673471bf0Spatrick ST.getOccupancyWithNumVGPRs(getVGPRNum(ST.hasGFX90AInsts())));
9709467b48Spatrick const auto OtherSGPROcc = std::min(MaxOccupancy,
9809467b48Spatrick ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
9973471bf0Spatrick const auto OtherVGPROcc =
10073471bf0Spatrick std::min(MaxOccupancy,
10173471bf0Spatrick ST.getOccupancyWithNumVGPRs(O.getVGPRNum(ST.hasGFX90AInsts())));
10209467b48Spatrick
10309467b48Spatrick const auto Occ = std::min(SGPROcc, VGPROcc);
10409467b48Spatrick const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
10509467b48Spatrick if (Occ != OtherOcc)
10609467b48Spatrick return Occ > OtherOcc;
10709467b48Spatrick
10809467b48Spatrick bool SGPRImportant = SGPROcc < VGPROcc;
10909467b48Spatrick const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
11009467b48Spatrick
11109467b48Spatrick // if both pressures disagree on what is more important compare vgprs
11209467b48Spatrick if (SGPRImportant != OtherSGPRImportant) {
11309467b48Spatrick SGPRImportant = false;
11409467b48Spatrick }
11509467b48Spatrick
11609467b48Spatrick // compare large regs pressure
11709467b48Spatrick bool SGPRFirst = SGPRImportant;
11809467b48Spatrick for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
11909467b48Spatrick if (SGPRFirst) {
12009467b48Spatrick auto SW = getSGPRTuplesWeight();
12109467b48Spatrick auto OtherSW = O.getSGPRTuplesWeight();
12209467b48Spatrick if (SW != OtherSW)
12309467b48Spatrick return SW < OtherSW;
12409467b48Spatrick } else {
12509467b48Spatrick auto VW = getVGPRTuplesWeight();
12609467b48Spatrick auto OtherVW = O.getVGPRTuplesWeight();
12709467b48Spatrick if (VW != OtherVW)
12809467b48Spatrick return VW < OtherVW;
12909467b48Spatrick }
13009467b48Spatrick }
13109467b48Spatrick return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
13273471bf0Spatrick (getVGPRNum(ST.hasGFX90AInsts()) <
13373471bf0Spatrick O.getVGPRNum(ST.hasGFX90AInsts()));
13409467b48Spatrick }
13509467b48Spatrick
13609467b48Spatrick #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
13709467b48Spatrick LLVM_DUMP_METHOD
print(const GCNRegPressure & RP,const GCNSubtarget * ST)138*d415bd75Srobert Printable llvm::print(const GCNRegPressure &RP, const GCNSubtarget *ST) {
139*d415bd75Srobert return Printable([&RP, ST](raw_ostream &OS) {
140*d415bd75Srobert OS << "VGPRs: " << RP.Value[GCNRegPressure::VGPR32] << ' '
141*d415bd75Srobert << "AGPRs: " << RP.getAGPRNum();
142*d415bd75Srobert if (ST)
143*d415bd75Srobert OS << "(O"
144*d415bd75Srobert << ST->getOccupancyWithNumVGPRs(RP.getVGPRNum(ST->hasGFX90AInsts()))
14573471bf0Spatrick << ')';
146*d415bd75Srobert OS << ", SGPRs: " << RP.getSGPRNum();
147*d415bd75Srobert if (ST)
148*d415bd75Srobert OS << "(O" << ST->getOccupancyWithNumSGPRs(RP.getSGPRNum()) << ')';
149*d415bd75Srobert OS << ", LVGPR WT: " << RP.getVGPRTuplesWeight()
150*d415bd75Srobert << ", LSGPR WT: " << RP.getSGPRTuplesWeight();
151*d415bd75Srobert if (ST)
152*d415bd75Srobert OS << " -> Occ: " << RP.getOccupancy(*ST);
15309467b48Spatrick OS << '\n';
154*d415bd75Srobert });
15509467b48Spatrick }
15609467b48Spatrick #endif
15709467b48Spatrick
getDefRegMask(const MachineOperand & MO,const MachineRegisterInfo & MRI)15809467b48Spatrick static LaneBitmask getDefRegMask(const MachineOperand &MO,
15909467b48Spatrick const MachineRegisterInfo &MRI) {
16073471bf0Spatrick assert(MO.isDef() && MO.isReg() && MO.getReg().isVirtual());
16109467b48Spatrick
16209467b48Spatrick // We don't rely on read-undef flag because in case of tentative schedule
16309467b48Spatrick // tracking it isn't set correctly yet. This works correctly however since
16409467b48Spatrick // use mask has been tracked before using LIS.
16509467b48Spatrick return MO.getSubReg() == 0 ?
16609467b48Spatrick MRI.getMaxLaneMaskForVReg(MO.getReg()) :
16709467b48Spatrick MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
16809467b48Spatrick }
16909467b48Spatrick
getUsedRegMask(const MachineOperand & MO,const MachineRegisterInfo & MRI,const LiveIntervals & LIS)17009467b48Spatrick static LaneBitmask getUsedRegMask(const MachineOperand &MO,
17109467b48Spatrick const MachineRegisterInfo &MRI,
17209467b48Spatrick const LiveIntervals &LIS) {
17373471bf0Spatrick assert(MO.isUse() && MO.isReg() && MO.getReg().isVirtual());
17409467b48Spatrick
17509467b48Spatrick if (auto SubReg = MO.getSubReg())
17609467b48Spatrick return MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(SubReg);
17709467b48Spatrick
17809467b48Spatrick auto MaxMask = MRI.getMaxLaneMaskForVReg(MO.getReg());
179097a140dSpatrick if (SIRegisterInfo::getNumCoveredRegs(MaxMask) > 1) // cannot have subregs
18009467b48Spatrick return MaxMask;
18109467b48Spatrick
18209467b48Spatrick // For a tentative schedule LIS isn't updated yet but livemask should remain
18309467b48Spatrick // the same on any schedule. Subreg defs can be reordered but they all must
18409467b48Spatrick // dominate uses anyway.
18509467b48Spatrick auto SI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex();
18609467b48Spatrick return getLiveLaneMask(MO.getReg(), SI, LIS, MRI);
18709467b48Spatrick }
18809467b48Spatrick
18909467b48Spatrick static SmallVector<RegisterMaskPair, 8>
collectVirtualRegUses(const MachineInstr & MI,const LiveIntervals & LIS,const MachineRegisterInfo & MRI)19009467b48Spatrick collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS,
19109467b48Spatrick const MachineRegisterInfo &MRI) {
19209467b48Spatrick SmallVector<RegisterMaskPair, 8> Res;
19309467b48Spatrick for (const auto &MO : MI.operands()) {
19473471bf0Spatrick if (!MO.isReg() || !MO.getReg().isVirtual())
19509467b48Spatrick continue;
19609467b48Spatrick if (!MO.isUse() || !MO.readsReg())
19709467b48Spatrick continue;
19809467b48Spatrick
19909467b48Spatrick auto const UsedMask = getUsedRegMask(MO, MRI, LIS);
20009467b48Spatrick
20109467b48Spatrick auto Reg = MO.getReg();
20273471bf0Spatrick auto I = llvm::find_if(
20373471bf0Spatrick Res, [Reg](const RegisterMaskPair &RM) { return RM.RegUnit == Reg; });
20409467b48Spatrick if (I != Res.end())
20509467b48Spatrick I->LaneMask |= UsedMask;
20609467b48Spatrick else
20709467b48Spatrick Res.push_back(RegisterMaskPair(Reg, UsedMask));
20809467b48Spatrick }
20909467b48Spatrick return Res;
21009467b48Spatrick }
21109467b48Spatrick
21209467b48Spatrick ///////////////////////////////////////////////////////////////////////////////
21309467b48Spatrick // GCNRPTracker
21409467b48Spatrick
getLiveLaneMask(unsigned Reg,SlotIndex SI,const LiveIntervals & LIS,const MachineRegisterInfo & MRI)21509467b48Spatrick LaneBitmask llvm::getLiveLaneMask(unsigned Reg,
21609467b48Spatrick SlotIndex SI,
21709467b48Spatrick const LiveIntervals &LIS,
21809467b48Spatrick const MachineRegisterInfo &MRI) {
21909467b48Spatrick LaneBitmask LiveMask;
22009467b48Spatrick const auto &LI = LIS.getInterval(Reg);
22109467b48Spatrick if (LI.hasSubRanges()) {
22209467b48Spatrick for (const auto &S : LI.subranges())
22309467b48Spatrick if (S.liveAt(SI)) {
22409467b48Spatrick LiveMask |= S.LaneMask;
22509467b48Spatrick assert(LiveMask < MRI.getMaxLaneMaskForVReg(Reg) ||
22609467b48Spatrick LiveMask == MRI.getMaxLaneMaskForVReg(Reg));
22709467b48Spatrick }
22809467b48Spatrick } else if (LI.liveAt(SI)) {
22909467b48Spatrick LiveMask = MRI.getMaxLaneMaskForVReg(Reg);
23009467b48Spatrick }
23109467b48Spatrick return LiveMask;
23209467b48Spatrick }
23309467b48Spatrick
getLiveRegs(SlotIndex SI,const LiveIntervals & LIS,const MachineRegisterInfo & MRI)23409467b48Spatrick GCNRPTracker::LiveRegSet llvm::getLiveRegs(SlotIndex SI,
23509467b48Spatrick const LiveIntervals &LIS,
23609467b48Spatrick const MachineRegisterInfo &MRI) {
23709467b48Spatrick GCNRPTracker::LiveRegSet LiveRegs;
23809467b48Spatrick for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
23909467b48Spatrick auto Reg = Register::index2VirtReg(I);
24009467b48Spatrick if (!LIS.hasInterval(Reg))
24109467b48Spatrick continue;
24209467b48Spatrick auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
24309467b48Spatrick if (LiveMask.any())
24409467b48Spatrick LiveRegs[Reg] = LiveMask;
24509467b48Spatrick }
24609467b48Spatrick return LiveRegs;
24709467b48Spatrick }
24809467b48Spatrick
reset(const MachineInstr & MI,const LiveRegSet * LiveRegsCopy,bool After)24909467b48Spatrick void GCNRPTracker::reset(const MachineInstr &MI,
25009467b48Spatrick const LiveRegSet *LiveRegsCopy,
25109467b48Spatrick bool After) {
25209467b48Spatrick const MachineFunction &MF = *MI.getMF();
25309467b48Spatrick MRI = &MF.getRegInfo();
25409467b48Spatrick if (LiveRegsCopy) {
25509467b48Spatrick if (&LiveRegs != LiveRegsCopy)
25609467b48Spatrick LiveRegs = *LiveRegsCopy;
25709467b48Spatrick } else {
25809467b48Spatrick LiveRegs = After ? getLiveRegsAfter(MI, LIS)
25909467b48Spatrick : getLiveRegsBefore(MI, LIS);
26009467b48Spatrick }
26109467b48Spatrick
26209467b48Spatrick MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs);
26309467b48Spatrick }
26409467b48Spatrick
reset(const MachineInstr & MI,const LiveRegSet * LiveRegsCopy)26509467b48Spatrick void GCNUpwardRPTracker::reset(const MachineInstr &MI,
26609467b48Spatrick const LiveRegSet *LiveRegsCopy) {
26709467b48Spatrick GCNRPTracker::reset(MI, LiveRegsCopy, true);
26809467b48Spatrick }
26909467b48Spatrick
recede(const MachineInstr & MI)27009467b48Spatrick void GCNUpwardRPTracker::recede(const MachineInstr &MI) {
27109467b48Spatrick assert(MRI && "call reset first");
27209467b48Spatrick
27309467b48Spatrick LastTrackedMI = &MI;
27409467b48Spatrick
27509467b48Spatrick if (MI.isDebugInstr())
27609467b48Spatrick return;
27709467b48Spatrick
27809467b48Spatrick auto const RegUses = collectVirtualRegUses(MI, LIS, *MRI);
27909467b48Spatrick
28009467b48Spatrick // calc pressure at the MI (defs + uses)
28109467b48Spatrick auto AtMIPressure = CurPressure;
28209467b48Spatrick for (const auto &U : RegUses) {
28309467b48Spatrick auto LiveMask = LiveRegs[U.RegUnit];
28409467b48Spatrick AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *MRI);
28509467b48Spatrick }
28609467b48Spatrick // update max pressure
28709467b48Spatrick MaxPressure = max(AtMIPressure, MaxPressure);
28809467b48Spatrick
289097a140dSpatrick for (const auto &MO : MI.operands()) {
29073471bf0Spatrick if (!MO.isReg() || !MO.isDef() || !MO.getReg().isVirtual() || MO.isDead())
29109467b48Spatrick continue;
29209467b48Spatrick
29309467b48Spatrick auto Reg = MO.getReg();
29409467b48Spatrick auto I = LiveRegs.find(Reg);
29509467b48Spatrick if (I == LiveRegs.end())
29609467b48Spatrick continue;
29709467b48Spatrick auto &LiveMask = I->second;
29809467b48Spatrick auto PrevMask = LiveMask;
29909467b48Spatrick LiveMask &= ~getDefRegMask(MO, *MRI);
30009467b48Spatrick CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
30109467b48Spatrick if (LiveMask.none())
30209467b48Spatrick LiveRegs.erase(I);
30309467b48Spatrick }
30409467b48Spatrick for (const auto &U : RegUses) {
30509467b48Spatrick auto &LiveMask = LiveRegs[U.RegUnit];
30609467b48Spatrick auto PrevMask = LiveMask;
30709467b48Spatrick LiveMask |= U.LaneMask;
30809467b48Spatrick CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
30909467b48Spatrick }
31009467b48Spatrick assert(CurPressure == getRegPressure(*MRI, LiveRegs));
31109467b48Spatrick }
31209467b48Spatrick
reset(const MachineInstr & MI,const LiveRegSet * LiveRegsCopy)31309467b48Spatrick bool GCNDownwardRPTracker::reset(const MachineInstr &MI,
31409467b48Spatrick const LiveRegSet *LiveRegsCopy) {
31509467b48Spatrick MRI = &MI.getParent()->getParent()->getRegInfo();
31609467b48Spatrick LastTrackedMI = nullptr;
31709467b48Spatrick MBBEnd = MI.getParent()->end();
31809467b48Spatrick NextMI = &MI;
31909467b48Spatrick NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
32009467b48Spatrick if (NextMI == MBBEnd)
32109467b48Spatrick return false;
32209467b48Spatrick GCNRPTracker::reset(*NextMI, LiveRegsCopy, false);
32309467b48Spatrick return true;
32409467b48Spatrick }
32509467b48Spatrick
advanceBeforeNext()32609467b48Spatrick bool GCNDownwardRPTracker::advanceBeforeNext() {
32709467b48Spatrick assert(MRI && "call reset first");
328*d415bd75Srobert if (!LastTrackedMI)
329*d415bd75Srobert return NextMI == MBBEnd;
33009467b48Spatrick
331*d415bd75Srobert assert(NextMI == MBBEnd || !NextMI->isDebugInstr());
33209467b48Spatrick
333*d415bd75Srobert SlotIndex SI = NextMI == MBBEnd
334*d415bd75Srobert ? LIS.getInstructionIndex(*LastTrackedMI).getDeadSlot()
335*d415bd75Srobert : LIS.getInstructionIndex(*NextMI).getBaseIndex();
33609467b48Spatrick assert(SI.isValid());
33709467b48Spatrick
33809467b48Spatrick // Remove dead registers or mask bits.
33909467b48Spatrick for (auto &It : LiveRegs) {
34009467b48Spatrick const LiveInterval &LI = LIS.getInterval(It.first);
34109467b48Spatrick if (LI.hasSubRanges()) {
34209467b48Spatrick for (const auto &S : LI.subranges()) {
34309467b48Spatrick if (!S.liveAt(SI)) {
34409467b48Spatrick auto PrevMask = It.second;
34509467b48Spatrick It.second &= ~S.LaneMask;
34609467b48Spatrick CurPressure.inc(It.first, PrevMask, It.second, *MRI);
34709467b48Spatrick }
34809467b48Spatrick }
34909467b48Spatrick } else if (!LI.liveAt(SI)) {
35009467b48Spatrick auto PrevMask = It.second;
35109467b48Spatrick It.second = LaneBitmask::getNone();
35209467b48Spatrick CurPressure.inc(It.first, PrevMask, It.second, *MRI);
35309467b48Spatrick }
35409467b48Spatrick if (It.second.none())
35509467b48Spatrick LiveRegs.erase(It.first);
35609467b48Spatrick }
35709467b48Spatrick
35809467b48Spatrick MaxPressure = max(MaxPressure, CurPressure);
35909467b48Spatrick
360*d415bd75Srobert LastTrackedMI = nullptr;
361*d415bd75Srobert
362*d415bd75Srobert return NextMI == MBBEnd;
36309467b48Spatrick }
36409467b48Spatrick
advanceToNext()36509467b48Spatrick void GCNDownwardRPTracker::advanceToNext() {
36609467b48Spatrick LastTrackedMI = &*NextMI++;
36773471bf0Spatrick NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
36809467b48Spatrick
36909467b48Spatrick // Add new registers or mask bits.
370097a140dSpatrick for (const auto &MO : LastTrackedMI->operands()) {
371097a140dSpatrick if (!MO.isReg() || !MO.isDef())
37209467b48Spatrick continue;
37309467b48Spatrick Register Reg = MO.getReg();
37473471bf0Spatrick if (!Reg.isVirtual())
37509467b48Spatrick continue;
37609467b48Spatrick auto &LiveMask = LiveRegs[Reg];
37709467b48Spatrick auto PrevMask = LiveMask;
37809467b48Spatrick LiveMask |= getDefRegMask(MO, *MRI);
37909467b48Spatrick CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
38009467b48Spatrick }
38109467b48Spatrick
38209467b48Spatrick MaxPressure = max(MaxPressure, CurPressure);
38309467b48Spatrick }
38409467b48Spatrick
advance()38509467b48Spatrick bool GCNDownwardRPTracker::advance() {
386*d415bd75Srobert if (NextMI == MBBEnd)
38709467b48Spatrick return false;
388*d415bd75Srobert advanceBeforeNext();
38909467b48Spatrick advanceToNext();
39009467b48Spatrick return true;
39109467b48Spatrick }
39209467b48Spatrick
advance(MachineBasicBlock::const_iterator End)39309467b48Spatrick bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator End) {
39409467b48Spatrick while (NextMI != End)
39509467b48Spatrick if (!advance()) return false;
39609467b48Spatrick return true;
39709467b48Spatrick }
39809467b48Spatrick
advance(MachineBasicBlock::const_iterator Begin,MachineBasicBlock::const_iterator End,const LiveRegSet * LiveRegsCopy)39909467b48Spatrick bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator Begin,
40009467b48Spatrick MachineBasicBlock::const_iterator End,
40109467b48Spatrick const LiveRegSet *LiveRegsCopy) {
40209467b48Spatrick reset(*Begin, LiveRegsCopy);
40309467b48Spatrick return advance(End);
40409467b48Spatrick }
40509467b48Spatrick
40609467b48Spatrick #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
40709467b48Spatrick LLVM_DUMP_METHOD
reportMismatch(const GCNRPTracker::LiveRegSet & LISLR,const GCNRPTracker::LiveRegSet & TrackedLR,const TargetRegisterInfo * TRI)408*d415bd75Srobert Printable llvm::reportMismatch(const GCNRPTracker::LiveRegSet &LISLR,
40909467b48Spatrick const GCNRPTracker::LiveRegSet &TrackedLR,
41009467b48Spatrick const TargetRegisterInfo *TRI) {
411*d415bd75Srobert return Printable([&LISLR, &TrackedLR, TRI](raw_ostream &OS) {
41209467b48Spatrick for (auto const &P : TrackedLR) {
41309467b48Spatrick auto I = LISLR.find(P.first);
41409467b48Spatrick if (I == LISLR.end()) {
415*d415bd75Srobert OS << " " << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second)
41609467b48Spatrick << " isn't found in LIS reported set\n";
417*d415bd75Srobert } else if (I->second != P.second) {
418*d415bd75Srobert OS << " " << printReg(P.first, TRI)
419*d415bd75Srobert << " masks doesn't match: LIS reported " << PrintLaneMask(I->second)
420*d415bd75Srobert << ", tracked " << PrintLaneMask(P.second) << '\n';
42109467b48Spatrick }
42209467b48Spatrick }
42309467b48Spatrick for (auto const &P : LISLR) {
42409467b48Spatrick auto I = TrackedLR.find(P.first);
42509467b48Spatrick if (I == TrackedLR.end()) {
426*d415bd75Srobert OS << " " << printReg(P.first, TRI) << ":L" << PrintLaneMask(P.second)
42709467b48Spatrick << " isn't found in tracked set\n";
42809467b48Spatrick }
42909467b48Spatrick }
430*d415bd75Srobert });
43109467b48Spatrick }
43209467b48Spatrick
isValid() const43309467b48Spatrick bool GCNUpwardRPTracker::isValid() const {
43409467b48Spatrick const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
43509467b48Spatrick const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
43609467b48Spatrick const auto &TrackedLR = LiveRegs;
43709467b48Spatrick
43809467b48Spatrick if (!isEqual(LISLR, TrackedLR)) {
43909467b48Spatrick dbgs() << "\nGCNUpwardRPTracker error: Tracked and"
440*d415bd75Srobert " LIS reported livesets mismatch:\n"
441*d415bd75Srobert << print(LISLR, *MRI);
44209467b48Spatrick reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo());
44309467b48Spatrick return false;
44409467b48Spatrick }
44509467b48Spatrick
44609467b48Spatrick auto LISPressure = getRegPressure(*MRI, LISLR);
44709467b48Spatrick if (LISPressure != CurPressure) {
448*d415bd75Srobert dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: "
449*d415bd75Srobert << print(CurPressure) << "LIS rpt: " << print(LISPressure);
45009467b48Spatrick return false;
45109467b48Spatrick }
45209467b48Spatrick return true;
45309467b48Spatrick }
45409467b48Spatrick
455*d415bd75Srobert LLVM_DUMP_METHOD
print(const GCNRPTracker::LiveRegSet & LiveRegs,const MachineRegisterInfo & MRI)456*d415bd75Srobert Printable llvm::print(const GCNRPTracker::LiveRegSet &LiveRegs,
45709467b48Spatrick const MachineRegisterInfo &MRI) {
458*d415bd75Srobert return Printable([&LiveRegs, &MRI](raw_ostream &OS) {
45909467b48Spatrick const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
46009467b48Spatrick for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
461*d415bd75Srobert Register Reg = Register::index2VirtReg(I);
46209467b48Spatrick auto It = LiveRegs.find(Reg);
46309467b48Spatrick if (It != LiveRegs.end() && It->second.any())
46409467b48Spatrick OS << ' ' << printVRegOrUnit(Reg, TRI) << ':'
46509467b48Spatrick << PrintLaneMask(It->second);
46609467b48Spatrick }
46709467b48Spatrick OS << '\n';
468*d415bd75Srobert });
46909467b48Spatrick }
470*d415bd75Srobert
471*d415bd75Srobert LLVM_DUMP_METHOD
dump() const472*d415bd75Srobert void GCNRegPressure::dump() const { dbgs() << print(*this); }
473*d415bd75Srobert
47409467b48Spatrick #endif
475