LCOV - code coverage report
Current view: top level - lib/Target/AMDGPU - GCNRegPressure.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 157 192 81.8 %
Date: 2017-09-14 15:23:50 Functions: 15 16 93.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- GCNRegPressure.cpp -------------------------------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "GCNRegPressure.h"
      11             : #include "AMDGPUSubtarget.h"
      12             : #include "SIRegisterInfo.h"
      13             : #include "llvm/ADT/SmallVector.h"
      14             : #include "llvm/CodeGen/LiveInterval.h"
      15             : #include "llvm/CodeGen/LiveIntervalAnalysis.h"
      16             : #include "llvm/CodeGen/MachineInstr.h"
      17             : #include "llvm/CodeGen/MachineOperand.h"
      18             : #include "llvm/CodeGen/MachineRegisterInfo.h"
      19             : #include "llvm/CodeGen/RegisterPressure.h"
      20             : #include "llvm/CodeGen/SlotIndexes.h"
      21             : #include "llvm/MC/LaneBitmask.h"
      22             : #include "llvm/Support/Compiler.h"
      23             : #include "llvm/Support/Debug.h"
      24             : #include "llvm/Support/ErrorHandling.h"
      25             : #include "llvm/Support/raw_ostream.h"
      26             : #include "llvm/Target/TargetRegisterInfo.h"
      27             : #include <algorithm>
      28             : #include <cassert>
      29             : 
      30             : using namespace llvm;
      31             : 
      32             : #define DEBUG_TYPE "machine-scheduler"
      33             : 
      34             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
      35             : LLVM_DUMP_METHOD
      36             : void llvm::printLivesAt(SlotIndex SI,
      37             :                         const LiveIntervals &LIS,
      38             :                         const MachineRegisterInfo &MRI) {
      39             :   dbgs() << "Live regs at " << SI << ": "
      40             :          << *LIS.getInstructionFromIndex(SI);
      41             :   unsigned Num = 0;
      42             :   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
      43             :     const unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
      44             :     if (!LIS.hasInterval(Reg))
      45             :       continue;
      46             :     const auto &LI = LIS.getInterval(Reg);
      47             :     if (LI.hasSubRanges()) {
      48             :       bool firstTime = true;
      49             :       for (const auto &S : LI.subranges()) {
      50             :         if (!S.liveAt(SI)) continue;
      51             :         if (firstTime) {
      52             :           dbgs() << "  " << PrintReg(Reg, MRI.getTargetRegisterInfo())
      53             :                  << '\n';
      54             :           firstTime = false;
      55             :         }
      56             :         dbgs() << "  " << S << '\n';
      57             :         ++Num;
      58             :       }
      59             :     } else if (LI.liveAt(SI)) {
      60             :       dbgs() << "  " << LI << '\n';
      61             :       ++Num;
      62             :     }
      63             :   }
      64             :   if (!Num) dbgs() << "  <none>\n";
      65             : }
      66             : 
      67             : static bool isEqual(const GCNRPTracker::LiveRegSet &S1,
      68             :                     const GCNRPTracker::LiveRegSet &S2) {
      69             :   if (S1.size() != S2.size())
      70             :     return false;
      71             : 
      72             :   for (const auto &P : S1) {
      73             :     auto I = S2.find(P.first);
      74             :     if (I == S2.end() || I->second != P.second)
      75             :       return false;
      76             :   }
      77             :   return true;
      78             : }
      79             : #endif
      80             : 
      81             : ///////////////////////////////////////////////////////////////////////////////
      82             : // GCNRegPressure
      83             : 
      84      920311 : unsigned GCNRegPressure::getRegKind(unsigned Reg,
      85             :                                     const MachineRegisterInfo &MRI) {
      86             :   assert(TargetRegisterInfo::isVirtualRegister(Reg));
      87      920311 :   const auto RC = MRI.getRegClass(Reg);
      88     1840622 :   auto STI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo());
      89     1840622 :   return STI->isSGPRClass(RC) ?
      90      403352 :     (STI->getRegSizeInBits(*RC) == 32 ? SGPR32 : SGPR_TUPLE) :
      91     1437270 :     (STI->getRegSizeInBits(*RC) == 32 ? VGPR32 : VGPR_TUPLE);
      92             : }
      93             : 
      94     1795465 : void GCNRegPressure::inc(unsigned Reg,
      95             :                          LaneBitmask PrevMask,
      96             :                          LaneBitmask NewMask,
      97             :                          const MachineRegisterInfo &MRI) {
      98     1795465 :   if (NewMask == PrevMask)
      99             :     return;
     100             : 
     101      920311 :   int Sign = 1;
     102      920311 :   if (NewMask < PrevMask) {
     103      437750 :     std::swap(NewMask, PrevMask);
     104      437750 :     Sign = -1;
     105             :   }
     106             : #ifndef NDEBUG
     107             :   const auto MaxMask = MRI.getMaxLaneMaskForVReg(Reg);
     108             : #endif
     109      920311 :   switch (auto Kind = getRegKind(Reg, MRI)) {
     110      371455 :   case SGPR32:
     111             :   case VGPR32:
     112             :     assert(PrevMask.none() && NewMask == MaxMask);
     113      371455 :     Value[Kind] += Sign;
     114      371455 :     break;
     115             : 
     116      548856 :   case SGPR_TUPLE:
     117             :   case VGPR_TUPLE:
     118             :     assert(NewMask < MaxMask || NewMask == MaxMask);
     119             :     assert(PrevMask < NewMask);
     120             : 
     121      548856 :     Value[Kind == SGPR_TUPLE ? SGPR32 : VGPR32] +=
     122     2195424 :       Sign * (~PrevMask & NewMask).getNumLanes();
     123             : 
     124      548856 :     if (PrevMask.none()) {
     125             :       assert(NewMask.any());
     126      292380 :       Value[Kind] += Sign * MRI.getPressureSets(Reg).getWeight();
     127             :     }
     128             :     break;
     129             : 
     130           0 :   default: llvm_unreachable("Unknown register kind");
     131             :   }
     132             : }
     133             : 
     134           0 : bool GCNRegPressure::less(const SISubtarget &ST,
     135             :                           const GCNRegPressure& O,
     136             :                           unsigned MaxOccupancy) const {
     137           0 :   const auto SGPROcc = std::min(MaxOccupancy,
     138           0 :                                 ST.getOccupancyWithNumSGPRs(getSGPRNum()));
     139           0 :   const auto VGPROcc = std::min(MaxOccupancy,
     140           0 :                                 ST.getOccupancyWithNumVGPRs(getVGPRNum()));
     141           0 :   const auto OtherSGPROcc = std::min(MaxOccupancy,
     142           0 :                                 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
     143           0 :   const auto OtherVGPROcc = std::min(MaxOccupancy,
     144           0 :                                 ST.getOccupancyWithNumVGPRs(O.getVGPRNum()));
     145             : 
     146           0 :   const auto Occ = std::min(SGPROcc, VGPROcc);
     147           0 :   const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
     148           0 :   if (Occ != OtherOcc)
     149           0 :     return Occ > OtherOcc;
     150             : 
     151           0 :   bool SGPRImportant = SGPROcc < VGPROcc;
     152           0 :   const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
     153             : 
     154             :   // if both pressures disagree on what is more important compare vgprs
     155           0 :   if (SGPRImportant != OtherSGPRImportant) {
     156           0 :     SGPRImportant = false;
     157             :   }
     158             : 
     159             :   // compare large regs pressure
     160           0 :   bool SGPRFirst = SGPRImportant;
     161           0 :   for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
     162           0 :     if (SGPRFirst) {
     163           0 :       auto SW = getSGPRTuplesWeight();
     164           0 :       auto OtherSW = O.getSGPRTuplesWeight();
     165           0 :       if (SW != OtherSW)
     166           0 :         return SW < OtherSW;
     167             :     } else {
     168           0 :       auto VW = getVGPRTuplesWeight();
     169           0 :       auto OtherVW = O.getVGPRTuplesWeight();
     170           0 :       if (VW != OtherVW)
     171           0 :         return VW < OtherVW;
     172             :     }
     173             :   }
     174           0 :   return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
     175           0 :                          (getVGPRNum() < O.getVGPRNum());
     176             : }
     177             : 
     178             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     179             : LLVM_DUMP_METHOD
     180             : void GCNRegPressure::print(raw_ostream &OS, const SISubtarget *ST) const {
     181             :   OS << "VGPRs: " << getVGPRNum();
     182             :   if (ST) OS << "(O" << ST->getOccupancyWithNumVGPRs(getVGPRNum()) << ')';
     183             :   OS << ", SGPRs: " << getSGPRNum();
     184             :   if (ST) OS << "(O" << ST->getOccupancyWithNumSGPRs(getSGPRNum()) << ')';
     185             :   OS << ", LVGPR WT: " << getVGPRTuplesWeight()
     186             :      << ", LSGPR WT: " << getSGPRTuplesWeight();
     187             :   if (ST) OS << " -> Occ: " << getOccupancy(*ST);
     188             :   OS << '\n';
     189             : }
     190             : #endif
     191             : 
     192      445723 : static LaneBitmask getDefRegMask(const MachineOperand &MO,
     193             :                                  const MachineRegisterInfo &MRI) {
     194             :   assert(MO.isDef() && MO.isReg() &&
     195             :     TargetRegisterInfo::isVirtualRegister(MO.getReg()));
     196             : 
     197             :   // We don't rely on read-undef flag because in case of tentative schedule
     198             :   // tracking it isn't set correctly yet. This works correctly however since
     199             :   // use mask has been tracked before using LIS.
     200      445723 :   return MO.getSubReg() == 0 ?
     201      267587 :     MRI.getMaxLaneMaskForVReg(MO.getReg()) :
     202     1515305 :     MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
     203             : }
     204             : 
     205        7648 : static LaneBitmask getUsedRegMask(const MachineOperand &MO,
     206             :                                   const MachineRegisterInfo &MRI,
     207             :                                   const LiveIntervals &LIS) {
     208             :   assert(MO.isUse() && MO.isReg() &&
     209             :          TargetRegisterInfo::isVirtualRegister(MO.getReg()));
     210             : 
     211        7648 :   if (auto SubReg = MO.getSubReg())
     212        3360 :     return MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(SubReg);
     213             : 
     214        5968 :   auto MaxMask = MRI.getMaxLaneMaskForVReg(MO.getReg());
     215       11936 :   if (MaxMask == LaneBitmask::getLane(0)) // cannot have subregs
     216        5400 :     return MaxMask;
     217             : 
     218             :   // For a tentative schedule LIS isn't updated yet but livemask should remain
     219             :   // the same on any schedule. Subreg defs can be reordered but they all must
     220             :   // dominate uses anyway.
     221        1704 :   auto SI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex();
     222         568 :   return getLiveLaneMask(MO.getReg(), SI, LIS, MRI);
     223             : }
     224             : 
     225             : static SmallVector<RegisterMaskPair, 8>
     226        5855 : collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS,
     227             :                       const MachineRegisterInfo &MRI) {
     228        5855 :   SmallVector<RegisterMaskPair, 8> Res;
     229       33151 :   for (const auto &MO : MI.operands()) {
     230       46703 :     if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
     231       33901 :       continue;
     232       26086 :     if (!MO.isUse() || !MO.readsReg())
     233        5395 :       continue;
     234             : 
     235        7648 :     auto const UsedMask = getUsedRegMask(MO, MRI, LIS);
     236             : 
     237        7648 :     auto Reg = MO.getReg();
     238       22944 :     auto I = std::find_if(Res.begin(), Res.end(), [Reg](const RegisterMaskPair &RM) {
     239             :       return RM.RegUnit == Reg;
     240        7648 :     });
     241        7648 :     if (I != Res.end())
     242         384 :       I->LaneMask |= UsedMask;
     243             :     else
     244       14528 :       Res.push_back(RegisterMaskPair(Reg, UsedMask));
     245             :   }
     246        5855 :   return Res;
     247             : }
     248             : 
     249             : ///////////////////////////////////////////////////////////////////////////////
     250             : // GCNRPTracker
     251             : 
     252      186273 : LaneBitmask llvm::getLiveLaneMask(unsigned Reg,
     253             :                                   SlotIndex SI,
     254             :                                   const LiveIntervals &LIS,
     255             :                                   const MachineRegisterInfo &MRI) {
     256      186273 :   LaneBitmask LiveMask;
     257      186273 :   const auto &LI = LIS.getInterval(Reg);
     258      186273 :   if (LI.hasSubRanges()) {
     259      180549 :     for (const auto &S : LI.subranges())
     260      134630 :       if (S.liveAt(SI)) {
     261             :         LiveMask |= S.LaneMask;
     262             :         assert(LiveMask < MRI.getMaxLaneMaskForVReg(Reg) ||
     263             :                LiveMask == MRI.getMaxLaneMaskForVReg(Reg));
     264             :       }
     265      140354 :   } else if (LI.liveAt(SI)) {
     266        5904 :     LiveMask = MRI.getMaxLaneMaskForVReg(Reg);
     267             :   }
     268      186273 :   return LiveMask;
     269             : }
     270             : 
     271       14891 : GCNRPTracker::LiveRegSet llvm::getLiveRegs(SlotIndex SI,
     272             :                                            const LiveIntervals &LIS,
     273             :                                            const MachineRegisterInfo &MRI) {
     274       14891 :   GCNRPTracker::LiveRegSet LiveRegs;
     275      662645 :   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
     276      632863 :     auto Reg = TargetRegisterInfo::index2VirtReg(I);
     277     1265726 :     if (!LIS.hasInterval(Reg))
     278      447158 :       continue;
     279      185705 :     auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
     280      185705 :     if (LiveMask.any())
     281        6554 :       LiveRegs[Reg] = LiveMask;
     282             :   }
     283       14891 :   return LiveRegs;
     284             : }
     285             : 
     286          17 : void GCNUpwardRPTracker::reset(const MachineInstr &MI,
     287             :                                const LiveRegSet *LiveRegsCopy) {
     288          17 :   MRI = &MI.getParent()->getParent()->getRegInfo();
     289          17 :   if (LiveRegsCopy) {
     290           0 :     if (&LiveRegs != LiveRegsCopy)
     291           0 :       LiveRegs = *LiveRegsCopy;
     292             :   } else {
     293          34 :     LiveRegs = getLiveRegsAfter(MI, LIS);
     294             :   }
     295          17 :   MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs);
     296          17 : }
     297             : 
     298        5855 : void GCNUpwardRPTracker::recede(const MachineInstr &MI) {
     299             :   assert(MRI && "call reset first");
     300             : 
     301        5855 :   LastTrackedMI = &MI;
     302             : 
     303        5855 :   if (MI.isDebugValue())
     304           0 :     return;
     305             : 
     306       11710 :   auto const RegUses = collectVirtualRegUses(MI, LIS, *MRI);
     307             : 
     308             :   // calc pressure at the MI (defs + uses)
     309        5855 :   auto AtMIPressure = CurPressure;
     310       24829 :   for (const auto &U : RegUses) {
     311       14528 :     auto LiveMask = LiveRegs[U.RegUnit];
     312       14528 :     AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *MRI);
     313             :   }
     314             :   // update max pressure
     315       11710 :   MaxPressure = max(AtMIPressure, MaxPressure);
     316             : 
     317       11267 :   for (const auto &MO : MI.defs()) {
     318       16219 :     if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()) ||
     319        5395 :          MO.isDead())
     320          34 :       continue;
     321             : 
     322        5395 :     auto Reg = MO.getReg();
     323        5395 :     auto I = LiveRegs.find(Reg);
     324       16185 :     if (I == LiveRegs.end())
     325           0 :       continue;
     326        5395 :     auto &LiveMask = I->second;
     327        5395 :     auto PrevMask = LiveMask;
     328       16185 :     LiveMask &= ~getDefRegMask(MO, *MRI);
     329        5395 :     CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
     330        5395 :     if (LiveMask.none())
     331        4647 :       LiveRegs.erase(I);
     332             :   }
     333       24829 :   for (const auto &U : RegUses) {
     334       14528 :     auto &LiveMask = LiveRegs[U.RegUnit];
     335        7264 :     auto PrevMask = LiveMask;
     336        7264 :     LiveMask |= U.LaneMask;
     337        7264 :     CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
     338             :   }
     339             :   assert(CurPressure == getRegPressure(*MRI, LiveRegs));
     340             : }
     341             : 
     342       31939 : bool GCNDownwardRPTracker::reset(const MachineInstr &MI,
     343             :                                  const LiveRegSet *LiveRegsCopy) {
     344       31939 :   MRI = &MI.getParent()->getParent()->getRegInfo();
     345       31939 :   LastTrackedMI = nullptr;
     346       63878 :   MBBEnd = MI.getParent()->end();
     347       31939 :   NextMI = &MI;
     348       31939 :   NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
     349       63878 :   if (NextMI == MBBEnd)
     350             :     return false;
     351       31939 :   if (LiveRegsCopy) {
     352       17065 :     if (&LiveRegs != LiveRegsCopy)
     353       16387 :       LiveRegs = *LiveRegsCopy;
     354             :   } else {
     355       44622 :     LiveRegs = getLiveRegsBefore(*NextMI, LIS);
     356             :   }
     357       31939 :   MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs);
     358       31939 :   return true;
     359             : }
     360             : 
     361      494993 : bool GCNDownwardRPTracker::advanceBeforeNext() {
     362             :   assert(MRI && "call reset first");
     363             : 
     364      494993 :   NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
     365      989986 :   if (NextMI == MBBEnd)
     366             :     return false;
     367             : 
     368     1977848 :   SlotIndex SI = LIS.getInstructionIndex(*NextMI).getBaseIndex();
     369             :   assert(SI.isValid());
     370             : 
     371             :   // Remove dead registers or mask bits.
     372     7762399 :   for (auto &It : LiveRegs) {
     373    12558026 :     const LiveInterval &LI = LIS.getInterval(It.first);
     374     6279013 :     if (LI.hasSubRanges()) {
     375     6257601 :       for (const auto &S : LI.subranges()) {
     376     4739223 :         if (!S.liveAt(SI)) {
     377     1084207 :           auto PrevMask = It.second;
     378     3252621 :           It.second &= ~S.LaneMask;
     379     1084207 :           CurPressure.inc(It.first, PrevMask, It.second, *MRI);
     380             :         }
     381             :       }
     382     4760635 :     } else if (!LI.liveAt(SI)) {
     383      212932 :       auto PrevMask = It.second;
     384      212932 :       It.second = LaneBitmask::getNone();
     385      212932 :       CurPressure.inc(It.first, PrevMask, It.second, *MRI);
     386             :     }
     387    12558026 :     if (It.second.none())
     388      286854 :       LiveRegs.erase(It.first);
     389             :   }
     390             : 
     391      988924 :   MaxPressure = max(MaxPressure, CurPressure);
     392             : 
     393      494462 :   return true;
     394             : }
     395             : 
     396      510462 : void GCNDownwardRPTracker::advanceToNext() {
     397     1531386 :   LastTrackedMI = &*NextMI++;
     398             : 
     399             :   // Add new registers or mask bits.
     400     1472889 :   for (const auto &MO : LastTrackedMI->defs()) {
     401      451965 :     if (!MO.isReg())
     402       11637 :       continue;
     403      451965 :     unsigned Reg = MO.getReg();
     404      903930 :     if (!TargetRegisterInfo::isVirtualRegister(Reg))
     405       11637 :       continue;
     406      880656 :     auto &LiveMask = LiveRegs[Reg];
     407      440328 :     auto PrevMask = LiveMask;
     408      880656 :     LiveMask |= getDefRegMask(MO, *MRI);
     409      440328 :     CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
     410             :   }
     411             : 
     412     1020924 :   MaxPressure = max(MaxPressure, CurPressure);
     413      510462 : }
     414             : 
     415      265225 : bool GCNDownwardRPTracker::advance() {
     416             :   // If we have just called reset live set is actual.
     417      530450 :   if ((NextMI == MBBEnd) || (LastTrackedMI && !advanceBeforeNext()))
     418             :     return false;
     419      265225 :   advanceToNext();
     420      265225 :   return true;
     421             : }
     422             : 
     423       16147 : bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator End) {
     424      562744 :   while (NextMI != End)
     425      265225 :     if (!advance()) return false;
     426             :   return true;
     427             : }
     428             : 
     429       15979 : bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator Begin,
     430             :                                    MachineBasicBlock::const_iterator End,
     431             :                                    const LiveRegSet *LiveRegsCopy) {
     432       15979 :   reset(*Begin, LiveRegsCopy);
     433       15979 :   return advance(End);
     434             : }
     435             : 
     436             : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     437             : LLVM_DUMP_METHOD
     438             : static void reportMismatch(const GCNRPTracker::LiveRegSet &LISLR,
     439             :                            const GCNRPTracker::LiveRegSet &TrackedLR,
     440             :                            const TargetRegisterInfo *TRI) {
     441             :   for (auto const &P : TrackedLR) {
     442             :     auto I = LISLR.find(P.first);
     443             :     if (I == LISLR.end()) {
     444             :       dbgs() << "  " << PrintReg(P.first, TRI)
     445             :              << ":L" << PrintLaneMask(P.second)
     446             :              << " isn't found in LIS reported set\n";
     447             :     }
     448             :     else if (I->second != P.second) {
     449             :       dbgs() << "  " << PrintReg(P.first, TRI)
     450             :         << " masks doesn't match: LIS reported "
     451             :         << PrintLaneMask(I->second)
     452             :         << ", tracked "
     453             :         << PrintLaneMask(P.second)
     454             :         << '\n';
     455             :     }
     456             :   }
     457             :   for (auto const &P : LISLR) {
     458             :     auto I = TrackedLR.find(P.first);
     459             :     if (I == TrackedLR.end()) {
     460             :       dbgs() << "  " << PrintReg(P.first, TRI)
     461             :              << ":L" << PrintLaneMask(P.second)
     462             :              << " isn't found in tracked set\n";
     463             :     }
     464             :   }
     465             : }
     466             : 
     467             : bool GCNUpwardRPTracker::isValid() const {
     468             :   const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
     469             :   const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
     470             :   const auto &TrackedLR = LiveRegs;
     471             : 
     472             :   if (!isEqual(LISLR, TrackedLR)) {
     473             :     dbgs() << "\nGCNUpwardRPTracker error: Tracked and"
     474             :               " LIS reported livesets mismatch:\n";
     475             :     printLivesAt(SI, LIS, *MRI);
     476             :     reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo());
     477             :     return false;
     478             :   }
     479             : 
     480             :   auto LISPressure = getRegPressure(*MRI, LISLR);
     481             :   if (LISPressure != CurPressure) {
     482             :     dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: ";
     483             :     CurPressure.print(dbgs());
     484             :     dbgs() << "LIS rpt: ";
     485             :     LISPressure.print(dbgs());
     486             :     return false;
     487             :   }
     488             :   return true;
     489             : }
     490             : 
     491             : void GCNRPTracker::printLiveRegs(raw_ostream &OS, const LiveRegSet& LiveRegs,
     492             :                                  const MachineRegisterInfo &MRI) {
     493             :   const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
     494             :   for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
     495             :     unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
     496             :     auto It = LiveRegs.find(Reg);
     497             :     if (It != LiveRegs.end() && It->second.any())
     498             :       OS << ' ' << PrintVRegOrUnit(Reg, TRI) << ':'
     499             :          << PrintLaneMask(It->second);
     500             :   }
     501             :   OS << '\n';
     502             : }
     503             : #endif

Generated by: LCOV version 1.13