LLVM 22.0.0git
AMDGPURewriteAGPRCopyMFMA.cpp
Go to the documentation of this file.
1//===-- AMDGPURewriteAGPRCopyMFMA.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/// \file \brief Try to replace MFMA instructions using VGPRs with MFMA
10/// instructions using AGPRs. We expect MFMAs to be selected using VGPRs, and
11/// only use AGPRs if it helps avoid spilling. In this case, the MFMA will have
12/// copies between AGPRs and VGPRs and the AGPR variant of an MFMA pseudo. This
13/// pass will attempt to delete the cross register bank copy and replace the
14/// MFMA opcode.
15///
16/// TODO:
17/// - Handle rewrites of phis. This must be more careful than normal about the
18/// reassignment. We do not want to introduce an AGPR-to-AGPR copy inside of a
19/// loop, so it depends on the exact assignment of the copy.
20///
21/// - Update LiveIntervals incrementally instead of recomputing from scratch
22///
23//===----------------------------------------------------------------------===//
24
25#include "AMDGPU.h"
26#include "GCNSubtarget.h"
28#include "SIRegisterInfo.h"
29#include "llvm/ADT/Statistic.h"
35
36using namespace llvm;
37
38#define DEBUG_TYPE "amdgpu-rewrite-agpr-copy-mfma"
39
40namespace {
41
42STATISTIC(NumMFMAsRewrittenToAGPR,
43 "Number of MFMA instructions rewritten to use AGPR form");
44
45class AMDGPURewriteAGPRCopyMFMAImpl {
47 const GCNSubtarget &ST;
48 const SIInstrInfo &TII;
49 const SIRegisterInfo &TRI;
51 VirtRegMap &VRM;
52 LiveRegMatrix ‎
53 LiveIntervals &LIS;
54 const RegisterClassInfo &RegClassInfo;
55
56 bool attemptReassignmentsToAGPR(SmallSetVector<Register, 4> &InterferingRegs,
57 MCPhysReg PrefPhysReg) const;
58
59public:
60 AMDGPURewriteAGPRCopyMFMAImpl(MachineFunction &MF, VirtRegMap &VRM,
62 const RegisterClassInfo &RegClassInfo)
63 : MF(MF), ST(MF.getSubtarget<GCNSubtarget>()), TII(*ST.getInstrInfo()),
64 TRI(*ST.getRegisterInfo()), MRI(MF.getRegInfo()), VRM(VRM), LRM(LRM),
65 LIS(LIS), RegClassInfo(RegClassInfo) {}
66
67 bool isRewriteCandidate(const MachineInstr &MI) const {
68 return TII.isMAI(MI) && AMDGPU::getMFMASrcCVDstAGPROp(MI.getOpcode()) != -1;
69 }
70
71 /// Find AV_* registers assigned to AGPRs (or virtual registers which were
72 /// already required to be AGPR).
73 ///
74 /// \return the assigned physical register that \p VReg is assigned to if it
75 /// is an AGPR, otherwise MCRegister().
76 MCRegister getAssignedAGPR(Register VReg) const {
77 MCRegister PhysReg = VRM.getPhys(VReg);
78 if (!PhysReg)
79 return MCRegister();
80
81 // If this is an AV register, we have to check if the actual assignment is
82 // to an AGPR
83 const TargetRegisterClass *AssignedRC = TRI.getPhysRegBaseClass(PhysReg);
84 return TRI.isAGPRClass(AssignedRC) ? PhysReg : MCRegister();
85 }
86
87 bool tryReassigningMFMAChain(MachineInstr &MFMA, Register MFMAHintReg,
88 MCPhysReg PhysRegHint) const;
89
90 /// Compute the register class constraints based on the uses of \p Reg,
91 /// excluding MFMA uses from which can be rewritten to change the register
92 /// class constraint. This should be nearly identical to
93 /// MachineRegisterInfo::recomputeRegClass.
94
95 /// \p RewriteCandidates will collect the set of MFMA instructions that need
96 /// to have the opcode mutated to perform the replacement.
97 ///
98 /// \p RewriteRegs will accumulate the set of register used by those MFMAs
99 /// that need to have the register classes adjusted.
100 bool recomputeRegClassExceptRewritable(
101 Register Reg, SmallVectorImpl<MachineInstr *> &RewriteCandidates,
102 SmallSetVector<Register, 4> &RewriteRegs) const;
103
104 bool tryFoldCopiesToAGPR(Register VReg, MCRegister AssignedAGPR) const;
105 bool tryFoldCopiesFromAGPR(Register VReg, MCRegister AssignedAGPR) const;
106 bool run(MachineFunction &MF) const;
107};
108
109bool AMDGPURewriteAGPRCopyMFMAImpl::recomputeRegClassExceptRewritable(
110 Register StartReg, SmallVectorImpl<MachineInstr *> &RewriteCandidates,
111 SmallSetVector<Register, 4> &RewriteRegs) const {
112 SmallVector<Register, 8> Worklist = {StartReg};
113
114 // Recursively visit all transitive MFMA users
115 while (!Worklist.empty()) {
116 Register Reg = Worklist.pop_back_val();
117 const TargetRegisterClass *OldRC = MRI.getRegClass(Reg);
118
119 // Inflate to the equivalent AV_* class.
120 const TargetRegisterClass *NewRC = TRI.getLargestLegalSuperClass(OldRC, MF);
121 if (OldRC == NewRC)
122 return false;
123
124 // Accumulate constraints from all uses.
125 for (MachineOperand &MO : MRI.reg_nodbg_operands(Reg)) {
126 // Apply the effect of the given operand to NewRC.
127 MachineInstr *MI = MO.getParent();
128
129 // We can swap the classes of dst + src2 as a pair to AGPR, so ignore the
130 // effects of rewrite candidates. It just so happens that we can use
131 // either AGPR or VGPR in src0/src1, so don't bother checking the
132 // constraint effects of the individual operands.
133 if (isRewriteCandidate(*MI)) {
134 const MachineOperand *VDst =
135 TII.getNamedOperand(*MI, AMDGPU::OpName::vdst);
136 const MachineOperand *Src2 =
137 TII.getNamedOperand(*MI, AMDGPU::OpName::src2);
138 for (const MachineOperand *Op : {VDst, Src2}) {
139 if (!Op->isReg())
140 continue;
141
142 Register OtherReg = Op->getReg();
143 if (OtherReg.isPhysical())
144 return false;
145
146 if (OtherReg != Reg && RewriteRegs.insert(OtherReg))
147 Worklist.push_back(OtherReg);
148 }
149
150 if (!is_contained(RewriteCandidates, MI)) {
151 LLVM_DEBUG({
152 Register VDstPhysReg = VRM.getPhys(VDst->getReg());
153 dbgs() << "Attempting to replace VGPR MFMA with AGPR version:"
154 << " Dst=[" << printReg(VDst->getReg()) << " => "
155 << printReg(VDstPhysReg, &TRI);
156
157 if (Src2->isReg()) {
158 Register Src2PhysReg = VRM.getPhys(Src2->getReg());
159 dbgs() << "], Src2=[" << printReg(Src2->getReg(), &TRI) << " => "
160 << printReg(Src2PhysReg, &TRI);
161 }
162
163 dbgs() << "]: " << MI;
164 });
165
166 RewriteCandidates.push_back(MI);
167 }
168
169 continue;
170 }
171
172 unsigned OpNo = &MO - &MI->getOperand(0);
173 NewRC = MI->getRegClassConstraintEffect(OpNo, NewRC, &TII, &TRI);
174 if (!NewRC || NewRC == OldRC) {
175 LLVM_DEBUG(dbgs() << "User of " << printReg(Reg, &TRI)
176 << " cannot be reassigned to "
177 << TRI.getRegClassName(NewRC) << ": " << *MI);
178 return false;
179 }
180 }
181 }
182
183 return true;
184}
185
186bool AMDGPURewriteAGPRCopyMFMAImpl::tryReassigningMFMAChain(
187 MachineInstr &MFMA, Register MFMAHintReg, MCPhysReg PhysRegHint) const {
188 // src2 and dst have the same physical class constraint; try to preserve
189 // the original src2 subclass if one were to exist.
190 SmallVector<MachineInstr *, 4> RewriteCandidates = {&MFMA};
191 SmallSetVector<Register, 4> RewriteRegs;
192
193 // Make sure we reassign the MFMA we found the copy from first. We want
194 // to ensure dst ends up in the physreg we were originally copying to.
195 RewriteRegs.insert(MFMAHintReg);
196
197 // We've found av = COPY (MFMA) (or MFMA (v = COPY av)) and need to verify
198 // that we can trivially rewrite src2 to use the new AGPR. If we can't
199 // trivially replace it, we're going to induce as many copies as we would have
200 // emitted in the first place, as well as need to assign another register, and
201 // need to figure out where to put them. The live range splitting is smarter
202 // than anything we're doing here, so trust it did something reasonable.
203 //
204 // Note recomputeRegClassExceptRewritable will consider the constraints of
205 // this MFMA's src2 as well as the src2/dst of any transitive MFMA users.
206 if (!recomputeRegClassExceptRewritable(MFMAHintReg, RewriteCandidates,
207 RewriteRegs)) {
208 LLVM_DEBUG(dbgs() << "Could not recompute the regclass of dst reg "
209 << printReg(MFMAHintReg, &TRI) << '\n');
210 return false;
211 }
212
213 // If src2 and dst are different registers, we need to also reassign the
214 // input to an available AGPR if it is compatible with all other uses.
215 //
216 // If we can't reassign it, we'd need to introduce a different copy
217 // which is likely worse than the copy we'd be saving.
218 //
219 // It's likely that the MFMA is used in sequence with other MFMAs; if we
220 // cannot migrate the full use/def chain of MFMAs, we would need to
221 // introduce intermediate copies somewhere. So we only make the
222 // transform if all the interfering MFMAs can also be migrated. Collect
223 // the set of rewritable MFMAs and check if we can assign an AGPR at
224 // that point.
225 //
226 // If any of the MFMAs aren't reassignable, we give up and rollback to
227 // the original register assignments.
228
229 using RecoloringStack =
231 RecoloringStack TentativeReassignments;
232
233 for (Register RewriteReg : RewriteRegs) {
234 LiveInterval &LI = LIS.getInterval(RewriteReg);
235 TentativeReassignments.push_back({&LI, VRM.getPhys(RewriteReg)});
236 LRM.unassign(LI);
237 }
238
239 if (!attemptReassignmentsToAGPR(RewriteRegs, PhysRegHint)) {
240 // Roll back the register assignments to the original state.
241 for (auto [LI, OldAssign] : TentativeReassignments) {
242 if (VRM.hasPhys(LI->reg()))
243 LRM.unassign(*LI);
244 LRM.assign(*LI, OldAssign);
245 }
246
247 return false;
248 }
249
250 // Fixup the register classes of the virtual registers now that we've
251 // committed to the reassignments.
252 for (Register InterferingReg : RewriteRegs) {
253 const TargetRegisterClass *EquivalentAGPRRegClass =
254 TRI.getEquivalentAGPRClass(MRI.getRegClass(InterferingReg));
255 MRI.setRegClass(InterferingReg, EquivalentAGPRRegClass);
256 }
257
258 for (MachineInstr *RewriteCandidate : RewriteCandidates) {
259 int NewMFMAOp =
260 AMDGPU::getMFMASrcCVDstAGPROp(RewriteCandidate->getOpcode());
261 RewriteCandidate->setDesc(TII.get(NewMFMAOp));
262 ++NumMFMAsRewrittenToAGPR;
263 }
264
265 return true;
266}
267
268/// Attempt to reassign the registers in \p InterferingRegs to be AGPRs, with a
269/// preference to use \p PhysReg first. Returns false if the reassignments
270/// cannot be trivially performed.
271bool AMDGPURewriteAGPRCopyMFMAImpl::attemptReassignmentsToAGPR(
272 SmallSetVector<Register, 4> &InterferingRegs, MCPhysReg PrefPhysReg) const {
273 // FIXME: The ordering may matter here, but we're just taking uselistorder
274 // with the special case of ensuring to process the starting instruction
275 // first. We probably should extract the priority advisor out of greedy and
276 // use that ordering.
277 for (Register InterferingReg : InterferingRegs) {
278 LiveInterval &ReassignLI = LIS.getInterval(InterferingReg);
279 const TargetRegisterClass *EquivalentAGPRRegClass =
280 TRI.getEquivalentAGPRClass(MRI.getRegClass(InterferingReg));
281
282 MCPhysReg Assignable = AMDGPU::NoRegister;
283 if (EquivalentAGPRRegClass->contains(PrefPhysReg) &&
284 LRM.checkInterference(ReassignLI, PrefPhysReg) ==
286 // First try to assign to the AGPR we were already copying to. This
287 // should be the first assignment we attempt. We have to guard
288 // against the use being a subregister (which doesn't have an exact
289 // class match).
290
291 // TODO: If this does happen to be a subregister use, we should
292 // still try to assign to a subregister of the original copy result.
293 Assignable = PrefPhysReg;
294 } else {
295 ArrayRef<MCPhysReg> AllocOrder =
296 RegClassInfo.getOrder(EquivalentAGPRRegClass);
297 for (MCPhysReg Reg : AllocOrder) {
298 if (LRM.checkInterference(ReassignLI, Reg) == LiveRegMatrix::IK_Free) {
299 Assignable = Reg;
300 break;
301 }
302 }
303 }
304
305 if (!Assignable) {
306 LLVM_DEBUG(dbgs() << "Unable to reassign VGPR "
307 << printReg(InterferingReg, &TRI)
308 << " to a free AGPR\n");
309 return false;
310 }
311
312 LLVM_DEBUG(dbgs() << "Reassigning VGPR " << printReg(InterferingReg, &TRI)
313 << " to " << printReg(Assignable, &TRI) << '\n');
314 LRM.assign(ReassignLI, Assignable);
315 }
316
317 return true;
318}
319
320/// Identify copies that look like:
321/// %vdst:vgpr = V_MFMA_.. %src0:av, %src1:av, %src2:vgpr
322/// %agpr = COPY %vgpr
323///
324/// Then try to replace the transitive uses of %src2 and %vdst with the AGPR
325/// versions of the MFMA. This should cover the common case.
326bool AMDGPURewriteAGPRCopyMFMAImpl::tryFoldCopiesToAGPR(
327 Register VReg, MCRegister AssignedAGPR) const {
328 bool MadeChange = false;
329 for (MachineInstr &UseMI : MRI.def_instructions(VReg)) {
330 if (!UseMI.isCopy())
331 continue;
332
333 Register CopySrcReg = UseMI.getOperand(1).getReg();
334 if (!CopySrcReg.isVirtual())
335 continue;
336
337 // TODO: Handle loop phis copied to AGPR. e.g.
338 //
339 // loop:
340 // %phi:vgpr = COPY %mfma:vgpr
341 // %mfma:vgpr = V_MFMA_xxx_vgprcd_e64 %a, %b, %phi
342 // s_cbranch_vccnz loop
343 //
344 // endloop:
345 // %agpr = mfma
346 //
347 // We need to be sure that %phi is assigned to the same physical register as
348 // %mfma, or else we will just be moving copies into the loop.
349
350 for (MachineInstr &CopySrcDefMI : MRI.def_instructions(CopySrcReg)) {
351 if (isRewriteCandidate(CopySrcDefMI) &&
352 tryReassigningMFMAChain(
353 CopySrcDefMI, CopySrcDefMI.getOperand(0).getReg(), AssignedAGPR))
354 MadeChange = true;
355 }
356 }
357
358 return MadeChange;
359}
360
361/// Identify copies that look like:
362/// %src:vgpr = COPY %src:agpr
363/// %vdst:vgpr = V_MFMA_... %src0:av, %src1:av, %src:vgpr
364///
365/// Then try to replace the transitive uses of %src2 and %vdst with the AGPR
366/// versions of the MFMA. This should cover rarer cases, and will generally be
367/// redundant with tryFoldCopiesToAGPR.
368bool AMDGPURewriteAGPRCopyMFMAImpl::tryFoldCopiesFromAGPR(
369 Register VReg, MCRegister AssignedAGPR) const {
370 bool MadeChange = false;
371 for (MachineInstr &UseMI : MRI.use_instructions(VReg)) {
372 if (!UseMI.isCopy())
373 continue;
374
375 Register CopyDstReg = UseMI.getOperand(0).getReg();
376 if (!CopyDstReg.isVirtual())
377 continue;
378 for (MachineOperand &CopyUseMO : MRI.reg_nodbg_operands(CopyDstReg)) {
379 if (!CopyUseMO.readsReg())
380 continue;
381
382 MachineInstr &CopyUseMI = *CopyUseMO.getParent();
383 if (isRewriteCandidate(CopyUseMI)) {
384 if (tryReassigningMFMAChain(CopyUseMI, CopyDstReg,
385 VRM.getPhys(CopyDstReg)))
386 MadeChange = true;
387 }
388 }
389 }
390
391 return MadeChange;
392}
393
394bool AMDGPURewriteAGPRCopyMFMAImpl::run(MachineFunction &MF) const {
395 // This only applies on subtargets that have a configurable AGPR vs. VGPR
396 // allocation.
397 if (!ST.hasGFX90AInsts())
398 return false;
399
400 // Early exit if no AGPRs were assigned.
401 if (!LRM.isPhysRegUsed(AMDGPU::AGPR0)) {
402 LLVM_DEBUG(dbgs() << "skipping function that did not allocate AGPRs\n");
403 return false;
404 }
405
406 bool MadeChange = false;
407
408 for (unsigned I = 0, E = MRI.getNumVirtRegs(); I != E; ++I) {
410 MCRegister AssignedAGPR = getAssignedAGPR(VReg);
411 if (!AssignedAGPR)
412 continue;
413
414 if (tryFoldCopiesToAGPR(VReg, AssignedAGPR))
415 MadeChange = true;
416 if (tryFoldCopiesFromAGPR(VReg, AssignedAGPR))
417 MadeChange = true;
418 }
419
420 return MadeChange;
421}
422
423class AMDGPURewriteAGPRCopyMFMALegacy : public MachineFunctionPass {
424public:
425 static char ID;
426 RegisterClassInfo RegClassInfo;
427
428 AMDGPURewriteAGPRCopyMFMALegacy() : MachineFunctionPass(ID) {
431 }
432
433 bool runOnMachineFunction(MachineFunction &MF) override;
434
435 StringRef getPassName() const override {
436 return "AMDGPU Rewrite AGPR-Copy-MFMA";
437 }
438
439 void getAnalysisUsage(AnalysisUsage &AU) const override {
443
447 AU.setPreservesAll();
449 }
450};
451
452} // End anonymous namespace.
453
454INITIALIZE_PASS_BEGIN(AMDGPURewriteAGPRCopyMFMALegacy, DEBUG_TYPE,
455 "AMDGPU Rewrite AGPR-Copy-MFMA", false, false)
459INITIALIZE_PASS_END(AMDGPURewriteAGPRCopyMFMALegacy, DEBUG_TYPE,
460 "AMDGPU Rewrite AGPR-Copy-MFMA", false, false)
461
462char AMDGPURewriteAGPRCopyMFMALegacy::ID = 0;
463
465 AMDGPURewriteAGPRCopyMFMALegacy::ID;
466
467bool AMDGPURewriteAGPRCopyMFMALegacy::runOnMachineFunction(
468 MachineFunction &MF) {
469 if (skipFunction(MF.getFunction()))
470 return false;
471
472 RegClassInfo.runOnMachineFunction(MF);
473
474 auto &VRM = getAnalysis<VirtRegMapWrapperLegacy>().getVRM();
475 auto &LRM = getAnalysis<LiveRegMatrixWrapperLegacy>().getLRM();
476 auto &LIS = getAnalysis<LiveIntervalsWrapperPass>().getLIS();
477
478 AMDGPURewriteAGPRCopyMFMAImpl Impl(MF, VRM, LRM, LIS, RegClassInfo);
479 return Impl.run(MF);
480}
481
485 VirtRegMap &VRM = MFAM.getResult<VirtRegMapAnalysis>(MF);
488 RegisterClassInfo RegClassInfo;
489 RegClassInfo.runOnMachineFunction(MF);
490
491 AMDGPURewriteAGPRCopyMFMAImpl Impl(MF, VRM, LRM, LIS, RegClassInfo);
492 if (!Impl.run(MF))
493 return PreservedAnalyses::all();
495 PA.preserveSet<CFGAnalyses>();
496 return PA;
497}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
AMDGPU Rewrite AGPR Copy MFMA
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
AMD GCN specific subclass of TargetSubtarget.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:58
Register Reg
Register const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
Interface definition for SIRegisterInfo.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:167
#define LLVM_DEBUG(...)
Definition Debug.h:114
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
bool hasGFX90AInsts() const
LiveInterval - This class represents the liveness of a register, or stack slot.
LiveInterval & getInterval(Register Reg)
void unassign(const LiveInterval &VirtReg)
Unassign VirtReg from its PhysReg.
bool isPhysRegUsed(MCRegister PhysReg) const
Returns true if the given PhysReg has any live intervals assigned.
@ IK_Free
No interference, go ahead and assign.
void assign(const LiveInterval &VirtReg, MCRegister PhysReg)
Assign VirtReg to PhysReg.
InterferenceKind checkInterference(const LiveInterval &VirtReg, MCRegister PhysReg)
Check for interference before assigning VirtReg to PhysReg.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:33
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
LLVM_ABI void runOnMachineFunction(const MachineFunction &MF, bool Rev=false)
runOnFunction - Prepare to answer questions about MF.
ArrayRef< MCPhysReg > getOrder(const TargetRegisterClass *RC) const
getOrder - Returns the preferred allocation order for RC.
Wrapper class representing virtual and physical registers.
Definition Register.h:19
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition Register.h:67
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:74
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:78
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:168
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:356
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
bool contains(Register Reg) const
Return true if the specified register is included in this register class.
MCRegister getPhys(Register virtReg) const
returns the physical register mapped to the specified virtual register
Definition VirtRegMap.h:91
bool hasPhys(Register virtReg) const
returns true if the specified virtual register is mapped to a physical register
Definition VirtRegMap.h:87
LLVM_READONLY int getMFMASrcCVDstAGPROp(uint16_t Opcode)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
void initializeAMDGPURewriteAGPRCopyMFMALegacyPass(PassRegistry &)
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1879
char & AMDGPURewriteAGPRCopyMFMALegacyID
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.