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);
131 std::pair<GUnmerge *, int> tryMatchRALFromUnmerge(Register Src);
134
138};
139
141 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
142 if (RB && RB->getID() == AMDGPU::VCCRegBankID)
143 return true;
144
145 const TargetRegisterClass *RC = MRI.getRegClassOrNull(Reg);
146 return RC && TRI.isSGPRClass(RC) && MRI.getType(Reg) == LLT::scalar(1);
147}
148
149std::pair<MachineInstr *, Register>
151 MachineInstr *MatchMI = MRI.getVRegDef(Src);
152 if (MatchMI->getOpcode() != Opcode)
153 return {nullptr, Register()};
154 return {MatchMI, MatchMI->getOperand(1).getReg()};
155}
156
157std::pair<GUnmerge *, int>
159 MachineInstr *ReadAnyLane = MRI.getVRegDef(Src);
160 if (ReadAnyLane->getOpcode() != AMDGPU::G_AMDGPU_READANYLANE)
161 return {nullptr, -1};
162
163 Register RALSrc = ReadAnyLane->getOperand(1).getReg();
164 if (auto *UnMerge = getOpcodeDef<GUnmerge>(RALSrc, MRI))
165 return {UnMerge, UnMerge->findRegisterDefOperandIdx(RALSrc, nullptr)};
166
167 return {nullptr, -1};
168}
169
171 // Src = G_AMDGPU_READANYLANE RALSrc
172 Register RALSrc;
173 if (mi_match(Src, MRI, m_GAMDGPUReadAnyLane(m_Reg(RALSrc))))
174 return RALSrc;
175
176 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
177 // AextSrc = G_TRUNC TruncSrc
178 // Src = G_ANYEXT AextSrc
179 if (mi_match(Src, MRI,
180 m_GAnyExt(m_GTrunc(m_GAMDGPUReadAnyLane(m_Reg(RALSrc)))))) {
181 return RALSrc;
182 }
183
184 // LoVgpr, HiVgpr = G_UNMERGE_VALUES UnmergeSrc
185 // LoSgpr = G_AMDGPU_READANYLANE LoVgpr
186 // HiSgpr = G_AMDGPU_READANYLANE HiVgpr
187 // Src G_MERGE_VALUES LoSgpr, HiSgpr
188 auto *Merge = getOpcodeDef<GMergeLikeInstr>(Src, MRI);
189 if (Merge) {
190 unsigned NumElts = Merge->getNumSources();
191 auto [Unmerge, Idx] = tryMatchRALFromUnmerge(Merge->getSourceReg(0));
192 if (!Unmerge || Unmerge->getNumDefs() != NumElts || Idx != 0)
193 return {};
194
195 // Check if all elements are from same unmerge and there is no shuffling.
196 for (unsigned i = 1; i < NumElts; ++i) {
197 auto [UnmergeI, IdxI] = tryMatchRALFromUnmerge(Merge->getSourceReg(i));
198 if (UnmergeI != Unmerge || (unsigned)IdxI != i)
199 return {};
200 }
201 return Unmerge->getSourceReg();
202 }
203
204 // SrcRegIdx = G_AMDGPU_READANYLANE RALElSrc
205 // SourceReg G_MERGE_VALUES ..., SrcRegIdx, ...
206 // ..., Src, ... = G_UNMERGE_VALUES SourceReg
207 auto *UnMerge = getOpcodeDef<GUnmerge>(Src, MRI);
208 if (!UnMerge)
209 return {};
210
211 int Idx = UnMerge->findRegisterDefOperandIdx(Src, nullptr);
212 Merge = getOpcodeDef<GMergeLikeInstr>(UnMerge->getSourceReg(), MRI);
213 if (!Merge || UnMerge->getNumDefs() != Merge->getNumSources())
214 return {};
215
216 Register SrcRegIdx = Merge->getSourceReg(Idx);
217 if (MRI.getType(Src) != MRI.getType(SrcRegIdx))
218 return {};
219
220 auto [RALEl, RALElSrc] = tryMatch(SrcRegIdx, AMDGPU::G_AMDGPU_READANYLANE);
221 if (RALEl)
222 return RALElSrc;
223
224 return {};
225}
226
228 Register Src) {
229 if (Dst.isVirtual())
230 MRI.replaceRegWith(Dst, Src);
231 else
232 B.buildCopy(Dst, Src);
233}
234
236 MachineInstr &Copy) {
237 Register Dst = Copy.getOperand(0).getReg();
238 Register Src = Copy.getOperand(1).getReg();
239
240 // Skip non-vgpr Dst
241 if (Dst.isVirtual() ? (MRI.getRegBankOrNull(Dst) != VgprRB)
242 : !TRI.isVGPR(MRI, Dst))
243 return false;
244
245 // Skip physical source registers and source registers with register class
246 if (!Src.isVirtual() || MRI.getRegClassOrNull(Src))
247 return false;
248
249 Register RALDst = Src;
250 MachineInstr &SrcMI = *MRI.getVRegDef(Src);
251 if (SrcMI.getOpcode() == AMDGPU::G_BITCAST)
252 RALDst = SrcMI.getOperand(1).getReg();
253
254 Register RALSrc = getReadAnyLaneSrc(RALDst);
255 if (!RALSrc)
256 return false;
257
258 B.setInstr(Copy);
259 if (SrcMI.getOpcode() != AMDGPU::G_BITCAST) {
260 // Src = READANYLANE RALSrc Src = READANYLANE RALSrc
261 // Dst = Copy Src $Dst = Copy Src
262 // -> ->
263 // Dst = RALSrc $Dst = Copy RALSrc
264 replaceRegWithOrBuildCopy(Dst, RALSrc);
265 } else {
266 // RALDst = READANYLANE RALSrc RALDst = READANYLANE RALSrc
267 // Src = G_BITCAST RALDst Src = G_BITCAST RALDst
268 // Dst = Copy Src Dst = Copy Src
269 // -> ->
270 // NewVgpr = G_BITCAST RALDst NewVgpr = G_BITCAST RALDst
271 // Dst = NewVgpr $Dst = Copy NewVgpr
272 auto Bitcast = B.buildBitcast({VgprRB, MRI.getType(Src)}, RALSrc);
273 replaceRegWithOrBuildCopy(Dst, Bitcast.getReg(0));
274 }
275
276 eraseInstr(Copy, MRI);
277 return true;
278}
279
282 return;
283
284 Register Dst = MI.getOperand(0).getReg();
285 Register Src = MI.getOperand(1).getReg();
286 // Skip copies of physical registers.
287 if (!Dst.isVirtual() || !Src.isVirtual())
288 return;
289
290 // This is a cross bank copy, sgpr S1 to lane mask.
291 //
292 // %Src:sgpr(s1) = G_TRUNC %TruncS32Src:sgpr(s32)
293 // %Dst:lane-mask(s1) = COPY %Src:sgpr(s1)
294 // ->
295 // %BoolSrc:sgpr(s32) = G_AND %TruncS32Src:sgpr(s32), 1
296 // %Dst:lane-mask(s1) = G_AMDGPU_COPY_VCC_SCC %BoolSrc:sgpr(s32)
297 if (isLaneMask(Dst) && MRI.getRegBankOrNull(Src) == SgprRB) {
298 auto [Trunc, TruncS32Src] = tryMatch(Src, AMDGPU::G_TRUNC);
299 assert(Trunc && MRI.getType(TruncS32Src) == S32 &&
300 "sgpr S1 must be result of G_TRUNC of sgpr S32");
301
302 B.setInstr(MI);
303 // Ensure that truncated bits in BoolSrc are 0.
304 auto One = B.buildConstant({SgprRB, S32}, 1);
305 auto BoolSrc = B.buildAnd({SgprRB, S32}, TruncS32Src, One);
306 B.buildInstr(AMDGPU::G_AMDGPU_COPY_VCC_SCC, {Dst}, {BoolSrc});
307 eraseInstr(MI, MRI);
308 }
309}
310
312 // %Src:sgpr(S1) = G_TRUNC %TruncSrc
313 // %Dst = G_ANYEXT %Src:sgpr(S1)
314 // ->
315 // %Dst = G_... %TruncSrc
316 Register Dst = MI.getOperand(0).getReg();
317 Register Src = MI.getOperand(1).getReg();
318 if (MRI.getType(Src) != S1)
319 return;
320
321 auto [Trunc, TruncSrc] = tryMatch(Src, AMDGPU::G_TRUNC);
322 if (!Trunc)
323 return;
324
325 LLT DstTy = MRI.getType(Dst);
326 LLT TruncSrcTy = MRI.getType(TruncSrc);
327
328 if (DstTy == TruncSrcTy) {
329 MRI.replaceRegWith(Dst, TruncSrc);
330 eraseInstr(MI, MRI);
331 return;
332 }
333
334 B.setInstr(MI);
335
336 if (DstTy == S32 && TruncSrcTy == S64) {
337 auto Unmerge = B.buildUnmerge({SgprRB, S32}, TruncSrc);
338 MRI.replaceRegWith(Dst, Unmerge.getReg(0));
339 eraseInstr(MI, MRI);
340 return;
341 }
342
343 if (DstTy == S64 && TruncSrcTy == S32) {
344 B.buildMergeLikeInstr(MI.getOperand(0).getReg(),
345 {TruncSrc, B.buildUndef({SgprRB, S32})});
346 eraseInstr(MI, MRI);
347 return;
348 }
349
350 if (DstTy == S32 && TruncSrcTy == S16) {
351 B.buildAnyExt(Dst, TruncSrc);
352 eraseInstr(MI, MRI);
353 return;
354 }
355
356 if (DstTy == S16 && TruncSrcTy == S32) {
357 B.buildTrunc(Dst, TruncSrc);
358 eraseInstr(MI, MRI);
359 return;
360 }
361
362 llvm_unreachable("missing anyext + trunc combine");
363}
364
365// Search through MRI for virtual registers with sgpr register bank and S1 LLT.
366[[maybe_unused]] static Register getAnySgprS1(const MachineRegisterInfo &MRI) {
367 const LLT S1 = LLT::scalar(1);
368 for (unsigned i = 0; i < MRI.getNumVirtRegs(); ++i) {
370 if (MRI.def_empty(Reg) || MRI.getType(Reg) != S1)
371 continue;
372
373 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
374 if (RB && RB->getID() == AMDGPU::SGPRRegBankID) {
375 LLVM_DEBUG(dbgs() << "Warning: detected sgpr S1 register in: ";
376 MRI.getVRegDef(Reg)->dump(););
377 return Reg;
378 }
379 }
380
381 return {};
382}
383
384bool AMDGPURegBankLegalize::runOnMachineFunction(MachineFunction &MF) {
385 if (MF.getProperties().hasFailedISel())
386 return false;
387
388 // Setup the instruction builder with CSE.
389 const TargetPassConfig &TPC = getAnalysis<TargetPassConfig>();
390 GISelCSEAnalysisWrapper &Wrapper =
391 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
392 GISelCSEInfo &CSEInfo = Wrapper.get(TPC.getCSEConfig());
393 GISelObserverWrapper Observer;
394 Observer.addObserver(&CSEInfo);
395
396 CSEMIRBuilder B(MF);
397 B.setCSEInfo(&CSEInfo);
398 B.setChangeObserver(Observer);
399
400 RAIIDelegateInstaller DelegateInstaller(MF, &Observer);
401 RAIIMFObserverInstaller MFObserverInstaller(MF, Observer);
402
403 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
404 MachineRegisterInfo &MRI = MF.getRegInfo();
405 const RegisterBankInfo &RBI = *ST.getRegBankInfo();
406 const MachineUniformityInfo &MUI =
407 getAnalysis<MachineUniformityAnalysisPass>().getUniformityInfo();
408
409 // RegBankLegalizeRules is initialized with assigning sets of IDs to opcodes.
410 const RegBankLegalizeRules &RBLRules = getRules(ST, MRI);
411
412 // Logic that does legalization based on IDs assigned to Opcode.
413 RegBankLegalizeHelper RBLHelper(B, MUI, RBI, RBLRules);
414
416
417 for (MachineBasicBlock &MBB : MF) {
418 for (MachineInstr &MI : MBB) {
419 AllInst.push_back(&MI);
420 }
421 }
422
423 for (MachineInstr *MI : AllInst) {
424 if (!MI->isPreISelOpcode())
425 continue;
426
427 unsigned Opc = MI->getOpcode();
428 // Insert point for use operands needs some calculation.
429 if (Opc == AMDGPU::G_PHI) {
430 RBLHelper.applyMappingPHI(*MI);
431 continue;
432 }
433
434 // Opcodes that support pretty much all combinations of reg banks and LLTs
435 // (except S1). There is no point in writing rules for them.
436 if (Opc == AMDGPU::G_BUILD_VECTOR || Opc == AMDGPU::G_UNMERGE_VALUES ||
437 Opc == AMDGPU::G_MERGE_VALUES || Opc == AMDGPU::G_BITCAST) {
438 RBLHelper.applyMappingTrivial(*MI);
439 continue;
440 }
441
442 // Opcodes that also support S1.
443 if (Opc == G_FREEZE &&
444 MRI.getType(MI->getOperand(0).getReg()) != LLT::scalar(1)) {
445 RBLHelper.applyMappingTrivial(*MI);
446 continue;
447 }
448
449 if ((Opc == AMDGPU::G_CONSTANT || Opc == AMDGPU::G_FCONSTANT ||
450 Opc == AMDGPU::G_IMPLICIT_DEF)) {
451 Register Dst = MI->getOperand(0).getReg();
452 // Non S1 types are trivially accepted.
453 if (MRI.getType(Dst) != LLT::scalar(1)) {
454 assert(MRI.getRegBank(Dst)->getID() == AMDGPU::SGPRRegBankID);
455 continue;
456 }
457
458 // S1 rules are in RegBankLegalizeRules.
459 }
460
461 RBLHelper.findRuleAndApplyMapping(*MI);
462 }
463
464 // Sgpr S1 clean up combines:
465 // - Sgpr S1(S32) to sgpr S1(S32) Copy: anyext + trunc combine.
466 // In RegBankLegalize 'S1 Dst' are legalized into S32 as
467 // 'S1Dst = Trunc S32Dst' and 'S1 Src' into 'S32Src = Anyext S1Src'.
468 // S1 Truncs and Anyexts that come from legalizer, that can have non-S32
469 // types e.g. S16 = Anyext S1 or S1 = Trunc S64, will also be cleaned up.
470 // - Sgpr S1(S32) to vcc Copy: G_AMDGPU_COPY_VCC_SCC combine.
471 // Divergent instruction uses sgpr S1 as input that should be lane mask(vcc)
472 // Legalizing this use creates sgpr S1(S32) to vcc Copy.
473
474 // Note: Remaining S1 copies, S1s are either sgpr S1(S32) or vcc S1:
475 // - Vcc to vcc Copy: nothing to do here, just a regular copy.
476 // - Vcc to sgpr S1 Copy: Should not exist in a form of COPY instruction(*).
477 // Note: For 'uniform-in-vcc to sgpr-S1 copy' G_AMDGPU_COPY_SCC_VCC is used
478 // instead. When only available instruction creates vcc result, use of
479 // UniformInVcc results in creating G_AMDGPU_COPY_SCC_VCC.
480
481 // (*)Explanation for 'sgpr S1(uniform) = COPY vcc(divergent)':
482 // Copy from divergent to uniform register indicates an error in either:
483 // - Uniformity analysis: Uniform instruction has divergent input. If one of
484 // the inputs is divergent, instruction should be divergent!
485 // - RegBankLegalizer not executing in waterfall loop (missing implementation)
486
487 AMDGPURegBankLegalizeCombiner Combiner(B, *ST.getRegisterInfo(), RBI);
488
489 for (MachineBasicBlock &MBB : MF) {
490 for (MachineInstr &MI : make_early_inc_range(MBB)) {
491 if (MI.getOpcode() == AMDGPU::COPY) {
492 Combiner.tryCombineCopy(MI);
493 continue;
494 }
495 if (MI.getOpcode() == AMDGPU::G_ANYEXT) {
496 Combiner.tryCombineS1AnyExt(MI);
497 continue;
498 }
499 }
500 }
501
503 "Registers with sgpr reg bank and S1 LLT are not legal after "
504 "AMDGPURegBankLegalize. Should lower to sgpr S32");
505
506 return true;
507}
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
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.
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)
bool tryEliminateReadAnyLane(MachineInstr &Copy)
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:248
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)
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:19
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition Register.h:67
void push_back(const T &Elt)
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:651
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:1719
char & AMDGPURegBankLegalizeID