LLVM 23.0.0git
AMDGPURegBankLegalize.cpp
Go to the documentation of this file.
1//===-- AMDGPURegBankLegalize.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/// Lower G_ instructions that can't be inst-selected with register bank
10/// assignment from AMDGPURegBankSelect based on machine uniformity info.
11/// Given types on all operands, some register bank assignments require lowering
12/// while others do not.
13/// Note: cases where all register bank assignments would require lowering are
14/// lowered in legalizer.
15/// For example vgpr S64 G_AND requires lowering to S32 while sgpr S64 does not.
16/// Eliminate sgpr S1 by lowering to sgpr S32.
17//
18//===----------------------------------------------------------------------===//
19
20#include "AMDGPU.h"
23#include "GCNSubtarget.h"
34
35#define DEBUG_TYPE "amdgpu-regbanklegalize"
36
37using namespace llvm;
38using namespace AMDGPU;
39using namespace llvm::MIPatternMatch;
40
41namespace {
42
43// AMDGPU-specific pattern matchers
44template <typename SrcTy>
46m_GAMDGPUReadAnyLane(const SrcTy &Src) {
48}
49
50class AMDGPURegBankLegalize : public MachineFunctionPass {
51public:
52 static char ID;
53
54public:
55 AMDGPURegBankLegalize() : MachineFunctionPass(ID) {}
56
57 bool runOnMachineFunction(MachineFunction &MF) override;
58
59 StringRef getPassName() const override {
60 return "AMDGPU Register Bank Legalize";
61 }
62
63 void getAnalysisUsage(AnalysisUsage &AU) const override {
69 }
70
71 // If there were no phis and we do waterfall expansion machine verifier would
72 // fail.
73 MachineFunctionProperties getClearedProperties() const override {
74 return MachineFunctionProperties().setNoPHIs();
75 }
76};
77
78} // End anonymous namespace.
79
80INITIALIZE_PASS_BEGIN(AMDGPURegBankLegalize, DEBUG_TYPE,
81 "AMDGPU Register Bank Legalize", false, false)
86INITIALIZE_PASS_END(AMDGPURegBankLegalize, DEBUG_TYPE,
87 "AMDGPU Register Bank Legalize", false, false)
88
89char AMDGPURegBankLegalize::ID = 0;
90
91char &llvm::AMDGPURegBankLegalizeID = AMDGPURegBankLegalize::ID;
92
94 return new AMDGPURegBankLegalize();
95}
96
99 static std::mutex GlobalMutex;
101 CacheForRuleSet;
102 std::lock_guard<std::mutex> Lock(GlobalMutex);
103 auto [It, Inserted] = CacheForRuleSet.try_emplace(ST.getGeneration());
104 if (Inserted)
105 It->second = std::make_unique<RegBankLegalizeRules>(ST, MRI);
106 else
107 It->second->refreshRefs(ST, MRI);
108 return *It->second;
109}
110
114 const SIRegisterInfo &TRI;
115 const RegisterBank *SgprRB;
116 const RegisterBank *VgprRB;
117 const RegisterBank *VccRB;
118
119 static constexpr LLT S1 = LLT::scalar(1);
120 static constexpr LLT S16 = LLT::scalar(16);
121 static constexpr LLT S32 = LLT::scalar(32);
122 static constexpr LLT S64 = LLT::scalar(64);
123
124public:
126 const RegisterBankInfo &RBI)
127 : B(B), MRI(*B.getMRI()), TRI(TRI),
128 SgprRB(&RBI.getRegBank(AMDGPU::SGPRRegBankID)),
129 VgprRB(&RBI.getRegBank(AMDGPU::VGPRRegBankID)),
130 VccRB(&RBI.getRegBank(AMDGPU::VCCRegBankID)) {};
131
132 bool isLaneMask(Register Reg);
133 std::pair<MachineInstr *, Register> tryMatch(Register Src, unsigned Opcode);
138
142};
143
145 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
146 if (RB && RB->getID() == AMDGPU::VCCRegBankID)
147 return true;
148
149 const TargetRegisterClass *RC = MRI.getRegClassOrNull(Reg);
150 return RC && TRI.isSGPRClass(RC) && MRI.getType(Reg) == LLT::scalar(1);
151}
152
153std::pair<MachineInstr *, Register>
155 MachineInstr *MatchMI = MRI.getVRegDef(Src);
156 if (MatchMI->getOpcode() != Opcode)
157 return {nullptr, Register()};
158 return {MatchMI, MatchMI->getOperand(1).getReg()};
159}
160
161// Check if all registers are from same unmerge and there is no shuffling.
162// Returns the unmerge source if both conditions are met.
164 SmallVectorImpl<Register> &DefRegs) {
165 auto *UnMerge = getOpcodeDef<GUnmerge>(DefRegs[0], MRI);
166 if (!UnMerge || UnMerge->getNumDefs() != DefRegs.size())
167 return {};
168 for (unsigned I = 1; I < DefRegs.size(); ++I) {
169 if (UnMerge->getReg(I) != DefRegs[I])
170 return {};
171 }
172 return UnMerge->getSourceReg();
173}
174
175// Check if all merge sources are readanylanes and return the readanylane
176// sources if they are.
179 SmallVector<Register> ReadAnyLaneSrcs;
180 for (unsigned i = 0; i < Merge->getNumSources(); ++i) {
181 Register Src;
182 if (!mi_match(Merge->getSourceReg(i), MRI,
183 m_GAMDGPUReadAnyLane(m_Reg(Src))))
184 return {};
185 ReadAnyLaneSrcs.push_back(Src);
186 }
187 return ReadAnyLaneSrcs;
188}
189
192 // Src = G_AMDGPU_READANYLANE RALSrc
193 Register RALSrc;
194 if (mi_match(Src, MRI, m_GAMDGPUReadAnyLane(m_Reg(RALSrc))))
195 return {RALSrc};
196
197 // RALSrc = G_ANYEXT S16Src
198 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
199 // Src = G_TRUNC TruncSrc
200 if (mi_match(Src, MRI,
201 m_GTrunc(m_GAMDGPUReadAnyLane(m_GAnyExt(m_Reg(RALSrc)))))) {
202 return {RALSrc};
203 }
204
205 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
206 // AextSrc = G_TRUNC TruncSrc
207 // Src = G_ANYEXT AextSrc
208 if (mi_match(Src, MRI,
209 m_GAnyExt(m_GTrunc(m_GAMDGPUReadAnyLane(m_Reg(RALSrc)))))) {
210 return {RALSrc};
211 }
212
213 // Sgpr0 = G_AMDGPU_READANYLANE Vgpr0
214 // Sgpr1 = G_AMDGPU_READANYLANE Vgpr1
215 // ...
216 // Src = G_MERGE_LIKE Sgpr0, Sgpr1, ...
217 // Dst = COPY Src
218 if (auto *Merge = getOpcodeDef<GMergeLikeInstr>(Src, MRI)) {
220 if (ReadAnyLaneSrcs.empty())
221 return {};
222
223 // Vgpr0, Vgpr1, ... = G_UNMERGE_VALUES UnmergeSrc
224 if (Register UnmergeSrc = tryMatchUnmergeDefs(ReadAnyLaneSrcs))
225 return {UnmergeSrc};
226
227 // Multiple ReadAnyLane vgpr sources, need to merge Vgpr0, Vgpr1, ...
228 return ReadAnyLaneSrcs;
229 }
230
231 // SrcRegIdx = G_AMDGPU_READANYLANE RALElSrc
232 // SourceReg G_MERGE_VALUES ..., SrcRegIdx, ...
233 // ..., Src, ... = G_UNMERGE_VALUES SourceReg
234 auto *UnMerge = getOpcodeDef<GUnmerge>(Src, MRI);
235 if (!UnMerge)
236 return {};
237
238 int Idx = UnMerge->findRegisterDefOperandIdx(Src, nullptr);
239 auto *Merge = getOpcodeDef<GMergeLikeInstr>(UnMerge->getSourceReg(), MRI);
240 if (!Merge || UnMerge->getNumDefs() != Merge->getNumSources())
241 return {};
242
243 Register SrcRegIdx = Merge->getSourceReg(Idx);
244 if (MRI.getType(Src) != MRI.getType(SrcRegIdx))
245 return {};
246
247 auto [RALEl, RALElSrc] = tryMatch(SrcRegIdx, AMDGPU::G_AMDGPU_READANYLANE);
248 if (RALEl)
249 return {RALElSrc};
250
251 return {};
252}
253
255 Register Src) {
256 if (Dst.isVirtual())
257 MRI.replaceRegWith(Dst, Src);
258 else
259 B.buildCopy(Dst, Src);
260}
261
263 MachineInstr &Copy) {
264 Register Dst = Copy.getOperand(0).getReg();
265 Register Src = Copy.getOperand(1).getReg();
266
267 // Skip non-vgpr Dst
268 if (Dst.isVirtual() ? (MRI.getRegBankOrNull(Dst) != VgprRB)
269 : !TRI.isVGPR(MRI, Dst))
270 return false;
271
272 // Skip physical source registers and source registers with register class
273 if (!Src.isVirtual() || MRI.getRegClassOrNull(Src))
274 return false;
275
276 Register RALDst = Src;
277 MachineInstr &SrcMI = *MRI.getVRegDef(Src);
278 if (SrcMI.getOpcode() == AMDGPU::G_BITCAST)
279 RALDst = SrcMI.getOperand(1).getReg();
280
281 B.setInstrAndDebugLoc(Copy);
282 SmallVector<Register> ReadAnyLaneSrcRegs = getReadAnyLaneSrcs(RALDst);
283 if (ReadAnyLaneSrcRegs.empty())
284 return false;
285
286 Register ReadAnyLaneSrc;
287 if (ReadAnyLaneSrcRegs.size() == 1) {
288 ReadAnyLaneSrc = ReadAnyLaneSrcRegs[0];
289 } else {
290 // Multiple readanylane sources without a common unmerge, merge them.
291 auto Merge = B.buildMergeLikeInstr({VgprRB, MRI.getType(RALDst)},
292 ReadAnyLaneSrcRegs);
293 ReadAnyLaneSrc = Merge.getReg(0);
294 }
295
296 if (SrcMI.getOpcode() != AMDGPU::G_BITCAST) {
297 // Src = READANYLANE RALSrc Src = READANYLANE RALSrc
298 // Dst = Copy Src $Dst = Copy Src
299 // -> ->
300 // Dst = RALSrc $Dst = Copy RALSrc
301 replaceRegWithOrBuildCopy(Dst, ReadAnyLaneSrc);
302 } else {
303 // RALDst = READANYLANE RALSrc RALDst = READANYLANE RALSrc
304 // Src = G_BITCAST RALDst Src = G_BITCAST RALDst
305 // Dst = Copy Src Dst = Copy Src
306 // -> ->
307 // NewVgpr = G_BITCAST RALDst NewVgpr = G_BITCAST RALDst
308 // Dst = NewVgpr $Dst = Copy NewVgpr
309 auto Bitcast = B.buildBitcast({VgprRB, MRI.getType(Src)}, ReadAnyLaneSrc);
310 replaceRegWithOrBuildCopy(Dst, Bitcast.getReg(0));
311 }
312
313 eraseInstr(Copy, MRI);
314 return true;
315}
316
319 return;
320
321 Register Dst = MI.getOperand(0).getReg();
322 Register Src = MI.getOperand(1).getReg();
323 // Skip copies of physical registers.
324 if (!Dst.isVirtual() || !Src.isVirtual())
325 return;
326
327 // This is a cross bank copy, sgpr S1 to lane mask.
328 //
329 // %Src:sgpr(s1) = G_TRUNC %TruncS32Src:sgpr(s32)
330 // %Dst:lane-mask(s1) = COPY %Src:sgpr(s1)
331 // ->
332 // %BoolSrc:sgpr(s32) = G_AND %TruncS32Src:sgpr(s32), 1
333 // %Dst:lane-mask(s1) = G_AMDGPU_COPY_VCC_SCC %BoolSrc:sgpr(s32)
334 if (isLaneMask(Dst) && MRI.getRegBankOrNull(Src) == SgprRB) {
335 auto [Trunc, TruncS32Src] = tryMatch(Src, AMDGPU::G_TRUNC);
336 assert(Trunc && MRI.getType(TruncS32Src) == S32 &&
337 "sgpr S1 must be result of G_TRUNC of sgpr S32");
338
339 B.setInstr(MI);
340 // Ensure that truncated bits in BoolSrc are 0.
341 auto One = B.buildConstant({SgprRB, S32}, 1);
342 auto BoolSrc = B.buildAnd({SgprRB, S32}, TruncS32Src, One);
343 B.buildInstr(AMDGPU::G_AMDGPU_COPY_VCC_SCC, {Dst}, {BoolSrc});
344 eraseInstr(MI, MRI);
345 }
346}
347
349 // %Src:sgpr(S1) = G_TRUNC %TruncSrc
350 // %Dst = G_ANYEXT %Src:sgpr(S1)
351 // ->
352 // %Dst = G_... %TruncSrc
353 Register Dst = MI.getOperand(0).getReg();
354 Register Src = MI.getOperand(1).getReg();
355 if (MRI.getType(Src) != S1)
356 return;
357
358 auto [Trunc, TruncSrc] = tryMatch(Src, AMDGPU::G_TRUNC);
359 if (!Trunc)
360 return;
361
362 LLT DstTy = MRI.getType(Dst);
363 LLT TruncSrcTy = MRI.getType(TruncSrc);
364
365 if (DstTy == TruncSrcTy) {
366 MRI.replaceRegWith(Dst, TruncSrc);
367 eraseInstr(MI, MRI);
368 return;
369 }
370
371 B.setInstr(MI);
372
373 if (DstTy == S32 && TruncSrcTy == S64) {
374 auto Unmerge = B.buildUnmerge({SgprRB, S32}, TruncSrc);
375 MRI.replaceRegWith(Dst, Unmerge.getReg(0));
376 eraseInstr(MI, MRI);
377 return;
378 }
379
380 if (DstTy == S64 && TruncSrcTy == S32) {
381 B.buildMergeLikeInstr(MI.getOperand(0).getReg(),
382 {TruncSrc, B.buildUndef({SgprRB, S32})});
383 eraseInstr(MI, MRI);
384 return;
385 }
386
387 if (DstTy == S32 && TruncSrcTy == S16) {
388 B.buildAnyExt(Dst, TruncSrc);
389 eraseInstr(MI, MRI);
390 return;
391 }
392
393 if (DstTy == S16 && TruncSrcTy == S32) {
394 B.buildTrunc(Dst, TruncSrc);
395 eraseInstr(MI, MRI);
396 return;
397 }
398
399 llvm_unreachable("missing anyext + trunc combine");
400}
401
402// Search through MRI for virtual registers with sgpr register bank and S1 LLT.
403[[maybe_unused]] static Register getAnySgprS1(const MachineRegisterInfo &MRI) {
404 const LLT S1 = LLT::scalar(1);
405 for (unsigned i = 0; i < MRI.getNumVirtRegs(); ++i) {
407 if (MRI.def_empty(Reg) || MRI.getType(Reg) != S1)
408 continue;
409
410 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
411 if (RB && RB->getID() == AMDGPU::SGPRRegBankID) {
412 LLVM_DEBUG(dbgs() << "Warning: detected sgpr S1 register in: ";
413 MRI.getVRegDef(Reg)->dump(););
414 return Reg;
415 }
416 }
417
418 return {};
419}
420
421bool AMDGPURegBankLegalize::runOnMachineFunction(MachineFunction &MF) {
422 if (MF.getProperties().hasFailedISel())
423 return false;
424
425 // Setup the instruction builder with CSE.
426 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
427 GISelCSEAnalysisWrapper &Wrapper =
428 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
429 GISelCSEInfo &CSEInfo = Wrapper.get(TPC.getCSEConfig());
430 GISelObserverWrapper Observer;
431 Observer.addObserver(&CSEInfo);
432
433 CSEMIRBuilder B(MF);
434 B.setCSEInfo(&CSEInfo);
435 B.setChangeObserver(Observer);
436
437 RAIIDelegateInstaller DelegateInstaller(MF, &Observer);
438 RAIIMFObserverInstaller MFObserverInstaller(MF, Observer);
439
440 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
441 MachineRegisterInfo &MRI = MF.getRegInfo();
442 const RegisterBankInfo &RBI = *ST.getRegBankInfo();
443 const MachineUniformityInfo &MUI =
444 getAnalysis<MachineUniformityAnalysisPass>().getUniformityInfo();
445 GISelValueTracking &VT =
446 getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
447
448 // RegBankLegalizeRules is initialized with assigning sets of IDs to opcodes.
449 const RegBankLegalizeRules &RBLRules = getRules(ST, MRI);
450
451 // Logic that does legalization based on IDs assigned to Opcode.
452 RegBankLegalizeHelper RBLHelper(B, MUI, &VT, RBI, RBLRules);
453
455
456 for (MachineBasicBlock &MBB : MF) {
457 for (MachineInstr &MI : MBB) {
458 AllInst.push_back(&MI);
459 }
460 }
461
462 for (MachineInstr *MI : AllInst) {
463 if (!MI->isPreISelOpcode())
464 continue;
465
466 if (!RBLHelper.findRuleAndApplyMapping(*MI))
467 return false;
468 }
469
470 // Sgpr S1 clean up combines:
471 // - Sgpr S1(S32) to sgpr S1(S32) Copy: anyext + trunc combine.
472 // In RegBankLegalize 'S1 Dst' are legalized into S32 as
473 // 'S1Dst = Trunc S32Dst' and 'S1 Src' into 'S32Src = Anyext S1Src'.
474 // S1 Truncs and Anyexts that come from legalizer, that can have non-S32
475 // types e.g. S16 = Anyext S1 or S1 = Trunc S64, will also be cleaned up.
476 // - Sgpr S1(S32) to vcc Copy: G_AMDGPU_COPY_VCC_SCC combine.
477 // Divergent instruction uses sgpr S1 as input that should be lane mask(vcc)
478 // Legalizing this use creates sgpr S1(S32) to vcc Copy.
479
480 // Note: Remaining S1 copies, S1s are either sgpr S1(S32) or vcc S1:
481 // - Vcc to vcc Copy: nothing to do here, just a regular copy.
482 // - Vcc to sgpr S1 Copy: Should not exist in a form of COPY instruction(*).
483 // Note: For 'uniform-in-vcc to sgpr-S1 copy' G_AMDGPU_COPY_SCC_VCC is used
484 // instead. When only available instruction creates vcc result, use of
485 // UniformInVcc results in creating G_AMDGPU_COPY_SCC_VCC.
486
487 // (*)Explanation for 'sgpr S1(uniform) = COPY vcc(divergent)':
488 // Copy from divergent to uniform register indicates an error in either:
489 // - Uniformity analysis: Uniform instruction has divergent input. If one of
490 // the inputs is divergent, instruction should be divergent!
491 // - RegBankLegalizer not executing in waterfall loop (missing implementation)
492
493 AMDGPURegBankLegalizeCombiner Combiner(B, *ST.getRegisterInfo(), RBI);
494
495 for (MachineBasicBlock &MBB : MF) {
496 for (MachineInstr &MI : make_early_inc_range(MBB)) {
497 if (MI.getOpcode() == AMDGPU::COPY) {
498 Combiner.tryCombineCopy(MI);
499 continue;
500 }
501 if (MI.getOpcode() == AMDGPU::G_ANYEXT) {
502 Combiner.tryCombineS1AnyExt(MI);
503 continue;
504 }
505 }
506 }
507
508 assert(!getAnySgprS1(MRI).isValid() &&
509 "Registers with sgpr reg bank and S1 LLT are not legal after "
510 "AMDGPURegBankLegalize. Should lower to sgpr S32");
511
512 return true;
513}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
amdgpu aa AMDGPU Address space based Alias Analysis Wrapper
constexpr LLT S16
constexpr LLT S1
constexpr LLT S32
static Register getAnySgprS1(const MachineRegisterInfo &MRI)
const RegBankLegalizeRules & getRules(const GCNSubtarget &ST, MachineRegisterInfo &MRI)
MachineBasicBlock & MBB
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Provides analysis for continuously CSEing during GISel passes.
This file implements a version of MachineIRBuilder which CSEs insts within a MachineBasicBlock.
AMD GCN specific subclass of TargetSubtarget.
Provides analysis for querying information about KnownBits during GISel passes.
#define DEBUG_TYPE
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Contains matchers for matching SSA Machine Instructions.
Register Reg
Machine IR instance of the generic uniformity analysis.
Promote Memory to Register
Definition Mem2Reg.cpp:110
#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
R600 Clause Merge
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Target-Independent Code Generator Pass Configuration Options pass.
Register tryMatchUnmergeDefs(SmallVectorImpl< Register > &DefRegs)
void replaceRegWithOrBuildCopy(Register Dst, Register Src)
AMDGPURegBankLegalizeCombiner(MachineIRBuilder &B, const SIRegisterInfo &TRI, const RegisterBankInfo &RBI)
void tryCombineS1AnyExt(MachineInstr &MI)
std::pair< MachineInstr *, Register > tryMatch(Register Src, unsigned Opcode)
SmallVector< Register > tryMatchMergeReadAnyLane(GMergeLikeInstr *Merge)
bool tryEliminateReadAnyLane(MachineInstr &Copy)
SmallVector< Register > getReadAnyLaneSrcs(Register Src)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:301
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
The actual analysis pass wrapper.
Definition CSEInfo.h:242
void addObserver(GISelChangeObserver *O)
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelValueTrackingInfoAnal...
Represents G_BUILD_VECTOR, G_CONCAT_VECTORS or G_MERGE_VALUES.
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
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.
Properties which a MachineFunction may have at a given point in time.
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.
const MachineFunctionProperties & getProperties() const
Get the function properties.
Helper class to build MachineInstr.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLT getType(Register Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register.
bool def_empty(Register RegNo) const
def_empty - Return true if there are no instructions defining the specified register (it may be live-...
const RegisterBank * getRegBankOrNull(Register Reg) const
Return the register bank of Reg, or null if Reg has not been assigned a register bank or has been ass...
unsigned getNumVirtRegs() const
getNumVirtRegs - Return the number of virtual registers created.
Legacy analysis pass which computes a MachineUniformityInfo.
Holds all the information related to register banks.
This class implements the register bank concept.
unsigned getID() const
Get the identifier of this register bank.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition Register.h:72
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.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Target-Independent Code Generator Pass Configuration Options.
virtual std::unique_ptr< CSEConfigBase > getCSEConfig() const
Returns the CSEConfig object to use for the current optimization level.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition CallingConv.h:24
operand_type_match m_Reg()
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
UnaryOp_match< SrcTy, TargetOpcode::G_ANYEXT > m_GAnyExt(const SrcTy &Src)
UnaryOp_match< SrcTy, TargetOpcode::G_TRUNC > m_GTrunc(const SrcTy &Src)
This is an optimization pass for GlobalISel generic memory operations.
GenericUniformityInfo< MachineSSAContext > MachineUniformityInfo
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
LLVM_ABI MachineInstr * getOpcodeDef(unsigned Opcode, Register Reg, const MachineRegisterInfo &MRI)
See if Reg is defined by an single def instruction that is Opcode.
Definition Utils.cpp:656
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:633
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
FunctionPass * createAMDGPURegBankLegalizePass()
LLVM_ABI void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
Definition Utils.cpp:1685
char & AMDGPURegBankLegalizeID