blob: be01988b6bc636b1b19bf2c4f97adf2a53ece7b4 [file] [log] [blame]
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +00001//===- GCNRegPressure.cpp -------------------------------------------------===//
Valery Pykhtinfd4c4102017-03-21 13:15:46 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Valery Pykhtinfd4c4102017-03-21 13:15:46 +00006//
7//===----------------------------------------------------------------------===//
Valery Pykhtinfd4c4102017-03-21 13:15:46 +00008
9#include "GCNRegPressure.h"
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +000010#include "AMDGPUSubtarget.h"
11#include "SIRegisterInfo.h"
12#include "llvm/ADT/SmallVector.h"
13#include "llvm/CodeGen/LiveInterval.h"
Matthias Braunf8422972017-12-13 02:51:04 +000014#include "llvm/CodeGen/LiveIntervals.h"
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +000015#include "llvm/CodeGen/MachineInstr.h"
16#include "llvm/CodeGen/MachineOperand.h"
17#include "llvm/CodeGen/MachineRegisterInfo.h"
Valery Pykhtin74cb9c82017-05-22 13:09:40 +000018#include "llvm/CodeGen/RegisterPressure.h"
Eugene Zelenkoc8fbf6f2017-08-10 00:46:15 +000019#include "llvm/CodeGen/SlotIndexes.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000020#include "llvm/CodeGen/TargetRegisterInfo.h"
Nico Weber432a3882018-04-30 14:59:11 +000021#include "llvm/Config/llvm-config.h"
Eugene Zelenkoc8fbf6f2017-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 Zelenkoc8fbf6f2017-08-10 00:46:15 +000027#include <algorithm>
28#include <cassert>
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000029
30using namespace llvm;
31
Evandro Menezes0cd23f562017-07-11 22:08:28 +000032#define DEBUG_TYPE "machine-scheduler"
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000033
Aaron Ballman615eb472017-10-15 14:32:27 +000034#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Valery Pykhtinfd4c4102017-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 Mekhanoshin464cecf2017-05-16 15:43:52 +000044 if (!LIS.hasInterval(Reg))
Valery Pykhtinfd4c4102017-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 Mistrih9d419d32017-11-28 12:42:37 +000052 dbgs() << " " << printReg(Reg, MRI.getTargetRegisterInfo())
Valery Pykhtinfd4c4102017-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}
Valery Pykhtin7e854e12019-06-18 11:43:17 +000066#endif
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000067
Valery Pykhtin7e854e12019-06-18 11:43:17 +000068bool llvm::isEqual(const GCNRPTracker::LiveRegSet &S1,
69 const GCNRPTracker::LiveRegSet &S2) {
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000070 if (S1.size() != S2.size())
71 return false;
72
73 for (const auto &P : S1) {
74 auto I = S2.find(P.first);
75 if (I == S2.end() || I->second != P.second)
76 return false;
77 }
78 return true;
79}
Valery Pykhtin7e854e12019-06-18 11:43:17 +000080
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000081
82///////////////////////////////////////////////////////////////////////////////
83// GCNRegPressure
84
85unsigned GCNRegPressure::getRegKind(unsigned Reg,
86 const MachineRegisterInfo &MRI) {
87 assert(TargetRegisterInfo::isVirtualRegister(Reg));
88 const auto RC = MRI.getRegClass(Reg);
89 auto STI = static_cast<const SIRegisterInfo*>(MRI.getTargetRegisterInfo());
90 return STI->isSGPRClass(RC) ?
Krzysztof Parzyszek44e25f32017-04-24 18:55:33 +000091 (STI->getRegSizeInBits(*RC) == 32 ? SGPR32 : SGPR_TUPLE) :
92 (STI->getRegSizeInBits(*RC) == 32 ? VGPR32 : VGPR_TUPLE);
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000093}
94
95void GCNRegPressure::inc(unsigned Reg,
96 LaneBitmask PrevMask,
97 LaneBitmask NewMask,
98 const MachineRegisterInfo &MRI) {
99 if (NewMask == PrevMask)
100 return;
101
102 int Sign = 1;
103 if (NewMask < PrevMask) {
104 std::swap(NewMask, PrevMask);
105 Sign = -1;
106 }
107#ifndef NDEBUG
108 const auto MaxMask = MRI.getMaxLaneMaskForVReg(Reg);
109#endif
110 switch (auto Kind = getRegKind(Reg, MRI)) {
111 case SGPR32:
112 case VGPR32:
113 assert(PrevMask.none() && NewMask == MaxMask);
114 Value[Kind] += Sign;
115 break;
116
117 case SGPR_TUPLE:
118 case VGPR_TUPLE:
119 assert(NewMask < MaxMask || NewMask == MaxMask);
120 assert(PrevMask < NewMask);
121
122 Value[Kind == SGPR_TUPLE ? SGPR32 : VGPR32] +=
Krzysztof Parzyszekf3a778d2017-07-20 19:43:19 +0000123 Sign * (~PrevMask & NewMask).getNumLanes();
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000124
125 if (PrevMask.none()) {
126 assert(NewMask.any());
127 Value[Kind] += Sign * MRI.getPressureSets(Reg).getWeight();
128 }
129 break;
130
131 default: llvm_unreachable("Unknown register kind");
132 }
133}
134
Tom Stellard5bfbae52018-07-11 20:59:01 +0000135bool GCNRegPressure::less(const GCNSubtarget &ST,
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000136 const GCNRegPressure& O,
137 unsigned MaxOccupancy) const {
138 const auto SGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000139 ST.getOccupancyWithNumSGPRs(getSGPRNum()));
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000140 const auto VGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000141 ST.getOccupancyWithNumVGPRs(getVGPRNum()));
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000142 const auto OtherSGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000143 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000144 const auto OtherVGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000145 ST.getOccupancyWithNumVGPRs(O.getVGPRNum()));
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000146
147 const auto Occ = std::min(SGPROcc, VGPROcc);
148 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
149 if (Occ != OtherOcc)
150 return Occ > OtherOcc;
151
152 bool SGPRImportant = SGPROcc < VGPROcc;
153 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
154
155 // if both pressures disagree on what is more important compare vgprs
156 if (SGPRImportant != OtherSGPRImportant) {
157 SGPRImportant = false;
158 }
159
160 // compare large regs pressure
161 bool SGPRFirst = SGPRImportant;
162 for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
163 if (SGPRFirst) {
164 auto SW = getSGPRTuplesWeight();
165 auto OtherSW = O.getSGPRTuplesWeight();
166 if (SW != OtherSW)
167 return SW < OtherSW;
168 } else {
169 auto VW = getVGPRTuplesWeight();
170 auto OtherVW = O.getVGPRTuplesWeight();
171 if (VW != OtherVW)
172 return VW < OtherVW;
173 }
174 }
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000175 return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
176 (getVGPRNum() < O.getVGPRNum());
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000177}
178
Aaron Ballman615eb472017-10-15 14:32:27 +0000179#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000180LLVM_DUMP_METHOD
Tom Stellard5bfbae52018-07-11 20:59:01 +0000181void GCNRegPressure::print(raw_ostream &OS, const GCNSubtarget *ST) const {
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000182 OS << "VGPRs: " << getVGPRNum();
183 if (ST) OS << "(O" << ST->getOccupancyWithNumVGPRs(getVGPRNum()) << ')';
184 OS << ", SGPRs: " << getSGPRNum();
185 if (ST) OS << "(O" << ST->getOccupancyWithNumSGPRs(getSGPRNum()) << ')';
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000186 OS << ", LVGPR WT: " << getVGPRTuplesWeight()
187 << ", LSGPR WT: " << getSGPRTuplesWeight();
188 if (ST) OS << " -> Occ: " << getOccupancy(*ST);
189 OS << '\n';
190}
191#endif
192
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000193static LaneBitmask getDefRegMask(const MachineOperand &MO,
194 const MachineRegisterInfo &MRI) {
195 assert(MO.isDef() && MO.isReg() &&
196 TargetRegisterInfo::isVirtualRegister(MO.getReg()));
197
198 // We don't rely on read-undef flag because in case of tentative schedule
199 // tracking it isn't set correctly yet. This works correctly however since
200 // use mask has been tracked before using LIS.
201 return MO.getSubReg() == 0 ?
202 MRI.getMaxLaneMaskForVReg(MO.getReg()) :
203 MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
204}
205
206static LaneBitmask getUsedRegMask(const MachineOperand &MO,
207 const MachineRegisterInfo &MRI,
208 const LiveIntervals &LIS) {
209 assert(MO.isUse() && MO.isReg() &&
210 TargetRegisterInfo::isVirtualRegister(MO.getReg()));
211
212 if (auto SubReg = MO.getSubReg())
213 return MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(SubReg);
214
215 auto MaxMask = MRI.getMaxLaneMaskForVReg(MO.getReg());
Krzysztof Parzyszeke9f0c1e2017-07-20 19:15:56 +0000216 if (MaxMask == LaneBitmask::getLane(0)) // cannot have subregs
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000217 return MaxMask;
218
219 // For a tentative schedule LIS isn't updated yet but livemask should remain
220 // the same on any schedule. Subreg defs can be reordered but they all must
221 // dominate uses anyway.
222 auto SI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex();
223 return getLiveLaneMask(MO.getReg(), SI, LIS, MRI);
224}
225
Benjamin Kramerdebb3c32017-05-26 20:09:00 +0000226static SmallVector<RegisterMaskPair, 8>
227collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS,
228 const MachineRegisterInfo &MRI) {
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000229 SmallVector<RegisterMaskPair, 8> Res;
230 for (const auto &MO : MI.operands()) {
231 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
232 continue;
233 if (!MO.isUse() || !MO.readsReg())
234 continue;
235
236 auto const UsedMask = getUsedRegMask(MO, MRI, LIS);
237
238 auto Reg = MO.getReg();
239 auto I = std::find_if(Res.begin(), Res.end(), [Reg](const RegisterMaskPair &RM) {
240 return RM.RegUnit == Reg;
241 });
242 if (I != Res.end())
243 I->LaneMask |= UsedMask;
244 else
245 Res.push_back(RegisterMaskPair(Reg, UsedMask));
246 }
247 return Res;
248}
249
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000250///////////////////////////////////////////////////////////////////////////////
251// GCNRPTracker
252
253LaneBitmask llvm::getLiveLaneMask(unsigned Reg,
254 SlotIndex SI,
255 const LiveIntervals &LIS,
256 const MachineRegisterInfo &MRI) {
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000257 LaneBitmask LiveMask;
258 const auto &LI = LIS.getInterval(Reg);
259 if (LI.hasSubRanges()) {
260 for (const auto &S : LI.subranges())
261 if (S.liveAt(SI)) {
262 LiveMask |= S.LaneMask;
263 assert(LiveMask < MRI.getMaxLaneMaskForVReg(Reg) ||
264 LiveMask == MRI.getMaxLaneMaskForVReg(Reg));
265 }
266 } else if (LI.liveAt(SI)) {
267 LiveMask = MRI.getMaxLaneMaskForVReg(Reg);
268 }
269 return LiveMask;
270}
271
272GCNRPTracker::LiveRegSet llvm::getLiveRegs(SlotIndex SI,
273 const LiveIntervals &LIS,
274 const MachineRegisterInfo &MRI) {
275 GCNRPTracker::LiveRegSet LiveRegs;
276 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
277 auto Reg = TargetRegisterInfo::index2VirtReg(I);
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000278 if (!LIS.hasInterval(Reg))
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000279 continue;
280 auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
281 if (LiveMask.any())
282 LiveRegs[Reg] = LiveMask;
283 }
284 return LiveRegs;
285}
286
Stanislav Mekhanoshin28624f92018-06-04 17:21:54 +0000287void GCNRPTracker::reset(const MachineInstr &MI,
288 const LiveRegSet *LiveRegsCopy,
289 bool After) {
290 const MachineFunction &MF = *MI.getMF();
291 MRI = &MF.getRegInfo();
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000292 if (LiveRegsCopy) {
293 if (&LiveRegs != LiveRegsCopy)
294 LiveRegs = *LiveRegsCopy;
295 } else {
Stanislav Mekhanoshin28624f92018-06-04 17:21:54 +0000296 LiveRegs = After ? getLiveRegsAfter(MI, LIS)
297 : getLiveRegsBefore(MI, LIS);
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000298 }
Stanislav Mekhanoshin28624f92018-06-04 17:21:54 +0000299
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000300 MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs);
301}
302
Stanislav Mekhanoshin28624f92018-06-04 17:21:54 +0000303void GCNUpwardRPTracker::reset(const MachineInstr &MI,
304 const LiveRegSet *LiveRegsCopy) {
305 GCNRPTracker::reset(MI, LiveRegsCopy, true);
306}
307
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000308void GCNUpwardRPTracker::recede(const MachineInstr &MI) {
309 assert(MRI && "call reset first");
310
311 LastTrackedMI = &MI;
312
Shiva Chen801bf7e2018-05-09 02:42:00 +0000313 if (MI.isDebugInstr())
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000314 return;
315
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000316 auto const RegUses = collectVirtualRegUses(MI, LIS, *MRI);
317
318 // calc pressure at the MI (defs + uses)
319 auto AtMIPressure = CurPressure;
320 for (const auto &U : RegUses) {
321 auto LiveMask = LiveRegs[U.RegUnit];
322 AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *MRI);
323 }
324 // update max pressure
325 MaxPressure = max(AtMIPressure, MaxPressure);
326
327 for (const auto &MO : MI.defs()) {
328 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()) ||
329 MO.isDead())
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000330 continue;
331
332 auto Reg = MO.getReg();
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000333 auto I = LiveRegs.find(Reg);
334 if (I == LiveRegs.end())
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000335 continue;
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000336 auto &LiveMask = I->second;
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000337 auto PrevMask = LiveMask;
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000338 LiveMask &= ~getDefRegMask(MO, *MRI);
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000339 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000340 if (LiveMask.none())
341 LiveRegs.erase(I);
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000342 }
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000343 for (const auto &U : RegUses) {
344 auto &LiveMask = LiveRegs[U.RegUnit];
345 auto PrevMask = LiveMask;
346 LiveMask |= U.LaneMask;
347 CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
348 }
349 assert(CurPressure == getRegPressure(*MRI, LiveRegs));
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000350}
351
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000352bool GCNDownwardRPTracker::reset(const MachineInstr &MI,
353 const LiveRegSet *LiveRegsCopy) {
354 MRI = &MI.getParent()->getParent()->getRegInfo();
355 LastTrackedMI = nullptr;
356 MBBEnd = MI.getParent()->end();
357 NextMI = &MI;
358 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
359 if (NextMI == MBBEnd)
360 return false;
Stanislav Mekhanoshin28624f92018-06-04 17:21:54 +0000361 GCNRPTracker::reset(*NextMI, LiveRegsCopy, false);
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000362 return true;
363}
364
365bool GCNDownwardRPTracker::advanceBeforeNext() {
366 assert(MRI && "call reset first");
367
368 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
369 if (NextMI == MBBEnd)
370 return false;
371
372 SlotIndex SI = LIS.getInstructionIndex(*NextMI).getBaseIndex();
373 assert(SI.isValid());
374
375 // Remove dead registers or mask bits.
376 for (auto &It : LiveRegs) {
377 const LiveInterval &LI = LIS.getInterval(It.first);
378 if (LI.hasSubRanges()) {
379 for (const auto &S : LI.subranges()) {
380 if (!S.liveAt(SI)) {
381 auto PrevMask = It.second;
382 It.second &= ~S.LaneMask;
383 CurPressure.inc(It.first, PrevMask, It.second, *MRI);
384 }
385 }
386 } else if (!LI.liveAt(SI)) {
387 auto PrevMask = It.second;
388 It.second = LaneBitmask::getNone();
389 CurPressure.inc(It.first, PrevMask, It.second, *MRI);
390 }
391 if (It.second.none())
392 LiveRegs.erase(It.first);
393 }
394
395 MaxPressure = max(MaxPressure, CurPressure);
396
397 return true;
398}
399
400void GCNDownwardRPTracker::advanceToNext() {
401 LastTrackedMI = &*NextMI++;
402
403 // Add new registers or mask bits.
404 for (const auto &MO : LastTrackedMI->defs()) {
405 if (!MO.isReg())
406 continue;
407 unsigned Reg = MO.getReg();
408 if (!TargetRegisterInfo::isVirtualRegister(Reg))
409 continue;
410 auto &LiveMask = LiveRegs[Reg];
411 auto PrevMask = LiveMask;
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000412 LiveMask |= getDefRegMask(MO, *MRI);
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000413 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
414 }
415
416 MaxPressure = max(MaxPressure, CurPressure);
417}
418
419bool GCNDownwardRPTracker::advance() {
420 // If we have just called reset live set is actual.
421 if ((NextMI == MBBEnd) || (LastTrackedMI && !advanceBeforeNext()))
422 return false;
423 advanceToNext();
424 return true;
425}
426
427bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator End) {
428 while (NextMI != End)
429 if (!advance()) return false;
430 return true;
431}
432
433bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator Begin,
434 MachineBasicBlock::const_iterator End,
435 const LiveRegSet *LiveRegsCopy) {
436 reset(*Begin, LiveRegsCopy);
437 return advance(End);
438}
439
Aaron Ballman615eb472017-10-15 14:32:27 +0000440#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000441LLVM_DUMP_METHOD
442static void reportMismatch(const GCNRPTracker::LiveRegSet &LISLR,
443 const GCNRPTracker::LiveRegSet &TrackedLR,
444 const TargetRegisterInfo *TRI) {
445 for (auto const &P : TrackedLR) {
446 auto I = LISLR.find(P.first);
447 if (I == LISLR.end()) {
Francis Visoiu Mistrih9d419d32017-11-28 12:42:37 +0000448 dbgs() << " " << printReg(P.first, TRI)
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000449 << ":L" << PrintLaneMask(P.second)
450 << " isn't found in LIS reported set\n";
451 }
452 else if (I->second != P.second) {
Francis Visoiu Mistrih9d419d32017-11-28 12:42:37 +0000453 dbgs() << " " << printReg(P.first, TRI)
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000454 << " masks doesn't match: LIS reported "
455 << PrintLaneMask(I->second)
456 << ", tracked "
457 << PrintLaneMask(P.second)
458 << '\n';
459 }
460 }
461 for (auto const &P : LISLR) {
462 auto I = TrackedLR.find(P.first);
463 if (I == TrackedLR.end()) {
Francis Visoiu Mistrih9d419d32017-11-28 12:42:37 +0000464 dbgs() << " " << printReg(P.first, TRI)
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000465 << ":L" << PrintLaneMask(P.second)
466 << " isn't found in tracked set\n";
467 }
468 }
469}
470
471bool GCNUpwardRPTracker::isValid() const {
472 const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
473 const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000474 const auto &TrackedLR = LiveRegs;
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000475
476 if (!isEqual(LISLR, TrackedLR)) {
477 dbgs() << "\nGCNUpwardRPTracker error: Tracked and"
478 " LIS reported livesets mismatch:\n";
479 printLivesAt(SI, LIS, *MRI);
480 reportMismatch(LISLR, TrackedLR, MRI->getTargetRegisterInfo());
481 return false;
482 }
483
484 auto LISPressure = getRegPressure(*MRI, LISLR);
485 if (LISPressure != CurPressure) {
486 dbgs() << "GCNUpwardRPTracker error: Pressure sets different\nTracked: ";
487 CurPressure.print(dbgs());
488 dbgs() << "LIS rpt: ";
489 LISPressure.print(dbgs());
490 return false;
491 }
492 return true;
493}
494
Stanislav Mekhanoshinacca0f52017-05-16 16:31:45 +0000495void GCNRPTracker::printLiveRegs(raw_ostream &OS, const LiveRegSet& LiveRegs,
496 const MachineRegisterInfo &MRI) {
497 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
498 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
499 unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
500 auto It = LiveRegs.find(Reg);
501 if (It != LiveRegs.end() && It->second.any())
Francis Visoiu Mistrih9d419d32017-11-28 12:42:37 +0000502 OS << ' ' << printVRegOrUnit(Reg, TRI) << ':'
Stanislav Mekhanoshinacca0f52017-05-16 16:31:45 +0000503 << PrintLaneMask(It->second);
504 }
505 OS << '\n';
506}
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000507#endif