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"
32
33#define DEBUG_TYPE "amdgpu-regbanklegalize"
34
35using namespace llvm;
36using namespace AMDGPU;
37
38namespace {
39
40class AMDGPURegBankLegalize : public MachineFunctionPass {
41public:
42 static char ID;
43
44public:
45 AMDGPURegBankLegalize() : MachineFunctionPass(ID) {}
46
47 bool runOnMachineFunction(MachineFunction &MF) override;
48
49 StringRef getPassName() const override {
50 return "AMDGPU Register Bank Legalize";
51 }
52
53 void getAnalysisUsage(AnalysisUsage &AU) const override {
58 }
59
60 // If there were no phis and we do waterfall expansion machine verifier would
61 // fail.
63 return MachineFunctionProperties().setNoPHIs();
64 }
65};
66
67} // End anonymous namespace.
68
69INITIALIZE_PASS_BEGIN(AMDGPURegBankLegalize, DEBUG_TYPE,
70 "AMDGPU Register Bank Legalize", false, false)
74INITIALIZE_PASS_END(AMDGPURegBankLegalize, DEBUG_TYPE,
75 "AMDGPU Register Bank Legalize", false, false)
76
77char AMDGPURegBankLegalize::ID = 0;
78
79char &llvm::AMDGPURegBankLegalizeID = AMDGPURegBankLegalize::ID;
80
82 return new AMDGPURegBankLegalize();
83}
84
87 static std::mutex GlobalMutex;
89 CacheForRuleSet;
90 std::lock_guard<std::mutex> Lock(GlobalMutex);
91 auto [It, Inserted] = CacheForRuleSet.try_emplace(ST.getGeneration());
92 if (Inserted)
93 It->second = std::make_unique<RegBankLegalizeRules>(ST, MRI);
94 else
95 It->second->refreshRefs(ST, MRI);
96 return *It->second;
97}
98
102 const SIRegisterInfo &TRI;
103 const RegisterBank *SgprRB;
104 const RegisterBank *VgprRB;
105 const RegisterBank *VccRB;
106
107 static constexpr LLT S1 = LLT::scalar(1);
108 static constexpr LLT S16 = LLT::scalar(16);
109 static constexpr LLT S32 = LLT::scalar(32);
110 static constexpr LLT S64 = LLT::scalar(64);
111
112public:
114 const RegisterBankInfo &RBI)
115 : B(B), MRI(*B.getMRI()), TRI(TRI),
116 SgprRB(&RBI.getRegBank(AMDGPU::SGPRRegBankID)),
117 VgprRB(&RBI.getRegBank(AMDGPU::VGPRRegBankID)),
118 VccRB(&RBI.getRegBank(AMDGPU::VCCRegBankID)) {};
119
120 bool isLaneMask(Register Reg);
121 std::pair<MachineInstr *, Register> tryMatch(Register Src, unsigned Opcode);
122 std::pair<GUnmerge *, int> tryMatchRALFromUnmerge(Register Src);
125
129};
130
132 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
133 if (RB && RB->getID() == AMDGPU::VCCRegBankID)
134 return true;
135
136 const TargetRegisterClass *RC = MRI.getRegClassOrNull(Reg);
137 return RC && TRI.isSGPRClass(RC) && MRI.getType(Reg) == LLT::scalar(1);
138}
139
140std::pair<MachineInstr *, Register>
142 MachineInstr *MatchMI = MRI.getVRegDef(Src);
143 if (MatchMI->getOpcode() != Opcode)
144 return {nullptr, Register()};
145 return {MatchMI, MatchMI->getOperand(1).getReg()};
146}
147
148std::pair<GUnmerge *, int>
150 MachineInstr *ReadAnyLane = MRI.getVRegDef(Src);
151 if (ReadAnyLane->getOpcode() != AMDGPU::G_AMDGPU_READANYLANE)
152 return {nullptr, -1};
153
154 Register RALSrc = ReadAnyLane->getOperand(1).getReg();
155 if (auto *UnMerge = getOpcodeDef<GUnmerge>(RALSrc, MRI))
156 return {UnMerge, UnMerge->findRegisterDefOperandIdx(RALSrc, nullptr)};
157
158 return {nullptr, -1};
159}
160
162 // Src = G_AMDGPU_READANYLANE RALSrc
163 auto [RAL, RALSrc] = tryMatch(Src, AMDGPU::G_AMDGPU_READANYLANE);
164 if (RAL)
165 return RALSrc;
166
167 // LoVgpr, HiVgpr = G_UNMERGE_VALUES UnmergeSrc
168 // LoSgpr = G_AMDGPU_READANYLANE LoVgpr
169 // HiSgpr = G_AMDGPU_READANYLANE HiVgpr
170 // Src G_MERGE_VALUES LoSgpr, HiSgpr
171 auto *Merge = getOpcodeDef<GMergeLikeInstr>(Src, MRI);
172 if (Merge) {
173 unsigned NumElts = Merge->getNumSources();
174 auto [Unmerge, Idx] = tryMatchRALFromUnmerge(Merge->getSourceReg(0));
175 if (!Unmerge || Unmerge->getNumDefs() != NumElts || Idx != 0)
176 return {};
177
178 // Check if all elements are from same unmerge and there is no shuffling.
179 for (unsigned i = 1; i < NumElts; ++i) {
180 auto [UnmergeI, IdxI] = tryMatchRALFromUnmerge(Merge->getSourceReg(i));
181 if (UnmergeI != Unmerge || (unsigned)IdxI != i)
182 return {};
183 }
184 return Unmerge->getSourceReg();
185 }
186
187 // SrcRegIdx = G_AMDGPU_READANYLANE RALElSrc
188 // SourceReg G_MERGE_VALUES ..., SrcRegIdx, ...
189 // ..., Src, ... = G_UNMERGE_VALUES SourceReg
190 auto *UnMerge = getOpcodeDef<GUnmerge>(Src, MRI);
191 if (!UnMerge)
192 return {};
193
194 int Idx = UnMerge->findRegisterDefOperandIdx(Src, nullptr);
195 Merge = getOpcodeDef<GMergeLikeInstr>(UnMerge->getSourceReg(), MRI);
196 if (!Merge || UnMerge->getNumDefs() != Merge->getNumSources())
197 return {};
198
199 Register SrcRegIdx = Merge->getSourceReg(Idx);
200 if (MRI.getType(Src) != MRI.getType(SrcRegIdx))
201 return {};
202
203 auto [RALEl, RALElSrc] = tryMatch(SrcRegIdx, AMDGPU::G_AMDGPU_READANYLANE);
204 if (RALEl)
205 return RALElSrc;
206
207 return {};
208}
209
211 Register Src) {
212 if (Dst.isVirtual())
213 MRI.replaceRegWith(Dst, Src);
214 else
215 B.buildCopy(Dst, Src);
216}
217
219 MachineInstr &Copy) {
220 Register Dst = Copy.getOperand(0).getReg();
221 Register Src = Copy.getOperand(1).getReg();
222
223 // Skip non-vgpr Dst
224 if (Dst.isVirtual() ? (MRI.getRegBankOrNull(Dst) != VgprRB)
225 : !TRI.isVGPR(MRI, Dst))
226 return false;
227
228 // Skip physical source registers and source registers with register class
229 if (!Src.isVirtual() || MRI.getRegClassOrNull(Src))
230 return false;
231
232 Register RALDst = Src;
233 MachineInstr &SrcMI = *MRI.getVRegDef(Src);
234 if (SrcMI.getOpcode() == AMDGPU::G_BITCAST)
235 RALDst = SrcMI.getOperand(1).getReg();
236
237 Register RALSrc = getReadAnyLaneSrc(RALDst);
238 if (!RALSrc)
239 return false;
240
241 B.setInstr(Copy);
242 if (SrcMI.getOpcode() != AMDGPU::G_BITCAST) {
243 // Src = READANYLANE RALSrc Src = READANYLANE RALSrc
244 // Dst = Copy Src $Dst = Copy Src
245 // -> ->
246 // Dst = RALSrc $Dst = Copy RALSrc
247 replaceRegWithOrBuildCopy(Dst, RALSrc);
248 } else {
249 // RALDst = READANYLANE RALSrc RALDst = READANYLANE RALSrc
250 // Src = G_BITCAST RALDst Src = G_BITCAST RALDst
251 // Dst = Copy Src Dst = Copy Src
252 // -> ->
253 // NewVgpr = G_BITCAST RALDst NewVgpr = G_BITCAST RALDst
254 // Dst = NewVgpr $Dst = Copy NewVgpr
255 auto Bitcast = B.buildBitcast({VgprRB, MRI.getType(Src)}, RALSrc);
256 replaceRegWithOrBuildCopy(Dst, Bitcast.getReg(0));
257 }
258
259 eraseInstr(Copy, MRI);
260 return true;
261}
262
265 return;
266
267 Register Dst = MI.getOperand(0).getReg();
268 Register Src = MI.getOperand(1).getReg();
269 // Skip copies of physical registers.
270 if (!Dst.isVirtual() || !Src.isVirtual())
271 return;
272
273 // This is a cross bank copy, sgpr S1 to lane mask.
274 //
275 // %Src:sgpr(s1) = G_TRUNC %TruncS32Src:sgpr(s32)
276 // %Dst:lane-mask(s1) = COPY %Src:sgpr(s1)
277 // ->
278 // %BoolSrc:sgpr(s32) = G_AND %TruncS32Src:sgpr(s32), 1
279 // %Dst:lane-mask(s1) = G_AMDGPU_COPY_VCC_SCC %BoolSrc:sgpr(s32)
280 if (isLaneMask(Dst) && MRI.getRegBankOrNull(Src) == SgprRB) {
281 auto [Trunc, TruncS32Src] = tryMatch(Src, AMDGPU::G_TRUNC);
282 assert(Trunc && MRI.getType(TruncS32Src) == S32 &&
283 "sgpr S1 must be result of G_TRUNC of sgpr S32");
284
285 B.setInstr(MI);
286 // Ensure that truncated bits in BoolSrc are 0.
287 auto One = B.buildConstant({SgprRB, S32}, 1);
288 auto BoolSrc = B.buildAnd({SgprRB, S32}, TruncS32Src, One);
289 B.buildInstr(AMDGPU::G_AMDGPU_COPY_VCC_SCC, {Dst}, {BoolSrc});
290 eraseInstr(MI, MRI);
291 }
292}
293
295 // %Src:sgpr(S1) = G_TRUNC %TruncSrc
296 // %Dst = G_ANYEXT %Src:sgpr(S1)
297 // ->
298 // %Dst = G_... %TruncSrc
299 Register Dst = MI.getOperand(0).getReg();
300 Register Src = MI.getOperand(1).getReg();
301 if (MRI.getType(Src) != S1)
302 return;
303
304 auto [Trunc, TruncSrc] = tryMatch(Src, AMDGPU::G_TRUNC);
305 if (!Trunc)
306 return;
307
308 LLT DstTy = MRI.getType(Dst);
309 LLT TruncSrcTy = MRI.getType(TruncSrc);
310
311 if (DstTy == TruncSrcTy) {
312 MRI.replaceRegWith(Dst, TruncSrc);
313 eraseInstr(MI, MRI);
314 return;
315 }
316
317 B.setInstr(MI);
318
319 if (DstTy == S32 && TruncSrcTy == S64) {
320 auto Unmerge = B.buildUnmerge({SgprRB, S32}, TruncSrc);
321 MRI.replaceRegWith(Dst, Unmerge.getReg(0));
322 eraseInstr(MI, MRI);
323 return;
324 }
325
326 if (DstTy == S64 && TruncSrcTy == S32) {
327 B.buildMergeLikeInstr(MI.getOperand(0).getReg(),
328 {TruncSrc, B.buildUndef({SgprRB, S32})});
329 eraseInstr(MI, MRI);
330 return;
331 }
332
333 if (DstTy == S32 && TruncSrcTy == S16) {
334 B.buildAnyExt(Dst, TruncSrc);
335 eraseInstr(MI, MRI);
336 return;
337 }
338
339 if (DstTy == S16 && TruncSrcTy == S32) {
340 B.buildTrunc(Dst, TruncSrc);
341 eraseInstr(MI, MRI);
342 return;
343 }
344
345 llvm_unreachable("missing anyext + trunc combine");
346}
347
348// Search through MRI for virtual registers with sgpr register bank and S1 LLT.
349[[maybe_unused]] static Register getAnySgprS1(const MachineRegisterInfo &MRI) {
350 const LLT S1 = LLT::scalar(1);
351 for (unsigned i = 0; i < MRI.getNumVirtRegs(); ++i) {
353 if (MRI.def_empty(Reg) || MRI.getType(Reg) != S1)
354 continue;
355
356 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
357 if (RB && RB->getID() == AMDGPU::SGPRRegBankID) {
358 LLVM_DEBUG(dbgs() << "Warning: detected sgpr S1 register in: ";
359 MRI.getVRegDef(Reg)->dump(););
360 return Reg;
361 }
362 }
363
364 return {};
365}
366
367bool AMDGPURegBankLegalize::runOnMachineFunction(MachineFunction &MF) {
368 if (MF.getProperties().hasFailedISel())
369 return false;
370
371 // Setup the instruction builder with CSE.
372 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
374 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
375 GISelCSEInfo &CSEInfo = Wrapper.get(TPC.getCSEConfig());
376 GISelObserverWrapper Observer;
377 Observer.addObserver(&CSEInfo);
378
379 CSEMIRBuilder B(MF);
380 B.setCSEInfo(&CSEInfo);
381 B.setChangeObserver(Observer);
382
383 RAIIDelegateInstaller DelegateInstaller(MF, &Observer);
384 RAIIMFObserverInstaller MFObserverInstaller(MF, Observer);
385
388 const RegisterBankInfo &RBI = *ST.getRegBankInfo();
389 const MachineUniformityInfo &MUI =
390 getAnalysis<MachineUniformityAnalysisPass>().getUniformityInfo();
391
392 // RegBankLegalizeRules is initialized with assigning sets of IDs to opcodes.
393 const RegBankLegalizeRules &RBLRules = getRules(ST, MRI);
394
395 // Logic that does legalization based on IDs assigned to Opcode.
396 RegBankLegalizeHelper RBLHelper(B, MUI, RBI, RBLRules);
397
399
400 for (MachineBasicBlock &MBB : MF) {
401 for (MachineInstr &MI : MBB) {
402 AllInst.push_back(&MI);
403 }
404 }
405
406 for (MachineInstr *MI : AllInst) {
407 if (!MI->isPreISelOpcode())
408 continue;
409
410 unsigned Opc = MI->getOpcode();
411 // Insert point for use operands needs some calculation.
412 if (Opc == AMDGPU::G_PHI) {
413 RBLHelper.applyMappingPHI(*MI);
414 continue;
415 }
416
417 // Opcodes that support pretty much all combinations of reg banks and LLTs
418 // (except S1). There is no point in writing rules for them.
419 if (Opc == AMDGPU::G_BUILD_VECTOR || Opc == AMDGPU::G_UNMERGE_VALUES ||
420 Opc == AMDGPU::G_MERGE_VALUES || Opc == AMDGPU::G_BITCAST) {
421 RBLHelper.applyMappingTrivial(*MI);
422 continue;
423 }
424
425 // Opcodes that also support S1.
426 if (Opc == G_FREEZE &&
427 MRI.getType(MI->getOperand(0).getReg()) != LLT::scalar(1)) {
428 RBLHelper.applyMappingTrivial(*MI);
429 continue;
430 }
431
432 if ((Opc == AMDGPU::G_CONSTANT || Opc == AMDGPU::G_FCONSTANT ||
433 Opc == AMDGPU::G_IMPLICIT_DEF)) {
434 Register Dst = MI->getOperand(0).getReg();
435 // Non S1 types are trivially accepted.
436 if (MRI.getType(Dst) != LLT::scalar(1)) {
437 assert(MRI.getRegBank(Dst)->getID() == AMDGPU::SGPRRegBankID);
438 continue;
439 }
440
441 // S1 rules are in RegBankLegalizeRules.
442 }
443
444 RBLHelper.findRuleAndApplyMapping(*MI);
445 }
446
447 // Sgpr S1 clean up combines:
448 // - Sgpr S1(S32) to sgpr S1(S32) Copy: anyext + trunc combine.
449 // In RegBankLegalize 'S1 Dst' are legalized into S32 as
450 // 'S1Dst = Trunc S32Dst' and 'S1 Src' into 'S32Src = Anyext S1Src'.
451 // S1 Truncs and Anyexts that come from legalizer, that can have non-S32
452 // types e.g. S16 = Anyext S1 or S1 = Trunc S64, will also be cleaned up.
453 // - Sgpr S1(S32) to vcc Copy: G_AMDGPU_COPY_VCC_SCC combine.
454 // Divergent instruction uses sgpr S1 as input that should be lane mask(vcc)
455 // Legalizing this use creates sgpr S1(S32) to vcc Copy.
456
457 // Note: Remaining S1 copies, S1s are either sgpr S1(S32) or vcc S1:
458 // - Vcc to vcc Copy: nothing to do here, just a regular copy.
459 // - Vcc to sgpr S1 Copy: Should not exist in a form of COPY instruction(*).
460 // Note: For 'uniform-in-vcc to sgpr-S1 copy' G_AMDGPU_COPY_SCC_VCC is used
461 // instead. When only available instruction creates vcc result, use of
462 // UniformInVcc results in creating G_AMDGPU_COPY_SCC_VCC.
463
464 // (*)Explanation for 'sgpr S1(uniform) = COPY vcc(divergent)':
465 // Copy from divergent to uniform register indicates an error in either:
466 // - Uniformity analysis: Uniform instruction has divergent input. If one of
467 // the inputs is divergent, instruction should be divergent!
468 // - RegBankLegalizer not executing in waterfall loop (missing implementation)
469
470 AMDGPURegBankLegalizeCombiner Combiner(B, *ST.getRegisterInfo(), RBI);
471
472 for (MachineBasicBlock &MBB : MF) {
474 if (MI.getOpcode() == AMDGPU::COPY) {
475 Combiner.tryCombineCopy(MI);
476 continue;
477 }
478 if (MI.getOpcode() == AMDGPU::G_ANYEXT) {
479 Combiner.tryCombineS1AnyExt(MI);
480 continue;
481 }
482 }
483 }
484
486 "Registers with sgpr reg bank and S1 LLT are not legal after "
487 "AMDGPURegBankLegalize. Should lower to sgpr S32");
488
489 return true;
490}
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
AMDGPU Register Bank Legalize
static Register getAnySgprS1(const MachineRegisterInfo &MRI)
const RegBankLegalizeRules & getRules(const GCNSubtarget &ST, MachineRegisterInfo &MRI)
#define DEBUG_TYPE
Lower G_ instructions that can't be inst-selected with register bank assignment from AMDGPURegBankSel...
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.
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
AMD GCN specific subclass of TargetSubtarget.
Declares convenience wrapper classes for interpreting MachineInstr instances as specific generic oper...
IRTranslator LLVM IR MI
Register const TargetRegisterInfo * TRI
Machine IR instance of the generic uniformity analysis.
#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.
std::pair< GUnmerge *, int > tryMatchRALFromUnmerge(Register Src)
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)
Register getReadAnyLaneSrc(Register Src)
bool tryEliminateReadAnyLane(MachineInstr &Copy)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
Defines a builder that does CSE of MachineInstructions using GISelCSEInfo.
Definition: CSEMIRBuilder.h:39
Combiner implementation.
Definition: Combiner.h:34
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition: DenseMap.h:245
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:314
The actual analysis pass wrapper.
Definition: CSEInfo.h:229
Simple wrapper that does the following.
Definition: CSEInfo.h:211
The CSE Analysis object.
Definition: CSEInfo.h:71
Simple wrapper observer that takes several observers, and calls each one for each event.
void addObserver(GISelChangeObserver *O)
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:43
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
virtual MachineFunctionProperties getClearedProperties() const
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
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.
MachineInstrBuilder buildUnmerge(ArrayRef< LLT > Res, const SrcOp &Op)
Build and insert Res0, ... = G_UNMERGE_VALUES Op.
MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
MachineInstrBuilder buildMergeLikeInstr(const DstOp &Res, ArrayRef< Register > Ops)
Build and insert Res = G_MERGE_VALUES Op0, ... or Res = G_BUILD_VECTOR Op0, ... or Res = G_CONCAT_VEC...
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
MachineInstrBuilder buildBitcast(const DstOp &Dst, const SrcOp &Src)
Build and insert Dst = G_BITCAST Src.
MachineInstrBuilder buildCopy(const DstOp &Res, const SrcOp &Op)
Build and insert Res = COPY Op.
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
Representation of each machine instruction.
Definition: MachineInstr.h:72
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:587
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:595
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.
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...
const TargetRegisterClass * getRegClassOrNull(Register Reg) const
Return the register class of Reg, or null if Reg has not been assigned a register class yet.
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
Legacy analysis pass which computes a MachineUniformityInfo.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Definition: Pass.cpp:85
A simple RAII based Delegate installer.
A simple RAII based Observer installer.
Holds all the information related to register banks.
This class implements the register bank concept.
Definition: RegisterBank.h:29
unsigned getID() const
Get the identifier of this register bank.
Definition: RegisterBank.h:46
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
bool isVGPR(const MachineRegisterInfo &MRI, Register Reg) const
static bool isSGPRClass(const TargetRegisterClass *RC)
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
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
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
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:663
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:207
FunctionPass * createAMDGPURegBankLegalizePass()
LLVM_ABI void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
Definition: Utils.cpp:1718
char & AMDGPURegBankLegalizeID