blob: 992bb7cceb6f22371dd74dd71b7e5852e0572050 [file] [log] [blame]
Eugene Zelenko75134ec2017-08-10 00:46:15 +00001//===- GCNRegPressure.cpp -------------------------------------------------===//
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +00002//
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//===----------------------------------------------------------------------===//
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +00009
10#include "GCNRegPressure.h"
Eugene Zelenko75134ec2017-08-10 00:46:15 +000011#include "AMDGPUSubtarget.h"
12#include "SIRegisterInfo.h"
13#include "llvm/ADT/SmallVector.h"
14#include "llvm/CodeGen/LiveInterval.h"
Matthias Braunfa621d22017-12-13 02:51:04 +000015#include "llvm/CodeGen/LiveIntervals.h"
Eugene Zelenko75134ec2017-08-10 00:46:15 +000016#include "llvm/CodeGen/MachineInstr.h"
17#include "llvm/CodeGen/MachineOperand.h"
18#include "llvm/CodeGen/MachineRegisterInfo.h"
Valery Pykhtin95b4ca62017-05-22 13:09:40 +000019#include "llvm/CodeGen/RegisterPressure.h"
Eugene Zelenko75134ec2017-08-10 00:46:15 +000020#include "llvm/CodeGen/SlotIndexes.h"
David Blaikiee3a9b4c2017-11-17 01:07:10 +000021#include "llvm/CodeGen/TargetRegisterInfo.h"
Eugene Zelenko75134ec2017-08-10 00:46:15 +000022#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"
Eugene Zelenko75134ec2017-08-10 00:46:15 +000027#include <algorithm>
28#include <cassert>
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +000029
30using namespace llvm;
31
Evandro Menezesfdda7ea2017-07-11 22:08:28 +000032#define DEBUG_TYPE "machine-scheduler"
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +000033
Aaron Ballman1d03d382017-10-15 14:32:27 +000034#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +000035LLVM_DUMP_METHOD
36void 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);
Stanislav Mekhanoshine61df312017-05-16 15:43:52 +000044 if (!LIS.hasInterval(Reg))
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +000045 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) {
Francis Visoiu Mistrihaccb3372017-11-28 12:42:37 +000052 dbgs() << " " << printReg(Reg, MRI.getTargetRegisterInfo())
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +000053 << '\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
67static 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}
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +000079#endif
80
81///////////////////////////////////////////////////////////////////////////////
82// GCNRegPressure
83
84unsigned GCNRegPressure::getRegKind(unsigned Reg,
85 const MachineRegisterInfo &MRI) {
86 assert(TargetRegisterInfo::isVirtualRegister(Reg));
87 const auto RC = MRI.getRegClass(Reg);
88 auto STI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo());
89 return STI->isSGPRClass(RC) ?
Krzysztof Parzyszek36d7c2b2017-04-24 18:55:33 +000090 (STI->getRegSizeInBits(*RC) == 32 ? SGPR32 : SGPR_TUPLE) :
91 (STI->getRegSizeInBits(*RC) == 32 ? VGPR32 : VGPR_TUPLE);
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +000092}
93
94void GCNRegPressure::inc(unsigned Reg,
95 LaneBitmask PrevMask,
96 LaneBitmask NewMask,
97 const MachineRegisterInfo &MRI) {
98 if (NewMask == PrevMask)
99 return;
100
101 int Sign = 1;
102 if (NewMask < PrevMask) {
103 std::swap(NewMask, PrevMask);
104 Sign = -1;
105 }
106#ifndef NDEBUG
107 const auto MaxMask = MRI.getMaxLaneMaskForVReg(Reg);
108#endif
109 switch (auto Kind = getRegKind(Reg, MRI)) {
110 case SGPR32:
111 case VGPR32:
112 assert(PrevMask.none() && NewMask == MaxMask);
113 Value[Kind] += Sign;
114 break;
115
116 case SGPR_TUPLE:
117 case VGPR_TUPLE:
118 assert(NewMask < MaxMask || NewMask == MaxMask);
119 assert(PrevMask < NewMask);
120
121 Value[Kind == SGPR_TUPLE ? SGPR32 : VGPR32] +=
Krzysztof Parzyszekcf138ec2017-07-20 19:43:19 +0000122 Sign * (~PrevMask & NewMask).getNumLanes();
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000123
124 if (PrevMask.none()) {
125 assert(NewMask.any());
126 Value[Kind] += Sign * MRI.getPressureSets(Reg).getWeight();
127 }
128 break;
129
130 default: llvm_unreachable("Unknown register kind");
131 }
132}
133
134bool GCNRegPressure::less(const SISubtarget &ST,
135 const GCNRegPressure& O,
136 unsigned MaxOccupancy) const {
137 const auto SGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshinf7e31582017-05-09 20:50:04 +0000138 ST.getOccupancyWithNumSGPRs(getSGPRNum()));
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000139 const auto VGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshinf7e31582017-05-09 20:50:04 +0000140 ST.getOccupancyWithNumVGPRs(getVGPRNum()));
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000141 const auto OtherSGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshinf7e31582017-05-09 20:50:04 +0000142 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000143 const auto OtherVGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshinf7e31582017-05-09 20:50:04 +0000144 ST.getOccupancyWithNumVGPRs(O.getVGPRNum()));
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000145
146 const auto Occ = std::min(SGPROcc, VGPROcc);
147 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
148 if (Occ != OtherOcc)
149 return Occ > OtherOcc;
150
151 bool SGPRImportant = SGPROcc < VGPROcc;
152 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
153
154 // if both pressures disagree on what is more important compare vgprs
155 if (SGPRImportant != OtherSGPRImportant) {
156 SGPRImportant = false;
157 }
158
159 // compare large regs pressure
160 bool SGPRFirst = SGPRImportant;
161 for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
162 if (SGPRFirst) {
163 auto SW = getSGPRTuplesWeight();
164 auto OtherSW = O.getSGPRTuplesWeight();
165 if (SW != OtherSW)
166 return SW < OtherSW;
167 } else {
168 auto VW = getVGPRTuplesWeight();
169 auto OtherVW = O.getVGPRTuplesWeight();
170 if (VW != OtherVW)
171 return VW < OtherVW;
172 }
173 }
Stanislav Mekhanoshinf7e31582017-05-09 20:50:04 +0000174 return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
175 (getVGPRNum() < O.getVGPRNum());
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000176}
177
Aaron Ballman1d03d382017-10-15 14:32:27 +0000178#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000179LLVM_DUMP_METHOD
180void GCNRegPressure::print(raw_ostream &OS, const SISubtarget *ST) const {
Stanislav Mekhanoshinf7e31582017-05-09 20:50:04 +0000181 OS << "VGPRs: " << getVGPRNum();
182 if (ST) OS << "(O" << ST->getOccupancyWithNumVGPRs(getVGPRNum()) << ')';
183 OS << ", SGPRs: " << getSGPRNum();
184 if (ST) OS << "(O" << ST->getOccupancyWithNumSGPRs(getSGPRNum()) << ')';
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000185 OS << ", LVGPR WT: " << getVGPRTuplesWeight()
186 << ", LSGPR WT: " << getSGPRTuplesWeight();
187 if (ST) OS << " -> Occ: " << getOccupancy(*ST);
188 OS << '\n';
189}
190#endif
191
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000192static 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 return MO.getSubReg() == 0 ?
201 MRI.getMaxLaneMaskForVReg(MO.getReg()) :
202 MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
203}
204
205static 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 if (auto SubReg = MO.getSubReg())
212 return MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(SubReg);
213
214 auto MaxMask = MRI.getMaxLaneMaskForVReg(MO.getReg());
Krzysztof Parzyszek80b6fdc2017-07-20 19:15:56 +0000215 if (MaxMask == LaneBitmask::getLane(0)) // cannot have subregs
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000216 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 auto SI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex();
222 return getLiveLaneMask(MO.getReg(), SI, LIS, MRI);
223}
224
Benjamin Kramera0f27f92017-05-26 20:09:00 +0000225static SmallVector<RegisterMaskPair, 8>
226collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS,
227 const MachineRegisterInfo &MRI) {
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000228 SmallVector<RegisterMaskPair, 8> Res;
229 for (const auto &MO : MI.operands()) {
230 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
231 continue;
232 if (!MO.isUse() || !MO.readsReg())
233 continue;
234
235 auto const UsedMask = getUsedRegMask(MO, MRI, LIS);
236
237 auto Reg = MO.getReg();
238 auto I = std::find_if(Res.begin(), Res.end(), [Reg](const RegisterMaskPair &RM) {
239 return RM.RegUnit == Reg;
240 });
241 if (I != Res.end())
242 I->LaneMask |= UsedMask;
243 else
244 Res.push_back(RegisterMaskPair(Reg, UsedMask));
245 }
246 return Res;
247}
248
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000249///////////////////////////////////////////////////////////////////////////////
250// GCNRPTracker
251
252LaneBitmask llvm::getLiveLaneMask(unsigned Reg,
253 SlotIndex SI,
254 const LiveIntervals &LIS,
255 const MachineRegisterInfo &MRI) {
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000256 LaneBitmask LiveMask;
257 const auto &LI = LIS.getInterval(Reg);
258 if (LI.hasSubRanges()) {
259 for (const auto &S : LI.subranges())
260 if (S.liveAt(SI)) {
261 LiveMask |= S.LaneMask;
262 assert(LiveMask < MRI.getMaxLaneMaskForVReg(Reg) ||
263 LiveMask == MRI.getMaxLaneMaskForVReg(Reg));
264 }
265 } else if (LI.liveAt(SI)) {
266 LiveMask = MRI.getMaxLaneMaskForVReg(Reg);
267 }
268 return LiveMask;
269}
270
271GCNRPTracker::LiveRegSet llvm::getLiveRegs(SlotIndex SI,
272 const LiveIntervals &LIS,
273 const MachineRegisterInfo &MRI) {
274 GCNRPTracker::LiveRegSet LiveRegs;
275 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
276 auto Reg = TargetRegisterInfo::index2VirtReg(I);
Stanislav Mekhanoshine61df312017-05-16 15:43:52 +0000277 if (!LIS.hasInterval(Reg))
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000278 continue;
279 auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
280 if (LiveMask.any())
281 LiveRegs[Reg] = LiveMask;
282 }
283 return LiveRegs;
284}
285
Stanislav Mekhanoshine61df312017-05-16 15:43:52 +0000286void GCNUpwardRPTracker::reset(const MachineInstr &MI,
287 const LiveRegSet *LiveRegsCopy) {
288 MRI = &MI.getParent()->getParent()->getRegInfo();
289 if (LiveRegsCopy) {
290 if (&LiveRegs != LiveRegsCopy)
291 LiveRegs = *LiveRegsCopy;
292 } else {
293 LiveRegs = getLiveRegsAfter(MI, LIS);
294 }
295 MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs);
296}
297
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000298void GCNUpwardRPTracker::recede(const MachineInstr &MI) {
299 assert(MRI && "call reset first");
300
301 LastTrackedMI = &MI;
302
303 if (MI.isDebugValue())
304 return;
305
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000306 auto const RegUses = collectVirtualRegUses(MI, LIS, *MRI);
307
308 // calc pressure at the MI (defs + uses)
309 auto AtMIPressure = CurPressure;
310 for (const auto &U : RegUses) {
311 auto LiveMask = LiveRegs[U.RegUnit];
312 AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *MRI);
313 }
314 // update max pressure
315 MaxPressure = max(AtMIPressure, MaxPressure);
316
317 for (const auto &MO : MI.defs()) {
318 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()) ||
319 MO.isDead())
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000320 continue;
321
322 auto Reg = MO.getReg();
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000323 auto I = LiveRegs.find(Reg);
324 if (I == LiveRegs.end())
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000325 continue;
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000326 auto &LiveMask = I->second;
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000327 auto PrevMask = LiveMask;
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000328 LiveMask &= ~getDefRegMask(MO, *MRI);
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000329 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000330 if (LiveMask.none())
331 LiveRegs.erase(I);
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000332 }
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000333 for (const auto &U : RegUses) {
334 auto &LiveMask = LiveRegs[U.RegUnit];
335 auto PrevMask = LiveMask;
336 LiveMask |= U.LaneMask;
337 CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
338 }
339 assert(CurPressure == getRegPressure(*MRI, LiveRegs));
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000340}
341
Stanislav Mekhanoshine61df312017-05-16 15:43:52 +0000342bool GCNDownwardRPTracker::reset(const MachineInstr &MI,
343 const LiveRegSet *LiveRegsCopy) {
344 MRI = &MI.getParent()->getParent()->getRegInfo();
345 LastTrackedMI = nullptr;
346 MBBEnd = MI.getParent()->end();
347 NextMI = &MI;
348 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
349 if (NextMI == MBBEnd)
350 return false;
351 if (LiveRegsCopy) {
352 if (&LiveRegs != LiveRegsCopy)
353 LiveRegs = *LiveRegsCopy;
354 } else {
355 LiveRegs = getLiveRegsBefore(*NextMI, LIS);
356 }
357 MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs);
358 return true;
359}
360
361bool GCNDownwardRPTracker::advanceBeforeNext() {
362 assert(MRI && "call reset first");
363
364 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
365 if (NextMI == MBBEnd)
366 return false;
367
368 SlotIndex SI = LIS.getInstructionIndex(*NextMI).getBaseIndex();
369 assert(SI.isValid());
370
371 // Remove dead registers or mask bits.
372 for (auto &It : LiveRegs) {
373 const LiveInterval &LI = LIS.getInterval(It.first);
374 if (LI.hasSubRanges()) {
375 for (const auto &S : LI.subranges()) {
376 if (!S.liveAt(SI)) {
377 auto PrevMask = It.second;
378 It.second &= ~S.LaneMask;
379 CurPressure.inc(It.first, PrevMask, It.second, *MRI);
380 }
381 }
382 } else if (!LI.liveAt(SI)) {
383 auto PrevMask = It.second;
384 It.second = LaneBitmask::getNone();
385 CurPressure.inc(It.first, PrevMask, It.second, *MRI);
386 }
387 if (It.second.none())
388 LiveRegs.erase(It.first);
389 }
390
391 MaxPressure = max(MaxPressure, CurPressure);
392
393 return true;
394}
395
396void GCNDownwardRPTracker::advanceToNext() {
397 LastTrackedMI = &*NextMI++;
398
399 // Add new registers or mask bits.
400 for (const auto &MO : LastTrackedMI->defs()) {
401 if (!MO.isReg())
402 continue;
403 unsigned Reg = MO.getReg();
404 if (!TargetRegisterInfo::isVirtualRegister(Reg))
405 continue;
406 auto &LiveMask = LiveRegs[Reg];
407 auto PrevMask = LiveMask;
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000408 LiveMask |= getDefRegMask(MO, *MRI);
Stanislav Mekhanoshine61df312017-05-16 15:43:52 +0000409 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
410 }
411
412 MaxPressure = max(MaxPressure, CurPressure);
413}
414
415bool GCNDownwardRPTracker::advance() {
416 // If we have just called reset live set is actual.
417 if ((NextMI == MBBEnd) || (LastTrackedMI && !advanceBeforeNext()))
418 return false;
419 advanceToNext();
420 return true;
421}
422
423bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator End) {
424 while (NextMI != End)
425 if (!advance()) return false;
426 return true;
427}
428
429bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator Begin,
430 MachineBasicBlock::const_iterator End,
431 const LiveRegSet *LiveRegsCopy) {
432 reset(*Begin, LiveRegsCopy);
433 return advance(End);
434}
435
Aaron Ballman1d03d382017-10-15 14:32:27 +0000436#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000437LLVM_DUMP_METHOD
438static 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()) {
Francis Visoiu Mistrihaccb3372017-11-28 12:42:37 +0000444 dbgs() << " " << printReg(P.first, TRI)
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000445 << ":L" << PrintLaneMask(P.second)
446 << " isn't found in LIS reported set\n";
447 }
448 else if (I->second != P.second) {
Francis Visoiu Mistrihaccb3372017-11-28 12:42:37 +0000449 dbgs() << " " << printReg(P.first, TRI)
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000450 << " 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()) {
Francis Visoiu Mistrihaccb3372017-11-28 12:42:37 +0000460 dbgs() << " " << printReg(P.first, TRI)
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000461 << ":L" << PrintLaneMask(P.second)
462 << " isn't found in tracked set\n";
463 }
464 }
465}
466
467bool GCNUpwardRPTracker::isValid() const {
468 const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
469 const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
Valery Pykhtin95b4ca62017-05-22 13:09:40 +0000470 const auto &TrackedLR = LiveRegs;
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000471
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
Stanislav Mekhanoshin791f3112017-05-16 16:31:45 +0000491void 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())
Francis Visoiu Mistrihaccb3372017-11-28 12:42:37 +0000498 OS << ' ' << printVRegOrUnit(Reg, TRI) << ':'
Stanislav Mekhanoshin791f3112017-05-16 16:31:45 +0000499 << PrintLaneMask(It->second);
500 }
501 OS << '\n';
502}
Valery Pykhtin4b7cf6c2017-03-21 13:15:46 +0000503#endif