LLVM 22.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"
33
34#define DEBUG_TYPE "amdgpu-regbanklegalize"
35
36using namespace llvm;
37using namespace AMDGPU;
38using namespace llvm::MIPatternMatch;
39
40namespace {
41
42// AMDGPU-specific pattern matchers
43template <typename SrcTy>
45m_GAMDGPUReadAnyLane(const SrcTy &Src) {
47}
48
49class AMDGPURegBankLegalize : public MachineFunctionPass {
50public:
51 static char ID;
52
53public:
54 AMDGPURegBankLegalize() : MachineFunctionPass(ID) {}
55
56 bool runOnMachineFunction(MachineFunction &MF) override;
57
58 StringRef getPassName() const override {
59 return "AMDGPU Register Bank Legalize";
60 }
61
62 void getAnalysisUsage(AnalysisUsage &AU) const override {
67 }
68
69 // If there were no phis and we do waterfall expansion machine verifier would
70 // fail.
71 MachineFunctionProperties getClearedProperties() const override {
72 return MachineFunctionProperties().setNoPHIs();
73 }
74};
75
76} // End anonymous namespace.
77
78INITIALIZE_PASS_BEGIN(AMDGPURegBankLegalize, DEBUG_TYPE,
79 "AMDGPU Register Bank Legalize", false, false)
83INITIALIZE_PASS_END(AMDGPURegBankLegalize, DEBUG_TYPE,
84 "AMDGPU Register Bank Legalize", false, false)
85
86char AMDGPURegBankLegalize::ID = 0;
87
88char &llvm::AMDGPURegBankLegalizeID = AMDGPURegBankLegalize::ID;
89
91 return new AMDGPURegBankLegalize();
92}
93
96 static std::mutex GlobalMutex;
98 CacheForRuleSet;
99 std::lock_guard<std::mutex> Lock(GlobalMutex);
100 auto [It, Inserted] = CacheForRuleSet.try_emplace(ST.getGeneration());
101 if (Inserted)
102 It->second = std::make_unique<RegBankLegalizeRules>(ST, MRI);
103 else
104 It->second->refreshRefs(ST, MRI);
105 return *It->second;
106}
107
111 const SIRegisterInfo &TRI;
112 const RegisterBank *SgprRB;
113 const RegisterBank *VgprRB;
114 const RegisterBank *VccRB;
115
116 static constexpr LLT S1 = LLT::scalar(1);
117 static constexpr LLT S16 = LLT::scalar(16);
118 static constexpr LLT S32 = LLT::scalar(32);
119 static constexpr LLT S64 = LLT::scalar(64);
120
121public:
123 const RegisterBankInfo &RBI)
124 : B(B), MRI(*B.getMRI()), TRI(TRI),
125 SgprRB(&RBI.getRegBank(AMDGPU::SGPRRegBankID)),
126 VgprRB(&RBI.getRegBank(AMDGPU::VGPRRegBankID)),
127 VccRB(&RBI.getRegBank(AMDGPU::VCCRegBankID)) {};
128
129 bool isLaneMask(Register Reg);
130 std::pair<MachineInstr *, Register> tryMatch(Register Src, unsigned Opcode);
135
139};
140
142 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
143 if (RB && RB->getID() == AMDGPU::VCCRegBankID)
144 return true;
145
146 const TargetRegisterClass *RC = MRI.getRegClassOrNull(Reg);
147 return RC && TRI.isSGPRClass(RC) && MRI.getType(Reg) == LLT::scalar(1);
148}
149
150std::pair<MachineInstr *, Register>
152 MachineInstr *MatchMI = MRI.getVRegDef(Src);
153 if (MatchMI->getOpcode() != Opcode)
154 return {nullptr, Register()};
155 return {MatchMI, MatchMI->getOperand(1).getReg()};
156}
157
158// Check if all registers are from same unmerge and there is no shuffling.
159// Returns the unmerge source if both conditions are met.
161 SmallVectorImpl<Register> &DefRegs) {
162 auto *UnMerge = getOpcodeDef<GUnmerge>(DefRegs[0], MRI);
163 if (!UnMerge || UnMerge->getNumDefs() != DefRegs.size())
164 return {};
165 for (unsigned I = 1; I < DefRegs.size(); ++I) {
166 if (UnMerge->getReg(I) != DefRegs[I])
167 return {};
168 }
169 return UnMerge->getSourceReg();
170}
171
172// Check if all merge sources are readanylanes and return the readanylane
173// sources if they are.
176 SmallVector<Register> ReadAnyLaneSrcs;
177 for (unsigned i = 0; i < Merge->getNumSources(); ++i) {
178 Register Src;
179 if (!mi_match(Merge->getSourceReg(i), MRI,
180 m_GAMDGPUReadAnyLane(m_Reg(Src))))
181 return {};
182 ReadAnyLaneSrcs.push_back(Src);
183 }
184 return ReadAnyLaneSrcs;
185}
186
189 // Src = G_AMDGPU_READANYLANE RALSrc
190 Register RALSrc;
191 if (mi_match(Src, MRI, m_GAMDGPUReadAnyLane(m_Reg(RALSrc))))
192 return {RALSrc};
193
194 // RALSrc = G_ANYEXT S16Src
195 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
196 // Src = G_TRUNC TruncSrc
197 if (mi_match(Src, MRI,
198 m_GTrunc(m_GAMDGPUReadAnyLane(m_GAnyExt(m_Reg(RALSrc)))))) {
199 return {RALSrc};
200 }
201
202 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
203 // AextSrc = G_TRUNC TruncSrc
204 // Src = G_ANYEXT AextSrc
205 if (mi_match(Src, MRI,
206 m_GAnyExt(m_GTrunc(m_GAMDGPUReadAnyLane(m_Reg(RALSrc)))))) {
207 return {RALSrc};
208 }
209
210 // Sgpr0 = G_AMDGPU_READANYLANE Vgpr0
211 // Sgpr1 = G_AMDGPU_READANYLANE Vgpr1
212 // ...
213 // Src = G_MERGE_LIKE Sgpr0, Sgpr1, ...
214 // Dst = COPY Src
215 if (auto *Merge = getOpcodeDef<GMergeLikeInstr>(Src, MRI)) {
217 if (ReadAnyLaneSrcs.empty())
218 return {};
219
220 // Vgpr0, Vgpr1, ... = G_UNMERGE_VALUES UnmergeSrc
221 if (Register UnmergeSrc = tryMatchUnmergeDefs(ReadAnyLaneSrcs))
222 return {UnmergeSrc};
223
224 // Multiple ReadAnyLane vgpr sources, need to merge Vgpr0, Vgpr1, ...
225 return ReadAnyLaneSrcs;
226 }
227
228 // SrcRegIdx = G_AMDGPU_READANYLANE RALElSrc
229 // SourceReg G_MERGE_VALUES ..., SrcRegIdx, ...
230 // ..., Src, ... = G_UNMERGE_VALUES SourceReg
231 auto *UnMerge = getOpcodeDef<GUnmerge>(Src, MRI);
232 if (!UnMerge)
233 return {};
234
235 int Idx = UnMerge->findRegisterDefOperandIdx(Src, nullptr);
236 auto *Merge = getOpcodeDef<GMergeLikeInstr>(UnMerge->getSourceReg(), MRI);
237 if (!Merge || UnMerge->getNumDefs() != Merge->getNumSources())
238 return {};
239
240 Register SrcRegIdx = Merge->getSourceReg(Idx);
241 if (MRI.getType(Src) != MRI.getType(SrcRegIdx))
242 return {};
243
244 auto [RALEl, RALElSrc] = tryMatch(SrcRegIdx, AMDGPU::G_AMDGPU_READANYLANE);
245 if (RALEl)
246 return {RALElSrc};
247
248 return {};
249}
250
252 Register Src) {
253 if (Dst.isVirtual())
254 MRI.replaceRegWith(Dst, Src);
255 else
256 B.buildCopy(Dst, Src);
257}
258
260 MachineInstr &Copy) {
261 Register Dst = Copy.getOperand(0).getReg();
262 Register Src = Copy.getOperand(1).getReg();
263
264 // Skip non-vgpr Dst
265 if (Dst.isVirtual() ? (MRI.getRegBankOrNull(Dst) != VgprRB)
266 : !TRI.isVGPR(MRI, Dst))
267 return false;
268
269 // Skip physical source registers and source registers with register class
270 if (!Src.isVirtual() || MRI.getRegClassOrNull(Src))
271 return false;
272
273 Register RALDst = Src;
274 MachineInstr &SrcMI = *MRI.getVRegDef(Src);
275 if (SrcMI.getOpcode() == AMDGPU::G_BITCAST)
276 RALDst = SrcMI.getOperand(1).getReg();
277
278 B.setInstrAndDebugLoc(Copy);
279 SmallVector<Register> ReadAnyLaneSrcRegs = getReadAnyLaneSrcs(RALDst);
280 if (ReadAnyLaneSrcRegs.empty())
281 return false;
282
283 Register ReadAnyLaneSrc;
284 if (ReadAnyLaneSrcRegs.size() == 1) {
285 ReadAnyLaneSrc = ReadAnyLaneSrcRegs[0];
286 } else {
287 // Multiple readanylane sources without a common unmerge, merge them.
288 auto Merge = B.buildMergeLikeInstr({VgprRB, MRI.getType(RALDst)},
289 ReadAnyLaneSrcRegs);
290 ReadAnyLaneSrc = Merge.getReg(0);
291 }
292
293 if (SrcMI.getOpcode() != AMDGPU::G_BITCAST) {
294 // Src = READANYLANE RALSrc Src = READANYLANE RALSrc
295 // Dst = Copy Src $Dst = Copy Src
296 // -> ->
297 // Dst = RALSrc $Dst = Copy RALSrc
298 replaceRegWithOrBuildCopy(Dst, ReadAnyLaneSrc);
299 } else {
300 // RALDst = READANYLANE RALSrc RALDst = READANYLANE RALSrc
301 // Src = G_BITCAST RALDst Src = G_BITCAST RALDst
302 // Dst = Copy Src Dst = Copy Src
303 // -> ->
304 // NewVgpr = G_BITCAST RALDst NewVgpr = G_BITCAST RALDst
305 // Dst = NewVgpr $Dst = Copy NewVgpr
306 auto Bitcast = B.buildBitcast({VgprRB, MRI.getType(Src)}, ReadAnyLaneSrc);
307 replaceRegWithOrBuildCopy(Dst, Bitcast.getReg(0));
308 }
309
310 eraseInstr(Copy, MRI);
311 return true;
312}
313
316 return;
317
318 Register Dst = MI.getOperand(0).getReg();
319 Register Src = MI.getOperand(1).getReg();
320 // Skip copies of physical registers.
321 if (!Dst.isVirtual() || !Src.isVirtual())
322 return;
323
324 // This is a cross bank copy, sgpr S1 to lane mask.
325 //
326 // %Src:sgpr(s1) = G_TRUNC %TruncS32Src:sgpr(s32)
327 // %Dst:lane-mask(s1) = COPY %Src:sgpr(s1)
328 // ->
329 // %BoolSrc:sgpr(s32) = G_AND %TruncS32Src:sgpr(s32), 1
330 // %Dst:lane-mask(s1) = G_AMDGPU_COPY_VCC_SCC %BoolSrc:sgpr(s32)
331 if (isLaneMask(Dst) && MRI.getRegBankOrNull(Src) == SgprRB) {
332 auto [Trunc, TruncS32Src] = tryMatch(Src, AMDGPU::G_TRUNC);
333 assert(Trunc && MRI.getType(TruncS32Src) == S32 &&
334 "sgpr S1 must be result of G_TRUNC of sgpr S32");
335
336 B.setInstr(MI);
337 // Ensure that truncated bits in BoolSrc are 0.
338 auto One = B.buildConstant({SgprRB, S32}, 1);
339 auto BoolSrc = B.buildAnd({SgprRB, S32}, TruncS32Src, One);
340 B.buildInstr(AMDGPU::G_AMDGPU_COPY_VCC_SCC, {Dst}, {BoolSrc});
341 eraseInstr(MI, MRI);
342 }
343}
344
346 // %Src:sgpr(S1) = G_TRUNC %TruncSrc
347 // %Dst = G_ANYEXT %Src:sgpr(S1)
348 // ->
349 // %Dst = G_... %TruncSrc
350 Register Dst = MI.getOperand(0).getReg();
351 Register Src = MI.getOperand(1).getReg();
352 if (MRI.getType(Src) != S1)
353 return;
354
355 auto [Trunc, TruncSrc] = tryMatch(Src, AMDGPU::G_TRUNC);
356 if (!Trunc)
357 return;
358
359 LLT DstTy = MRI.getType(Dst);
360 LLT TruncSrcTy = MRI.getType(TruncSrc);
361
362 if (DstTy == TruncSrcTy) {
363 MRI.replaceRegWith(Dst, TruncSrc);
364 eraseInstr(MI, MRI);
365 return;
366 }
367
368 B.setInstr(MI);
369
370 if (DstTy == S32 && TruncSrcTy == S64) {
371 auto Unmerge = B.buildUnmerge({SgprRB, S32}, TruncSrc);
372 MRI.replaceRegWith(Dst, Unmerge.getReg(0));
373 eraseInstr(MI, MRI);
374 return;
375 }
376
377 if (DstTy == S64 && TruncSrcTy == S32) {
378 B.buildMergeLikeInstr(MI.getOperand(0).getReg(),
379 {TruncSrc, B.buildUndef({SgprRB, S32})});
380 eraseInstr(MI, MRI);
381 return;
382 }
383
384 if (DstTy == S32 && TruncSrcTy == S16) {
385 B.buildAnyExt(Dst, TruncSrc);
386 eraseInstr(MI, MRI);
387 return;
388 }
389
390 if (DstTy == S16 && TruncSrcTy == S32) {
391 B.buildTrunc(Dst, TruncSrc);
392 eraseInstr(MI, MRI);
393 return;
394 }
395
396 llvm_unreachable("missing anyext + trunc combine");
397}
398
399// Search through MRI for virtual registers with sgpr register bank and S1 LLT.
400[[maybe_unused]] static Register getAnySgprS1(const MachineRegisterInfo &MRI) {
401 const LLT S1 = LLT::scalar(1);
402 for (unsigned i = 0; i < MRI.getNumVirtRegs(); ++i) {
404 if (MRI.def_empty(Reg) || MRI.getType(Reg) != S1)
405 continue;
406
407 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
408 if (RB && RB->getID() == AMDGPU::SGPRRegBankID) {
409 LLVM_DEBUG(dbgs() << "Warning: detected sgpr S1 register in: ";
410 MRI.getVRegDef(Reg)->dump(););
411 return Reg;
412 }
413 }
414
415 return {};
416}
417
418bool AMDGPURegBankLegalize::runOnMachineFunction(MachineFunction &MF) {
419 if (MF.getProperties().hasFailedISel())
420 return false;
421
422 // Setup the instruction builder with CSE.
423 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
424 GISelCSEAnalysisWrapper &Wrapper =
425 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
426 GISelCSEInfo &CSEInfo = Wrapper.get(TPC.getCSEConfig());
427 GISelObserverWrapper Observer;
428 Observer.addObserver(&CSEInfo);
429
430 CSEMIRBuilder B(MF);
431 B.setCSEInfo(&CSEInfo);
432 B.setChangeObserver(Observer);
433
434 RAIIDelegateInstaller DelegateInstaller(MF, &Observer);
435 RAIIMFObserverInstaller MFObserverInstaller(MF, Observer);
436
437 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
438 MachineRegisterInfo &MRI = MF.getRegInfo();
439 const RegisterBankInfo &RBI = *ST.getRegBankInfo();
440 const MachineUniformityInfo &MUI =
441 getAnalysis<MachineUniformityAnalysisPass>().getUniformityInfo();
442
443 // RegBankLegalizeRules is initialized with assigning sets of IDs to opcodes.
444 const RegBankLegalizeRules &RBLRules = getRules(ST, MRI);
445
446 // Logic that does legalization based on IDs assigned to Opcode.
447 RegBankLegalizeHelper RBLHelper(B, MUI, RBI, RBLRules);
448
450
451 for (MachineBasicBlock &MBB : MF) {
452 for (MachineInstr &MI : MBB) {
453 AllInst.push_back(&MI);
454 }
455 }
456
457 for (MachineInstr *MI : AllInst) {
458 if (!MI->isPreISelOpcode())
459 continue;
460
461 unsigned Opc = MI->getOpcode();
462 // Insert point for use operands needs some calculation.
463 if (Opc == AMDGPU::G_PHI) {
464 if (!RBLHelper.applyMappingPHI(*MI))
465 return false;
466 continue;
467 }
468
469 // Opcodes that support pretty much all combinations of reg banks and LLTs
470 // (except S1). There is no point in writing rules for them.
471 if (Opc == AMDGPU::G_BUILD_VECTOR || Opc == AMDGPU::G_UNMERGE_VALUES ||
472 Opc == AMDGPU::G_MERGE_VALUES || Opc == AMDGPU::G_CONCAT_VECTORS ||
473 Opc == AMDGPU::G_BITCAST) {
474 RBLHelper.applyMappingTrivial(*MI);
475 continue;
476 }
477
478 // Opcodes that also support S1.
479 if (Opc == G_FREEZE &&
480 MRI.getType(MI->getOperand(0).getReg()) != LLT::scalar(1)) {
481 RBLHelper.applyMappingTrivial(*MI);
482 continue;
483 }
484
485 if ((Opc == AMDGPU::G_CONSTANT || Opc == AMDGPU::G_FCONSTANT ||
486 Opc == AMDGPU::G_IMPLICIT_DEF)) {
487 Register Dst = MI->getOperand(0).getReg();
488 // Non S1 types are trivially accepted.
489 if (MRI.getType(Dst) != LLT::scalar(1)) {
490 assert(MRI.getRegBank(Dst)->getID() == AMDGPU::SGPRRegBankID);
491 continue;
492 }
493
494 // S1 rules are in RegBankLegalizeRules.
495 }
496
497 if (!RBLHelper.findRuleAndApplyMapping(*MI))
498 return false;
499 }
500
501 // Sgpr S1 clean up combines:
502 // - Sgpr S1(S32) to sgpr S1(S32) Copy: anyext + trunc combine.
503 // In RegBankLegalize 'S1 Dst' are legalized into S32 as
504 // 'S1Dst = Trunc S32Dst' and 'S1 Src' into 'S32Src = Anyext S1Src'.
505 // S1 Truncs and Anyexts that come from legalizer, that can have non-S32
506 // types e.g. S16 = Anyext S1 or S1 = Trunc S64, will also be cleaned up.
507 // - Sgpr S1(S32) to vcc Copy: G_AMDGPU_COPY_VCC_SCC combine.
508 // Divergent instruction uses sgpr S1 as input that should be lane mask(vcc)
509 // Legalizing this use creates sgpr S1(S32) to vcc Copy.
510
511 // Note: Remaining S1 copies, S1s are either sgpr S1(S32) or vcc S1:
512 // - Vcc to vcc Copy: nothing to do here, just a regular copy.
513 // - Vcc to sgpr S1 Copy: Should not exist in a form of COPY instruction(*).
514 // Note: For 'uniform-in-vcc to sgpr-S1 copy' G_AMDGPU_COPY_SCC_VCC is used
515 // instead. When only available instruction creates vcc result, use of
516 // UniformInVcc results in creating G_AMDGPU_COPY_SCC_VCC.
517
518 // (*)Explanation for 'sgpr S1(uniform) = COPY vcc(divergent)':
519 // Copy from divergent to uniform register indicates an error in either:
520 // - Uniformity analysis: Uniform instruction has divergent input. If one of
521 // the inputs is divergent, instruction should be divergent!
522 // - RegBankLegalizer not executing in waterfall loop (missing implementation)
523
524 AMDGPURegBankLegalizeCombiner Combiner(B, *ST.getRegisterInfo(), RBI);
525
526 for (MachineBasicBlock &MBB : MF) {
527 for (MachineInstr &MI : make_early_inc_range(MBB)) {
528 if (MI.getOpcode() == AMDGPU::COPY) {
529 Combiner.tryCombineCopy(MI);
530 continue;
531 }
532 if (MI.getOpcode() == AMDGPU::G_ANYEXT) {
533 Combiner.tryCombineS1AnyExt(MI);
534 continue;
535 }
536 }
537 }
538
540 "Registers with sgpr reg bank and S1 LLT are not legal after "
541 "AMDGPURegBankLegalize. Should lower to sgpr S32");
542
543 return true;
544}
unsigned const MachineRegisterInfo * MRI
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.
#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:114
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:256
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
The actual analysis pass wrapper.
Definition CSEInfo.h:229
void addObserver(GISelChangeObserver *O)
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,...
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.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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:654
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:632
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
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:1726
char & AMDGPURegBankLegalizeID