LLVM 24.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-reg-bank-legalize"
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 bool IsBitcast = mi_match(Src, MRI, m_GBitcast(m_Reg(RALDst)));
278
279 B.setInstrAndDebugLoc(Copy);
280 SmallVector<Register> ReadAnyLaneSrcRegs = getReadAnyLaneSrcs(RALDst);
281 if (ReadAnyLaneSrcRegs.empty())
282 return false;
283
284 Register ReadAnyLaneSrc;
285 if (ReadAnyLaneSrcRegs.size() == 1) {
286 ReadAnyLaneSrc = ReadAnyLaneSrcRegs[0];
287 } else {
288 // Multiple readanylane sources without a common unmerge, merge them.
289 auto Merge = B.buildMergeLikeInstr({VgprRB, MRI.getType(RALDst)},
290 ReadAnyLaneSrcRegs);
291 ReadAnyLaneSrc = Merge.getReg(0);
292 }
293
294 if (!IsBitcast) {
295 // Src = READANYLANE RALSrc Src = READANYLANE RALSrc
296 // Dst = Copy Src $Dst = Copy Src
297 // -> ->
298 // Dst = RALSrc $Dst = Copy RALSrc
299 replaceRegWithOrBuildCopy(Dst, ReadAnyLaneSrc);
300 } else {
301 // RALDst = READANYLANE RALSrc RALDst = READANYLANE RALSrc
302 // Src = G_BITCAST RALDst Src = G_BITCAST RALDst
303 // Dst = Copy Src Dst = Copy Src
304 // -> ->
305 // NewVgpr = G_BITCAST RALDst NewVgpr = G_BITCAST RALDst
306 // Dst = NewVgpr $Dst = Copy NewVgpr
307 auto Bitcast = B.buildBitcast({VgprRB, MRI.getType(Src)}, ReadAnyLaneSrc);
308 replaceRegWithOrBuildCopy(Dst, Bitcast.getReg(0));
309 }
310
311 eraseInstr(Copy, MRI);
312 return true;
313}
314
317 return;
318
319 Register Dst = MI.getOperand(0).getReg();
320 Register Src = MI.getOperand(1).getReg();
321 // Skip copies of physical registers.
322 if (!Dst.isVirtual() || !Src.isVirtual())
323 return;
324
325 // This is a cross bank copy, sgpr S1 to lane mask.
326 //
327 // %Src:sgpr(s1) = G_TRUNC %TruncS32Src:sgpr(s32)
328 // %Dst:lane-mask(s1) = COPY %Src:sgpr(s1)
329 // ->
330 // %BoolSrc:sgpr(s32) = G_AND %TruncS32Src:sgpr(s32), 1
331 // %Dst:lane-mask(s1) = G_AMDGPU_COPY_VCC_SCC %BoolSrc:sgpr(s32)
332 if (isLaneMask(Dst) && MRI.getRegBankOrNull(Src) == SgprRB) {
333 auto [Trunc, TruncS32Src] = tryMatch(Src, AMDGPU::G_TRUNC);
334 assert(Trunc && MRI.getType(TruncS32Src) == S32 &&
335 "sgpr S1 must be result of G_TRUNC of sgpr S32");
336
337 B.setInstr(MI);
338 // Ensure that truncated bits in BoolSrc are 0.
339 auto One = B.buildConstant({SgprRB, S32}, 1);
340 auto BoolSrc = B.buildAnd({SgprRB, S32}, TruncS32Src, One);
341 B.buildInstr(AMDGPU::G_AMDGPU_COPY_VCC_SCC, {Dst}, {BoolSrc});
342 eraseInstr(MI, MRI);
343 }
344}
345
347 // %Src:sgpr(S1) = G_TRUNC %TruncSrc
348 // %Dst = G_ANYEXT %Src:sgpr(S1)
349 // ->
350 // %Dst = G_... %TruncSrc
351 Register Dst = MI.getOperand(0).getReg();
352 Register Src = MI.getOperand(1).getReg();
353 if (MRI.getType(Src) != S1)
354 return;
355
356 auto [Trunc, TruncSrc] = tryMatch(Src, AMDGPU::G_TRUNC);
357 if (!Trunc)
358 return;
359
360 LLT DstTy = MRI.getType(Dst);
361 LLT TruncSrcTy = MRI.getType(TruncSrc);
362
363 if (DstTy == TruncSrcTy) {
364 MRI.replaceRegWith(Dst, TruncSrc);
365 eraseInstr(MI, MRI);
366 return;
367 }
368
369 B.setInstr(MI);
370
371 if (DstTy == S32 && TruncSrcTy == S64) {
372 auto Unmerge = B.buildUnmerge({SgprRB, S32}, TruncSrc);
373 MRI.replaceRegWith(Dst, Unmerge.getReg(0));
374 eraseInstr(MI, MRI);
375 return;
376 }
377
378 if (DstTy == S64 && TruncSrcTy == S32) {
379 B.buildMergeLikeInstr(MI.getOperand(0).getReg(),
380 {TruncSrc, B.buildUndef({SgprRB, S32})});
381 eraseInstr(MI, MRI);
382 return;
383 }
384
385 if (DstTy == S32 && TruncSrcTy == S16) {
386 B.buildAnyExt(Dst, TruncSrc);
387 eraseInstr(MI, MRI);
388 return;
389 }
390
391 if (DstTy == S16 && TruncSrcTy == S32) {
392 B.buildTrunc(Dst, TruncSrc);
393 eraseInstr(MI, MRI);
394 return;
395 }
396
397 llvm_unreachable("missing anyext + trunc combine");
398}
399
400// Search through MRI for virtual registers with sgpr register bank and S1 LLT.
401[[maybe_unused]] static Register getAnySgprS1(const MachineRegisterInfo &MRI) {
402 const LLT S1 = LLT::scalar(1);
403 for (unsigned i = 0; i < MRI.getNumVirtRegs(); ++i) {
405 if (MRI.def_empty(Reg) || MRI.getType(Reg) != S1)
406 continue;
407
408 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
409 if (RB && RB->getID() == AMDGPU::SGPRRegBankID) {
410 LLVM_DEBUG(dbgs() << "Warning: detected sgpr S1 register in: ";
411 MRI.getVRegDef(Reg)->dump(););
412 return Reg;
413 }
414 }
415
416 return {};
417}
418
419bool AMDGPURegBankLegalize::runOnMachineFunction(MachineFunction &MF) {
420 if (MF.getProperties().hasFailedISel())
421 return false;
422
423 // Setup the instruction builder with CSE.
424 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
425 GISelCSEAnalysisWrapper &Wrapper =
426 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
427 GISelCSEInfo &CSEInfo = Wrapper.get(TPC.getCSEConfig());
428 GISelObserverWrapper Observer;
429 Observer.addObserver(&CSEInfo);
430
431 CSEMIRBuilder B(MF);
432 B.setCSEInfo(&CSEInfo);
433 B.setChangeObserver(Observer);
434
435 RAIIDelegateInstaller DelegateInstaller(MF, &Observer);
436 RAIIMFObserverInstaller MFObserverInstaller(MF, Observer);
437
438 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
439 MachineRegisterInfo &MRI = MF.getRegInfo();
440 const RegisterBankInfo &RBI = *ST.getRegBankInfo();
441 const MachineUniformityInfo &MUI =
442 getAnalysis<MachineUniformityAnalysisPass>().getUniformityInfo();
443 GISelValueTracking &VT =
444 getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
445
446 // RegBankLegalizeRules is initialized with assigning sets of IDs to opcodes.
447 const RegBankLegalizeRules &RBLRules = getRules(ST, MRI);
448
449 // Logic that does legalization based on IDs assigned to Opcode.
450 RegBankLegalizeHelper RBLHelper(B, MUI, &VT, RBI, RBLRules);
451
453
454 for (MachineBasicBlock &MBB : MF) {
455 for (MachineInstr &MI : MBB) {
456 AllInst.push_back(&MI);
457 }
458 }
459
460 for (MachineInstr *MI : AllInst) {
461 if (!MI->isPreISelOpcode())
462 continue;
463
464 if (!RBLHelper.findRuleAndApplyMapping(*MI))
465 return false;
466 }
467
468 // Sgpr S1 clean up combines:
469 // - Sgpr S1(S32) to sgpr S1(S32) Copy: anyext + trunc combine.
470 // In RegBankLegalize 'S1 Dst' are legalized into S32 as
471 // 'S1Dst = Trunc S32Dst' and 'S1 Src' into 'S32Src = Anyext S1Src'.
472 // S1 Truncs and Anyexts that come from legalizer, that can have non-S32
473 // types e.g. S16 = Anyext S1 or S1 = Trunc S64, will also be cleaned up.
474 // - Sgpr S1(S32) to vcc Copy: G_AMDGPU_COPY_VCC_SCC combine.
475 // Divergent instruction uses sgpr S1 as input that should be lane mask(vcc)
476 // Legalizing this use creates sgpr S1(S32) to vcc Copy.
477
478 // Note: Remaining S1 copies, S1s are either sgpr S1(S32) or vcc S1:
479 // - Vcc to vcc Copy: nothing to do here, just a regular copy.
480 // - Vcc to sgpr S1 Copy: Should not exist in a form of COPY instruction(*).
481 // Note: For 'uniform-in-vcc to sgpr-S1 copy' G_AMDGPU_COPY_SCC_VCC is used
482 // instead. When only available instruction creates vcc result, use of
483 // UniformInVcc results in creating G_AMDGPU_COPY_SCC_VCC.
484
485 // (*)Explanation for 'sgpr S1(uniform) = COPY vcc(divergent)':
486 // Copy from divergent to uniform register indicates an error in either:
487 // - Uniformity analysis: Uniform instruction has divergent input. If one of
488 // the inputs is divergent, instruction should be divergent!
489 // - RegBankLegalizer not executing in waterfall loop (missing implementation)
490
491 AMDGPURegBankLegalizeCombiner Combiner(B, *ST.getRegisterInfo(), RBI);
492
493 for (MachineBasicBlock &MBB : MF) {
494 for (MachineInstr &MI : make_early_inc_range(MBB)) {
495 if (MI.getOpcode() == AMDGPU::COPY) {
496 Combiner.tryCombineCopy(MI);
497 continue;
498 }
499 if (MI.getOpcode() == AMDGPU::G_ANYEXT) {
500 Combiner.tryCombineS1AnyExt(MI);
501 continue;
502 }
503 }
504 }
505
506 assert(!getAnySgprS1(MRI).isValid() &&
507 "Registers with sgpr reg bank and S1 LLT are not legal after "
508 "AMDGPURegBankLegalize. Should lower to sgpr S32");
509
510 return true;
511}
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
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:299
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
The actual analysis pass wrapper.
Definition CSEInfo.h:243
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 LLVM_READONLY 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.
operand_type_match m_Reg()
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
UnaryOp_match< SrcTy, TargetOpcode::G_BITCAST > m_GBitcast(const SrcTy &Src)
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:1670
char & AMDGPURegBankLegalizeID
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58