Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/AMDGPU/GCNRegPressure.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- GCNRegPressure.cpp -------------------------------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include "GCNRegPressure.h"
10
#include "AMDGPUSubtarget.h"
11
#include "SIRegisterInfo.h"
12
#include "llvm/ADT/SmallVector.h"
13
#include "llvm/CodeGen/LiveInterval.h"
14
#include "llvm/CodeGen/LiveIntervals.h"
15
#include "llvm/CodeGen/MachineInstr.h"
16
#include "llvm/CodeGen/MachineOperand.h"
17
#include "llvm/CodeGen/MachineRegisterInfo.h"
18
#include "llvm/CodeGen/RegisterPressure.h"
19
#include "llvm/CodeGen/SlotIndexes.h"
20
#include "llvm/CodeGen/TargetRegisterInfo.h"
21
#include "llvm/Config/llvm-config.h"
22
#include "llvm/MC/LaneBitmask.h"
23
#include "llvm/Support/Compiler.h"
24
#include "llvm/Support/Debug.h"
25
#include "llvm/Support/ErrorHandling.h"
26
#include "llvm/Support/raw_ostream.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
#endif
67
68
bool llvm::isEqual(const GCNRPTracker::LiveRegSet &S1,
69
0
                   const GCNRPTracker::LiveRegSet &S2) {
70
0
  if (S1.size() != S2.size())
71
0
    return false;
72
0
73
0
  for (const auto &P : S1) {
74
0
    auto I = S2.find(P.first);
75
0
    if (I == S2.end() || I->second != P.second)
76
0
      return false;
77
0
  }
78
0
  return true;
79
0
}
80
81
82
///////////////////////////////////////////////////////////////////////////////
83
// GCNRegPressure
84
85
unsigned GCNRegPressure::getRegKind(unsigned Reg,
86
1.45M
                                    const MachineRegisterInfo &MRI) {
87
1.45M
  assert(TargetRegisterInfo::isVirtualRegister(Reg));
88
1.45M
  const auto RC = MRI.getRegClass(Reg);
89
1.45M
  auto STI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo());
90
1.45M
  return STI->isSGPRClass(RC) ?
91
683k
    (STI->getRegSizeInBits(*RC) == 32 ? 
SGPR32111k
:
SGPR_TUPLE572k
) :
92
1.45M
    
STI->hasAGPRs(RC) 772k
?
93
3.85k
      (STI->getRegSizeInBits(*RC) == 32 ? 
AGPR32214
:
AGPR_TUPLE3.63k
) :
94
772k
      
(STI->getRegSizeInBits(*RC) == 32 768k
?
VGPR32414k
:
VGPR_TUPLE354k
);
95
1.45M
}
96
97
void GCNRegPressure::inc(unsigned Reg,
98
                         LaneBitmask PrevMask,
99
                         LaneBitmask NewMask,
100
2.84M
                         const MachineRegisterInfo &MRI) {
101
2.84M
  if (NewMask == PrevMask)
102
1.38M
    return;
103
1.45M
104
1.45M
  int Sign = 1;
105
1.45M
  if (NewMask < PrevMask) {
106
688k
    std::swap(NewMask, PrevMask);
107
688k
    Sign = -1;
108
688k
  }
109
#ifndef NDEBUG
110
  const auto MaxMask = MRI.getMaxLaneMaskForVReg(Reg);
111
#endif
112
  switch (auto Kind = getRegKind(Reg, MRI)) {
113
1.45M
  case SGPR32:
114
525k
  case VGPR32:
115
525k
  case AGPR32:
116
525k
    assert(PrevMask.none() && NewMask == MaxMask);
117
525k
    Value[Kind] += Sign;
118
525k
    break;
119
525k
120
930k
  case SGPR_TUPLE:
121
930k
  case VGPR_TUPLE:
122
930k
  case AGPR_TUPLE:
123
930k
    assert(NewMask < MaxMask || NewMask == MaxMask);
124
930k
    assert(PrevMask < NewMask);
125
930k
126
930k
    Value[Kind == SGPR_TUPLE ? 
SGPR32572k
:
Kind == AGPR_TUPLE 357k
?
AGPR323.63k
:
VGPR32354k
] +=
127
930k
      Sign * (~PrevMask & NewMask).getNumLanes();
128
930k
129
930k
    if (PrevMask.none()) {
130
508k
      assert(NewMask.any());
131
508k
      Value[Kind] += Sign * MRI.getPressureSets(Reg).getWeight();
132
508k
    }
133
930k
    break;
134
930k
135
930k
  
default: 0
llvm_unreachable0
("Unknown register kind");
136
1.45M
  }
137
1.45M
}
138
139
bool GCNRegPressure::less(const GCNSubtarget &ST,
140
                          const GCNRegPressure& O,
141
0
                          unsigned MaxOccupancy) const {
142
0
  const auto SGPROcc = std::min(MaxOccupancy,
143
0
                                ST.getOccupancyWithNumSGPRs(getSGPRNum()));
144
0
  const auto VGPROcc = std::min(MaxOccupancy,
145
0
                                ST.getOccupancyWithNumVGPRs(getVGPRNum()));
146
0
  const auto OtherSGPROcc = std::min(MaxOccupancy,
147
0
                                ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
148
0
  const auto OtherVGPROcc = std::min(MaxOccupancy,
149
0
                                ST.getOccupancyWithNumVGPRs(O.getVGPRNum()));
150
0
151
0
  const auto Occ = std::min(SGPROcc, VGPROcc);
152
0
  const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
153
0
  if (Occ != OtherOcc)
154
0
    return Occ > OtherOcc;
155
0
156
0
  bool SGPRImportant = SGPROcc < VGPROcc;
157
0
  const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
158
0
159
0
  // if both pressures disagree on what is more important compare vgprs
160
0
  if (SGPRImportant != OtherSGPRImportant) {
161
0
    SGPRImportant = false;
162
0
  }
163
0
164
0
  // compare large regs pressure
165
0
  bool SGPRFirst = SGPRImportant;
166
0
  for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
167
0
    if (SGPRFirst) {
168
0
      auto SW = getSGPRTuplesWeight();
169
0
      auto OtherSW = O.getSGPRTuplesWeight();
170
0
      if (SW != OtherSW)
171
0
        return SW < OtherSW;
172
0
    } else {
173
0
      auto VW = getVGPRTuplesWeight();
174
0
      auto OtherVW = O.getVGPRTuplesWeight();
175
0
      if (VW != OtherVW)
176
0
        return VW < OtherVW;
177
0
    }
178
0
  }
179
0
  return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
180
0
                         (getVGPRNum() < O.getVGPRNum());
181
0
}
182
183
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
184
LLVM_DUMP_METHOD
185
void GCNRegPressure::print(raw_ostream &OS, const GCNSubtarget *ST) const {
186
  OS << "VGPRs: " << getVGPRNum();
187
  if (ST) OS << "(O" << ST->getOccupancyWithNumVGPRs(getVGPRNum()) << ')';
188
  OS << ", SGPRs: " << getSGPRNum();
189
  if (ST) OS << "(O" << ST->getOccupancyWithNumSGPRs(getSGPRNum()) << ')';
190
  OS << ", LVGPR WT: " << getVGPRTuplesWeight()
191
     << ", LSGPR WT: " << getSGPRTuplesWeight();
192
  if (ST) OS << " -> Occ: " << getOccupancy(*ST);
193
  OS << '\n';
194
}
195
#endif
196
197
static LaneBitmask getDefRegMask(const MachineOperand &MO,
198
702k
                                 const MachineRegisterInfo &MRI) {
199
702k
  assert(MO.isDef() && MO.isReg() &&
200
702k
    TargetRegisterInfo::isVirtualRegister(MO.getReg()));
201
702k
202
702k
  // We don't rely on read-undef flag because in case of tentative schedule
203
702k
  // tracking it isn't set correctly yet. This works correctly however since
204
702k
  // use mask has been tracked before using LIS.
205
702k
  return MO.getSubReg() == 0 ?
206
428k
    MRI.getMaxLaneMaskForVReg(MO.getReg()) :
207
702k
    
MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg())273k
;
208
702k
}
209
210
static LaneBitmask getUsedRegMask(const MachineOperand &MO,
211
                                  const MachineRegisterInfo &MRI,
212
8.35k
                                  const LiveIntervals &LIS) {
213
8.35k
  assert(MO.isUse() && MO.isReg() &&
214
8.35k
         TargetRegisterInfo::isVirtualRegister(MO.getReg()));
215
8.35k
216
8.35k
  if (auto SubReg = MO.getSubReg())
217
2.51k
    return MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(SubReg);
218
5.84k
219
5.84k
  auto MaxMask = MRI.getMaxLaneMaskForVReg(MO.getReg());
220
5.84k
  if (MaxMask == LaneBitmask::getLane(0)) // cannot have subregs
221
4.87k
    return MaxMask;
222
970
223
970
  // For a tentative schedule LIS isn't updated yet but livemask should remain
224
970
  // the same on any schedule. Subreg defs can be reordered but they all must
225
970
  // dominate uses anyway.
226
970
  auto SI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex();
227
970
  return getLiveLaneMask(MO.getReg(), SI, LIS, MRI);
228
970
}
229
230
static SmallVector<RegisterMaskPair, 8>
231
collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS,
232
6.08k
                      const MachineRegisterInfo &MRI) {
233
6.08k
  SmallVector<RegisterMaskPair, 8> Res;
234
31.3k
  for (const auto &MO : MI.operands()) {
235
31.3k
    if (!MO.isReg() || 
!TargetRegisterInfo::isVirtualRegister(MO.getReg())21.1k
)
236
17.3k
      continue;
237
13.9k
    if (!MO.isUse() || 
!MO.readsReg()8.35k
)
238
5.58k
      continue;
239
8.35k
240
8.35k
    auto const UsedMask = getUsedRegMask(MO, MRI, LIS);
241
8.35k
242
8.35k
    auto Reg = MO.getReg();
243
8.35k
    auto I = std::find_if(Res.begin(), Res.end(), [Reg](const RegisterMaskPair &RM) {
244
2.65k
      return RM.RegUnit == Reg;
245
2.65k
    });
246
8.35k
    if (I != Res.end())
247
640
      I->LaneMask |= UsedMask;
248
7.71k
    else
249
7.71k
      Res.push_back(RegisterMaskPair(Reg, UsedMask));
250
8.35k
  }
251
6.08k
  return Res;
252
6.08k
}
253
254
///////////////////////////////////////////////////////////////////////////////
255
// GCNRPTracker
256
257
LaneBitmask llvm::getLiveLaneMask(unsigned Reg,
258
                                  SlotIndex SI,
259
                                  const LiveIntervals &LIS,
260
106k
                                  const MachineRegisterInfo &MRI) {
261
106k
  LaneBitmask LiveMask;
262
106k
  const auto &LI = LIS.getInterval(Reg);
263
106k
  if (LI.hasSubRanges()) {
264
30.2k
    for (const auto &S : LI.subranges())
265
87.9k
      if (S.liveAt(SI)) {
266
17.2k
        LiveMask |= S.LaneMask;
267
17.2k
        assert(LiveMask < MRI.getMaxLaneMaskForVReg(Reg) ||
268
17.2k
               LiveMask == MRI.getMaxLaneMaskForVReg(Reg));
269
17.2k
      }
270
76.4k
  } else if (LI.liveAt(SI)) {
271
10.3k
    LiveMask = MRI.getMaxLaneMaskForVReg(Reg);
272
10.3k
  }
273
106k
  return LiveMask;
274
106k
}
275
276
GCNRPTracker::LiveRegSet llvm::getLiveRegs(SlotIndex SI,
277
                                           const LiveIntervals &LIS,
278
5.76k
                                           const MachineRegisterInfo &MRI) {
279
5.76k
  GCNRPTracker::LiveRegSet LiveRegs;
280
437k
  for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; 
++I432k
) {
281
432k
    auto Reg = TargetRegisterInfo::index2VirtReg(I);
282
432k
    if (!LIS.hasInterval(Reg))
283
326k
      continue;
284
105k
    auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
285
105k
    if (LiveMask.any())
286
16.7k
      LiveRegs[Reg] = LiveMask;
287
105k
  }
288
5.76k
  return LiveRegs;
289
5.76k
}
290
291
void GCNRPTracker::reset(const MachineInstr &MI,
292
                         const LiveRegSet *LiveRegsCopy,
293
60.2k
                         bool After) {
294
60.2k
  const MachineFunction &MF = *MI.getMF();
295
60.2k
  MRI = &MF.getRegInfo();
296
60.2k
  if (LiveRegsCopy) {
297
54.4k
    if (&LiveRegs != LiveRegsCopy)
298
53.2k
      LiveRegs = *LiveRegsCopy;
299
54.4k
  } else {
300
5.76k
    LiveRegs = After ? 
getLiveRegsAfter(MI, LIS)20
301
5.76k
                     : 
getLiveRegsBefore(MI, LIS)5.74k
;
302
5.76k
  }
303
60.2k
304
60.2k
  MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs);
305
60.2k
}
306
307
void GCNUpwardRPTracker::reset(const MachineInstr &MI,
308
20
                               const LiveRegSet *LiveRegsCopy) {
309
20
  GCNRPTracker::reset(MI, LiveRegsCopy, true);
310
20
}
311
312
6.08k
void GCNUpwardRPTracker::recede(const MachineInstr &MI) {
313
6.08k
  assert(MRI && "call reset first");
314
6.08k
315
6.08k
  LastTrackedMI = &MI;
316
6.08k
317
6.08k
  if (MI.isDebugInstr())
318
0
    return;
319
6.08k
320
6.08k
  auto const RegUses = collectVirtualRegUses(MI, LIS, *MRI);
321
6.08k
322
6.08k
  // calc pressure at the MI (defs + uses)
323
6.08k
  auto AtMIPressure = CurPressure;
324
7.71k
  for (const auto &U : RegUses) {
325
7.71k
    auto LiveMask = LiveRegs[U.RegUnit];
326
7.71k
    AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *MRI);
327
7.71k
  }
328
6.08k
  // update max pressure
329
6.08k
  MaxPressure = max(AtMIPressure, MaxPressure);
330
6.08k
331
6.08k
  for (const auto &MO : MI.defs()) {
332
5.60k
    if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()) ||
333
5.60k
         
MO.isDead()5.58k
)
334
20
      continue;
335
5.58k
336
5.58k
    auto Reg = MO.getReg();
337
5.58k
    auto I = LiveRegs.find(Reg);
338
5.58k
    if (I == LiveRegs.end())
339
0
      continue;
340
5.58k
    auto &LiveMask = I->second;
341
5.58k
    auto PrevMask = LiveMask;
342
5.58k
    LiveMask &= ~getDefRegMask(MO, *MRI);
343
5.58k
    CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
344
5.58k
    if (LiveMask.none())
345
4.48k
      LiveRegs.erase(I);
346
5.58k
  }
347
7.71k
  for (const auto &U : RegUses) {
348
7.71k
    auto &LiveMask = LiveRegs[U.RegUnit];
349
7.71k
    auto PrevMask = LiveMask;
350
7.71k
    LiveMask |= U.LaneMask;
351
7.71k
    CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
352
7.71k
  }
353
6.08k
  assert(CurPressure == getRegPressure(*MRI, LiveRegs));
354
6.08k
}
355
356
bool GCNDownwardRPTracker::reset(const MachineInstr &MI,
357
60.2k
                                 const LiveRegSet *LiveRegsCopy) {
358
60.2k
  MRI = &MI.getParent()->getParent()->getRegInfo();
359
60.2k
  LastTrackedMI = nullptr;
360
60.2k
  MBBEnd = MI.getParent()->end();
361
60.2k
  NextMI = &MI;
362
60.2k
  NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
363
60.2k
  if (NextMI == MBBEnd)
364
1
    return false;
365
60.2k
  GCNRPTracker::reset(*NextMI, LiveRegsCopy, false);
366
60.2k
  return true;
367
60.2k
}
368
369
754k
bool GCNDownwardRPTracker::advanceBeforeNext() {
370
754k
  assert(MRI && "call reset first");
371
754k
372
754k
  NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
373
754k
  if (NextMI == MBBEnd)
374
1.04k
    return false;
375
753k
376
753k
  SlotIndex SI = LIS.getInstructionIndex(*NextMI).getBaseIndex();
377
753k
  assert(SI.isValid());
378
753k
379
753k
  // Remove dead registers or mask bits.
380
7.58M
  for (auto &It : LiveRegs) {
381
7.58M
    const LiveInterval &LI = LIS.getInterval(It.first);
382
7.58M
    if (LI.hasSubRanges()) {
383
6.62M
      for (const auto &S : LI.subranges()) {
384
6.62M
        if (!S.liveAt(SI)) {
385
1.73M
          auto PrevMask = It.second;
386
1.73M
          It.second &= ~S.LaneMask;
387
1.73M
          CurPressure.inc(It.first, PrevMask, It.second, *MRI);
388
1.73M
        }
389
6.62M
      }
390
5.51M
    } else if (!LI.liveAt(SI)) {
391
326k
      auto PrevMask = It.second;
392
326k
      It.second = LaneBitmask::getNone();
393
326k
      CurPressure.inc(It.first, PrevMask, It.second, *MRI);
394
326k
    }
395
7.58M
    if (It.second.none())
396
442k
      LiveRegs.erase(It.first);
397
7.58M
  }
398
753k
399
753k
  MaxPressure = max(MaxPressure, CurPressure);
400
753k
401
753k
  return true;
402
753k
}
403
404
790k
void GCNDownwardRPTracker::advanceToNext() {
405
790k
  LastTrackedMI = &*NextMI++;
406
790k
407
790k
  // Add new registers or mask bits.
408
790k
  for (const auto &MO : LastTrackedMI->defs()) {
409
731k
    if (!MO.isReg())
410
0
      continue;
411
731k
    unsigned Reg = MO.getReg();
412
731k
    if (!TargetRegisterInfo::isVirtualRegister(Reg))
413
34.7k
      continue;
414
696k
    auto &LiveMask = LiveRegs[Reg];
415
696k
    auto PrevMask = LiveMask;
416
696k
    LiveMask |= getDefRegMask(MO, *MRI);
417
696k
    CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
418
696k
  }
419
790k
420
790k
  MaxPressure = max(MaxPressure, CurPressure);
421
790k
}
422
423
405k
bool GCNDownwardRPTracker::advance() {
424
405k
  // If we have just called reset live set is actual.
425
405k
  if ((NextMI == MBBEnd) || (LastTrackedMI && 
!advanceBeforeNext()378k
))
426
0
    return false;
427
405k
  advanceToNext();
428
405k
  return true;
429
405k
}
430
431
27.5k
bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator End) {
432
433k
  while (NextMI != End)
433
405k
    if (!advance()) 
return false0
;
434
27.5k
  return true;
435
27.5k
}
436
437
bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator Begin,
438
                                   MachineBasicBlock::const_iterator End,
439
27.3k
                                   const LiveRegSet *LiveRegsCopy) {
440
27.3k
  reset(*Begin, LiveRegsCopy);
441
27.3k
  return advance(End);
442
27.3k
}
443
444
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
445
LLVM_DUMP_METHOD
446
static void reportMismatch(const GCNRPTracker::LiveRegSet &LISLR,
447
                           const GCNRPTracker::LiveRegSet &TrackedLR,
448
                           const TargetRegisterInfo *TRI) {
449
  for (auto const &P : TrackedLR) {
450
    auto I = LISLR.find(P.first);
451
    if (I == LISLR.end()) {
452
      dbgs() << "  " << printReg(P.first, TRI)
453
             << ":L" << PrintLaneMask(P.second)
454
             << " isn't found in LIS reported set\n";
455
    }
456
    else if (I->second != P.second) {
457
      dbgs() << "  " << printReg(P.first, TRI)
458
        << " masks doesn't match: LIS reported "
459
        << PrintLaneMask(I->second)
460
        << ", tracked "
461
        << PrintLaneMask(P.second)
462
        << '\n';
463
    }
464
  }
465
  for (auto const &P : LISLR) {
466
    auto I = TrackedLR.find(P.first);
467
    if (I == TrackedLR.end()) {
468
      dbgs() << "  " << printReg(P.first, TRI)
469
             << ":L" << PrintLaneMask(P.second)
470
             << " isn't found in tracked set\n";
471
    }
472
  }
473
}
474
475
bool GCNUpwardRPTracker::isValid() const {
476
  const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
477
  const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
478
  const auto &TrackedLR = LiveRegs;
479
480
  if (!isEqual(LISLR, TrackedLR)) {
481
    dbgs() << "\nGCNUpwardRPTracker error: Tracked and"
482
              " LIS reported livesets mismatch:\n";
483
    printLivesAt(SI, LIS, *MRI);
484
    reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo());
485
    return false;
486
  }
487
488
  auto LISPressure = getRegPressure(*MRI, LISLR);
489
  if (LISPressure != CurPressure) {
490
    dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: ";
491
    CurPressure.print(dbgs());
492
    dbgs() << "LIS rpt: ";
493
    LISPressure.print(dbgs());
494
    return false;
495
  }
496
  return true;
497
}
498
499
void GCNRPTracker::printLiveRegs(raw_ostream &OS, const LiveRegSet& LiveRegs,
500
                                 const MachineRegisterInfo &MRI) {
501
  const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
502
  for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
503
    unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
504
    auto It = LiveRegs.find(Reg);
505
    if (It != LiveRegs.end() && It->second.any())
506
      OS << ' ' << printVRegOrUnit(Reg, TRI) << ':'
507
         << PrintLaneMask(It->second);
508
  }
509
  OS << '\n';
510
}
511
#endif