blob: 39460fbd8a84d63fa1259aa040b12fa5fb7877f5 [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) :
Stanislav Mekhanoshine67cc382019-07-11 21:19:33 +000092 STI->hasAGPRs(RC) ?
93 (STI->getRegSizeInBits(*RC) == 32 ? AGPR32 : AGPR_TUPLE) :
94 (STI->getRegSizeInBits(*RC) == 32 ? VGPR32 : VGPR_TUPLE);
Valery Pykhtinfd4c4102017-03-21 13:15:46 +000095}
96
97void GCNRegPressure::inc(unsigned Reg,
98 LaneBitmask PrevMask,
99 LaneBitmask NewMask,
100 const MachineRegisterInfo &MRI) {
101 if (NewMask == PrevMask)
102 return;
103
104 int Sign = 1;
105 if (NewMask < PrevMask) {
106 std::swap(NewMask, PrevMask);
107 Sign = -1;
108 }
109#ifndef NDEBUG
110 const auto MaxMask = MRI.getMaxLaneMaskForVReg(Reg);
111#endif
112 switch (auto Kind = getRegKind(Reg, MRI)) {
113 case SGPR32:
114 case VGPR32:
Stanislav Mekhanoshine67cc382019-07-11 21:19:33 +0000115 case AGPR32:
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000116 assert(PrevMask.none() && NewMask == MaxMask);
117 Value[Kind] += Sign;
118 break;
119
120 case SGPR_TUPLE:
121 case VGPR_TUPLE:
Stanislav Mekhanoshine67cc382019-07-11 21:19:33 +0000122 case AGPR_TUPLE:
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000123 assert(NewMask < MaxMask || NewMask == MaxMask);
124 assert(PrevMask < NewMask);
125
Stanislav Mekhanoshine67cc382019-07-11 21:19:33 +0000126 Value[Kind == SGPR_TUPLE ? SGPR32 : Kind == AGPR_TUPLE ? AGPR32 : VGPR32] +=
Krzysztof Parzyszekf3a778d2017-07-20 19:43:19 +0000127 Sign * (~PrevMask & NewMask).getNumLanes();
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000128
129 if (PrevMask.none()) {
130 assert(NewMask.any());
131 Value[Kind] += Sign * MRI.getPressureSets(Reg).getWeight();
132 }
133 break;
134
135 default: llvm_unreachable("Unknown register kind");
136 }
137}
138
Tom Stellard5bfbae52018-07-11 20:59:01 +0000139bool GCNRegPressure::less(const GCNSubtarget &ST,
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000140 const GCNRegPressure& O,
141 unsigned MaxOccupancy) const {
142 const auto SGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000143 ST.getOccupancyWithNumSGPRs(getSGPRNum()));
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000144 const auto VGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000145 ST.getOccupancyWithNumVGPRs(getVGPRNum()));
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000146 const auto OtherSGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000147 ST.getOccupancyWithNumSGPRs(O.getSGPRNum()));
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000148 const auto OtherVGPROcc = std::min(MaxOccupancy,
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000149 ST.getOccupancyWithNumVGPRs(O.getVGPRNum()));
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000150
151 const auto Occ = std::min(SGPROcc, VGPROcc);
152 const auto OtherOcc = std::min(OtherSGPROcc, OtherVGPROcc);
153 if (Occ != OtherOcc)
154 return Occ > OtherOcc;
155
156 bool SGPRImportant = SGPROcc < VGPROcc;
157 const bool OtherSGPRImportant = OtherSGPROcc < OtherVGPROcc;
158
159 // if both pressures disagree on what is more important compare vgprs
160 if (SGPRImportant != OtherSGPRImportant) {
161 SGPRImportant = false;
162 }
163
164 // compare large regs pressure
165 bool SGPRFirst = SGPRImportant;
166 for (int I = 2; I > 0; --I, SGPRFirst = !SGPRFirst) {
167 if (SGPRFirst) {
168 auto SW = getSGPRTuplesWeight();
169 auto OtherSW = O.getSGPRTuplesWeight();
170 if (SW != OtherSW)
171 return SW < OtherSW;
172 } else {
173 auto VW = getVGPRTuplesWeight();
174 auto OtherVW = O.getVGPRTuplesWeight();
175 if (VW != OtherVW)
176 return VW < OtherVW;
177 }
178 }
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000179 return SGPRImportant ? (getSGPRNum() < O.getSGPRNum()):
180 (getVGPRNum() < O.getVGPRNum());
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000181}
182
Aaron Ballman615eb472017-10-15 14:32:27 +0000183#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000184LLVM_DUMP_METHOD
Tom Stellard5bfbae52018-07-11 20:59:01 +0000185void GCNRegPressure::print(raw_ostream &OS, const GCNSubtarget *ST) const {
Stanislav Mekhanoshin7e3794d2017-05-09 20:50:04 +0000186 OS << "VGPRs: " << getVGPRNum();
187 if (ST) OS << "(O" << ST->getOccupancyWithNumVGPRs(getVGPRNum()) << ')';
188 OS << ", SGPRs: " << getSGPRNum();
189 if (ST) OS << "(O" << ST->getOccupancyWithNumSGPRs(getSGPRNum()) << ')';
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000190 OS << ", LVGPR WT: " << getVGPRTuplesWeight()
191 << ", LSGPR WT: " << getSGPRTuplesWeight();
192 if (ST) OS << " -> Occ: " << getOccupancy(*ST);
193 OS << '\n';
194}
195#endif
196
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000197static LaneBitmask getDefRegMask(const MachineOperand &MO,
198 const MachineRegisterInfo &MRI) {
199 assert(MO.isDef() && MO.isReg() &&
200 TargetRegisterInfo::isVirtualRegister(MO.getReg()));
201
202 // We don't rely on read-undef flag because in case of tentative schedule
203 // tracking it isn't set correctly yet. This works correctly however since
204 // use mask has been tracked before using LIS.
205 return MO.getSubReg() == 0 ?
206 MRI.getMaxLaneMaskForVReg(MO.getReg()) :
207 MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(MO.getSubReg());
208}
209
210static LaneBitmask getUsedRegMask(const MachineOperand &MO,
211 const MachineRegisterInfo &MRI,
212 const LiveIntervals &LIS) {
213 assert(MO.isUse() && MO.isReg() &&
214 TargetRegisterInfo::isVirtualRegister(MO.getReg()));
215
216 if (auto SubReg = MO.getSubReg())
217 return MRI.getTargetRegisterInfo()->getSubRegIndexLaneMask(SubReg);
218
219 auto MaxMask = MRI.getMaxLaneMaskForVReg(MO.getReg());
Krzysztof Parzyszeke9f0c1e2017-07-20 19:15:56 +0000220 if (MaxMask == LaneBitmask::getLane(0)) // cannot have subregs
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000221 return MaxMask;
222
223 // For a tentative schedule LIS isn't updated yet but livemask should remain
224 // the same on any schedule. Subreg defs can be reordered but they all must
225 // dominate uses anyway.
226 auto SI = LIS.getInstructionIndex(*MO.getParent()).getBaseIndex();
227 return getLiveLaneMask(MO.getReg(), SI, LIS, MRI);
228}
229
Benjamin Kramerdebb3c32017-05-26 20:09:00 +0000230static SmallVector<RegisterMaskPair, 8>
231collectVirtualRegUses(const MachineInstr &MI, const LiveIntervals &LIS,
232 const MachineRegisterInfo &MRI) {
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000233 SmallVector<RegisterMaskPair, 8> Res;
234 for (const auto &MO : MI.operands()) {
235 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()))
236 continue;
237 if (!MO.isUse() || !MO.readsReg())
238 continue;
239
240 auto const UsedMask = getUsedRegMask(MO, MRI, LIS);
241
242 auto Reg = MO.getReg();
243 auto I = std::find_if(Res.begin(), Res.end(), [Reg](const RegisterMaskPair &RM) {
244 return RM.RegUnit == Reg;
245 });
246 if (I != Res.end())
247 I->LaneMask |= UsedMask;
248 else
249 Res.push_back(RegisterMaskPair(Reg, UsedMask));
250 }
251 return Res;
252}
253
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000254///////////////////////////////////////////////////////////////////////////////
255// GCNRPTracker
256
257LaneBitmask llvm::getLiveLaneMask(unsigned Reg,
258 SlotIndex SI,
259 const LiveIntervals &LIS,
260 const MachineRegisterInfo &MRI) {
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000261 LaneBitmask LiveMask;
262 const auto &LI = LIS.getInterval(Reg);
263 if (LI.hasSubRanges()) {
264 for (const auto &S : LI.subranges())
265 if (S.liveAt(SI)) {
266 LiveMask |= S.LaneMask;
267 assert(LiveMask < MRI.getMaxLaneMaskForVReg(Reg) ||
268 LiveMask == MRI.getMaxLaneMaskForVReg(Reg));
269 }
270 } else if (LI.liveAt(SI)) {
271 LiveMask = MRI.getMaxLaneMaskForVReg(Reg);
272 }
273 return LiveMask;
274}
275
276GCNRPTracker::LiveRegSet llvm::getLiveRegs(SlotIndex SI,
277 const LiveIntervals &LIS,
278 const MachineRegisterInfo &MRI) {
279 GCNRPTracker::LiveRegSet LiveRegs;
280 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
281 auto Reg = TargetRegisterInfo::index2VirtReg(I);
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000282 if (!LIS.hasInterval(Reg))
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000283 continue;
284 auto LiveMask = getLiveLaneMask(Reg, SI, LIS, MRI);
285 if (LiveMask.any())
286 LiveRegs[Reg] = LiveMask;
287 }
288 return LiveRegs;
289}
290
Stanislav Mekhanoshin28624f92018-06-04 17:21:54 +0000291void GCNRPTracker::reset(const MachineInstr &MI,
292 const LiveRegSet *LiveRegsCopy,
293 bool After) {
294 const MachineFunction &MF = *MI.getMF();
295 MRI = &MF.getRegInfo();
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000296 if (LiveRegsCopy) {
297 if (&LiveRegs != LiveRegsCopy)
298 LiveRegs = *LiveRegsCopy;
299 } else {
Stanislav Mekhanoshin28624f92018-06-04 17:21:54 +0000300 LiveRegs = After ? getLiveRegsAfter(MI, LIS)
301 : getLiveRegsBefore(MI, LIS);
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000302 }
Stanislav Mekhanoshin28624f92018-06-04 17:21:54 +0000303
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000304 MaxPressure = CurPressure = getRegPressure(*MRI, LiveRegs);
305}
306
Stanislav Mekhanoshin28624f92018-06-04 17:21:54 +0000307void GCNUpwardRPTracker::reset(const MachineInstr &MI,
308 const LiveRegSet *LiveRegsCopy) {
309 GCNRPTracker::reset(MI, LiveRegsCopy, true);
310}
311
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000312void GCNUpwardRPTracker::recede(const MachineInstr &MI) {
313 assert(MRI && "call reset first");
314
315 LastTrackedMI = &MI;
316
Shiva Chen801bf7e2018-05-09 02:42:00 +0000317 if (MI.isDebugInstr())
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000318 return;
319
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000320 auto const RegUses = collectVirtualRegUses(MI, LIS, *MRI);
321
322 // calc pressure at the MI (defs + uses)
323 auto AtMIPressure = CurPressure;
324 for (const auto &U : RegUses) {
325 auto LiveMask = LiveRegs[U.RegUnit];
326 AtMIPressure.inc(U.RegUnit, LiveMask, LiveMask | U.LaneMask, *MRI);
327 }
328 // update max pressure
329 MaxPressure = max(AtMIPressure, MaxPressure);
330
331 for (const auto &MO : MI.defs()) {
332 if (!MO.isReg() || !TargetRegisterInfo::isVirtualRegister(MO.getReg()) ||
333 MO.isDead())
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000334 continue;
335
336 auto Reg = MO.getReg();
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000337 auto I = LiveRegs.find(Reg);
338 if (I == LiveRegs.end())
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000339 continue;
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000340 auto &LiveMask = I->second;
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000341 auto PrevMask = LiveMask;
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000342 LiveMask &= ~getDefRegMask(MO, *MRI);
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000343 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000344 if (LiveMask.none())
345 LiveRegs.erase(I);
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000346 }
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000347 for (const auto &U : RegUses) {
348 auto &LiveMask = LiveRegs[U.RegUnit];
349 auto PrevMask = LiveMask;
350 LiveMask |= U.LaneMask;
351 CurPressure.inc(U.RegUnit, PrevMask, LiveMask, *MRI);
352 }
353 assert(CurPressure == getRegPressure(*MRI, LiveRegs));
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000354}
355
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000356bool GCNDownwardRPTracker::reset(const MachineInstr &MI,
357 const LiveRegSet *LiveRegsCopy) {
358 MRI = &MI.getParent()->getParent()->getRegInfo();
359 LastTrackedMI = nullptr;
360 MBBEnd = MI.getParent()->end();
361 NextMI = &MI;
362 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
363 if (NextMI == MBBEnd)
364 return false;
Stanislav Mekhanoshin28624f92018-06-04 17:21:54 +0000365 GCNRPTracker::reset(*NextMI, LiveRegsCopy, false);
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000366 return true;
367}
368
369bool GCNDownwardRPTracker::advanceBeforeNext() {
370 assert(MRI && "call reset first");
371
372 NextMI = skipDebugInstructionsForward(NextMI, MBBEnd);
373 if (NextMI == MBBEnd)
374 return false;
375
376 SlotIndex SI = LIS.getInstructionIndex(*NextMI).getBaseIndex();
377 assert(SI.isValid());
378
379 // Remove dead registers or mask bits.
380 for (auto &It : LiveRegs) {
381 const LiveInterval &LI = LIS.getInterval(It.first);
382 if (LI.hasSubRanges()) {
383 for (const auto &S : LI.subranges()) {
384 if (!S.liveAt(SI)) {
385 auto PrevMask = It.second;
386 It.second &= ~S.LaneMask;
387 CurPressure.inc(It.first, PrevMask, It.second, *MRI);
388 }
389 }
390 } else if (!LI.liveAt(SI)) {
391 auto PrevMask = It.second;
392 It.second = LaneBitmask::getNone();
393 CurPressure.inc(It.first, PrevMask, It.second, *MRI);
394 }
395 if (It.second.none())
396 LiveRegs.erase(It.first);
397 }
398
399 MaxPressure = max(MaxPressure, CurPressure);
400
401 return true;
402}
403
404void GCNDownwardRPTracker::advanceToNext() {
405 LastTrackedMI = &*NextMI++;
406
407 // Add new registers or mask bits.
408 for (const auto &MO : LastTrackedMI->defs()) {
409 if (!MO.isReg())
410 continue;
411 unsigned Reg = MO.getReg();
412 if (!TargetRegisterInfo::isVirtualRegister(Reg))
413 continue;
414 auto &LiveMask = LiveRegs[Reg];
415 auto PrevMask = LiveMask;
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000416 LiveMask |= getDefRegMask(MO, *MRI);
Stanislav Mekhanoshin464cecf2017-05-16 15:43:52 +0000417 CurPressure.inc(Reg, PrevMask, LiveMask, *MRI);
418 }
419
420 MaxPressure = max(MaxPressure, CurPressure);
421}
422
423bool GCNDownwardRPTracker::advance() {
424 // If we have just called reset live set is actual.
425 if ((NextMI == MBBEnd) || (LastTrackedMI && !advanceBeforeNext()))
426 return false;
427 advanceToNext();
428 return true;
429}
430
431bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator End) {
432 while (NextMI != End)
433 if (!advance()) return false;
434 return true;
435}
436
437bool GCNDownwardRPTracker::advance(MachineBasicBlock::const_iterator Begin,
438 MachineBasicBlock::const_iterator End,
439 const LiveRegSet *LiveRegsCopy) {
440 reset(*Begin, LiveRegsCopy);
441 return advance(End);
442}
443
Aaron Ballman615eb472017-10-15 14:32:27 +0000444#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000445LLVM_DUMP_METHOD
446static 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()) {
Francis Visoiu Mistrih9d419d32017-11-28 12:42:37 +0000452 dbgs() << " " << printReg(P.first, TRI)
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000453 << ":L" << PrintLaneMask(P.second)
454 << " isn't found in LIS reported set\n";
455 }
456 else if (I->second != P.second) {
Francis Visoiu Mistrih9d419d32017-11-28 12:42:37 +0000457 dbgs() << " " << printReg(P.first, TRI)
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000458 << " 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()) {
Francis Visoiu Mistrih9d419d32017-11-28 12:42:37 +0000468 dbgs() << " " << printReg(P.first, TRI)
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000469 << ":L" << PrintLaneMask(P.second)
470 << " isn't found in tracked set\n";
471 }
472 }
473}
474
475bool GCNUpwardRPTracker::isValid() const {
476 const auto &SI = LIS.getInstructionIndex(*LastTrackedMI).getBaseIndex();
477 const auto LISLR = llvm::getLiveRegs(SI, LIS, *MRI);
Valery Pykhtin74cb9c82017-05-22 13:09:40 +0000478 const auto &TrackedLR = LiveRegs;
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000479
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
Stanislav Mekhanoshinacca0f52017-05-16 16:31:45 +0000499void 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())
Francis Visoiu Mistrih9d419d32017-11-28 12:42:37 +0000506 OS << ' ' << printVRegOrUnit(Reg, TRI) << ':'
Stanislav Mekhanoshinacca0f52017-05-16 16:31:45 +0000507 << PrintLaneMask(It->second);
508 }
509 OS << '\n';
510}
Valery Pykhtinfd4c4102017-03-21 13:15:46 +0000511#endif