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"
36
37#define DEBUG_TYPE "amdgpu-reg-bank-legalize"
38
39using namespace llvm;
40using namespace AMDGPU;
41using namespace llvm::MIPatternMatch;
42
43namespace {
44
45// AMDGPU-specific pattern matchers
46template <typename SrcTy>
48m_GAMDGPUReadAnyLane(const SrcTy &Src) {
50}
51
52class AMDGPURegBankLegalizeLegacy : public MachineFunctionPass {
53public:
54 static char ID;
55
56public:
57 AMDGPURegBankLegalizeLegacy() : MachineFunctionPass(ID) {}
58
59 bool runOnMachineFunction(MachineFunction &MF) override;
60
61 StringRef getPassName() const override {
62 return "AMDGPU Register Bank Legalize";
63 }
64
65 void getAnalysisUsage(AnalysisUsage &AU) const override {
71 }
72
73 // If there were no phis and we do waterfall expansion machine verifier would
74 // fail.
75 MachineFunctionProperties getClearedProperties() const override {
76 return MachineFunctionProperties().setNoPHIs();
77 }
78};
79
80} // End anonymous namespace.
81
82INITIALIZE_PASS_BEGIN(AMDGPURegBankLegalizeLegacy, DEBUG_TYPE,
83 "AMDGPU Register Bank Legalize", false, false)
88INITIALIZE_PASS_END(AMDGPURegBankLegalizeLegacy, DEBUG_TYPE,
89 "AMDGPU Register Bank Legalize", false, false)
90
91char AMDGPURegBankLegalizeLegacy::ID = 0;
92
93char &llvm::AMDGPURegBankLegalizeLegacyID = AMDGPURegBankLegalizeLegacy::ID;
94
96 return new AMDGPURegBankLegalizeLegacy();
97}
98
100 MachineRegisterInfo &MRI) {
101 static std::mutex GlobalMutex;
103 CacheForRuleSet;
104 std::lock_guard<std::mutex> Lock(GlobalMutex);
105 auto [It, Inserted] = CacheForRuleSet.try_emplace(ST.getGeneration());
106 if (Inserted)
107 It->second = std::make_unique<RegBankLegalizeRules>(ST, MRI);
108 else
109 It->second->refreshRefs(ST, MRI);
110 return *It->second;
111}
112
116 const SIRegisterInfo &TRI;
117 const RegisterBank *SgprRB;
118 const RegisterBank *VgprRB;
119 const RegisterBank *VccRB;
120
121 static constexpr LLT S1 = LLT::scalar(1);
122 static constexpr LLT S16 = LLT::scalar(16);
123 static constexpr LLT S32 = LLT::scalar(32);
124 static constexpr LLT S64 = LLT::scalar(64);
125
126public:
128 const RegisterBankInfo &RBI)
129 : B(B), MRI(*B.getMRI()), TRI(TRI),
130 SgprRB(&RBI.getRegBank(AMDGPU::SGPRRegBankID)),
131 VgprRB(&RBI.getRegBank(AMDGPU::VGPRRegBankID)),
132 VccRB(&RBI.getRegBank(AMDGPU::VCCRegBankID)) {};
133
134 bool isLaneMask(Register Reg);
135 std::pair<MachineInstr *, Register> tryMatch(Register Src, unsigned Opcode);
140
144};
145
147 const RegisterBank *RB = MRI.getRegBankOrNull(Reg);
148 if (RB && RB->getID() == AMDGPU::VCCRegBankID)
149 return true;
150
151 const TargetRegisterClass *RC = MRI.getRegClassOrNull(Reg);
152 return RC && TRI.isSGPRClass(RC) && MRI.getType(Reg) == LLT::scalar(1);
153}
154
155std::pair<MachineInstr *, Register>
157 MachineInstr *MatchMI = MRI.getVRegDef(Src);
158 if (MatchMI->getOpcode() != Opcode)
159 return {nullptr, Register()};
160 return {MatchMI, MatchMI->getOperand(1).getReg()};
161}
162
163// Check if all registers are from same unmerge and there is no shuffling.
164// Returns the unmerge source if both conditions are met.
166 SmallVectorImpl<Register> &DefRegs) {
167 auto *UnMerge = getOpcodeDef<GUnmerge>(DefRegs[0], MRI);
168 if (!UnMerge || UnMerge->getNumDefs() != DefRegs.size())
169 return {};
170 for (unsigned I = 1; I < DefRegs.size(); ++I) {
171 if (UnMerge->getReg(I) != DefRegs[I])
172 return {};
173 }
174 return UnMerge->getSourceReg();
175}
176
177// Check if all merge sources are readanylanes and return the readanylane
178// sources if they are.
181 SmallVector<Register> ReadAnyLaneSrcs;
182 for (unsigned i = 0; i < Merge->getNumSources(); ++i) {
183 Register Src;
184 if (!mi_match(Merge->getSourceReg(i), MRI,
185 m_GAMDGPUReadAnyLane(m_Reg(Src))))
186 return {};
187 ReadAnyLaneSrcs.push_back(Src);
188 }
189 return ReadAnyLaneSrcs;
190}
191
194 // Src = G_AMDGPU_READANYLANE RALSrc
195 Register RALSrc;
196 if (mi_match(Src, MRI, m_GAMDGPUReadAnyLane(m_Reg(RALSrc))))
197 return {RALSrc};
198
199 // RALSrc = G_ANYEXT S16Src
200 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
201 // Src = G_TRUNC TruncSrc
202 if (mi_match(Src, MRI,
203 m_GTrunc(m_GAMDGPUReadAnyLane(m_GAnyExt(m_Reg(RALSrc)))))) {
204 return {RALSrc};
205 }
206
207 // TruncSrc = G_AMDGPU_READANYLANE RALSrc
208 // AextSrc = G_TRUNC TruncSrc
209 // Src = G_ANYEXT AextSrc
210 if (mi_match(Src, MRI,
211 m_GAnyExt(m_GTrunc(m_GAMDGPUReadAnyLane(m_Reg(RALSrc)))))) {
212 return {RALSrc};
213 }
214
215 // Sgpr0 = G_AMDGPU_READANYLANE Vgpr0
216 // Sgpr1 = G_AMDGPU_READANYLANE Vgpr1
217 // ...
218 // Src = G_MERGE_LIKE Sgpr0, Sgpr1, ...
219 // Dst = COPY Src
220 if (auto *Merge = getOpcodeDef<GMergeLikeInstr>(Src, MRI)) {
222 if (ReadAnyLaneSrcs.empty())
223 return {};
224
225 // Vgpr0, Vgpr1, ... = G_UNMERGE_VALUES UnmergeSrc
226 if (Register UnmergeSrc = tryMatchUnmergeDefs(ReadAnyLaneSrcs))
227 return {UnmergeSrc};
228
229 // Multiple ReadAnyLane vgpr sources, need to merge Vgpr0, Vgpr1, ...
230 return ReadAnyLaneSrcs;
231 }
232
233 // SrcRegIdx = G_AMDGPU_READANYLANE RALElSrc
234 // SourceReg G_MERGE_VALUES ..., SrcRegIdx, ...
235 // ..., Src, ... = G_UNMERGE_VALUES SourceReg
236 auto *UnMerge = getOpcodeDef<GUnmerge>(Src, MRI);
237 if (!UnMerge)
238 return {};
239
240 int Idx = UnMerge->findRegisterDefOperandIdx(Src, nullptr);
241 auto *Merge = getOpcodeDef<GMergeLikeInstr>(UnMerge->getSourceReg(), MRI);
242 if (!Merge || UnMerge->getNumDefs() != Merge->getNumSources())
243 return {};
244
245 Register SrcRegIdx = Merge->getSourceReg(Idx);
246 if (MRI.getType(Src) != MRI.getType(SrcRegIdx))
247 return {};
248
249 auto [RALEl, RALElSrc] = tryMatch(SrcRegIdx, AMDGPU::G_AMDGPU_READANYLANE);
250 if (RALEl)
251 return {RALElSrc};
252
253 return {};
254}
255
257 Register Src) {
258 if (Dst.isVirtual())
259 MRI.replaceRegWith(Dst, Src);
260 else
261 B.buildCopy(Dst, Src);
262}
263
265 MachineInstr &Copy) {
266 Register Dst = Copy.getOperand(0).getReg();
267 Register Src = Copy.getOperand(1).getReg();
268
269 // Skip non-vgpr Dst
270 if (Dst.isVirtual() ? (MRI.getRegBankOrNull(Dst) != VgprRB)
271 : !TRI.isVGPR(MRI, Dst))
272 return false;
273
274 // Skip physical source registers and source registers with register class
275 if (!Src.isVirtual() || MRI.getRegClassOrNull(Src))
276 return false;
277
278 Register RALDst = Src;
279 bool IsBitcast = mi_match(Src, MRI, m_GBitcast(m_Reg(RALDst)));
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 (!IsBitcast) {
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
421static bool
423 function_ref<GISelCSEInfo *()> GetCSEInfo,
424 function_ref<const MachineUniformityInfo *()> GetMUI,
425 function_ref<GISelValueTracking *()> GetVT) {
426 if (MF.getProperties().hasFailedISel())
427 return false;
428
429 GISelCSEInfo &CSEInfo = *GetCSEInfo();
430 const MachineUniformityInfo &MUI = *GetMUI();
431 GISelValueTracking &VT = *GetVT();
432
433 // Setup the instruction builder with CSE.
434 GISelObserverWrapper Observer;
435 Observer.addObserver(&CSEInfo);
436
437 CSEMIRBuilder B(MF);
438 B.setCSEInfo(&CSEInfo);
439 B.setChangeObserver(Observer);
440
441 RAIIDelegateInstaller DelegateInstaller(MF, &Observer);
442 RAIIMFObserverInstaller MFObserverInstaller(MF, Observer);
443
444 const GCNSubtarget &ST = MF.getSubtarget<GCNSubtarget>();
446 const RegisterBankInfo &RBI = *ST.getRegBankInfo();
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) {
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}
514
515bool AMDGPURegBankLegalizeLegacy::runOnMachineFunction(MachineFunction &MF) {
516 return runRegBankLegalize(
517 MF,
518 [&]() {
519 GISelCSEAnalysisWrapper &Wrapper =
520 getAnalysis<GISelCSEAnalysisWrapperPass>().getCSEWrapper();
521 return &Wrapper.get(getAnalysis<TargetPassConfig>().getCSEConfig());
522 },
523 [&]() {
524 return &getAnalysis<MachineUniformityAnalysisPass>()
525 .getUniformityInfo();
526 },
527 [&]() {
528 return &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
529 });
530}
531
532PreservedAnalyses
535 MFPropsModifier _(*this, MF);
536
538 MF, [&]() { return MFAM.getResult<GISelCSEAnalysis>(MF).get(); },
539 [&]() { return &MFAM.getResult<MachineUniformityAnalysis>(MF); },
540 [&]() { return &MFAM.getResult<GISelValueTrackingAnalysis>(MF); }))
541 return PreservedAnalyses::all();
542
544}
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)
static bool runRegBankLegalize(MachineFunction &MF, function_ref< GISelCSEInfo *()> GetCSEInfo, function_ref< const MachineUniformityInfo *()> GetMUI, function_ref< GISelValueTracking *()> GetVT)
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...
#define _
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)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
Defines a builder that does CSE of MachineInstructions using GISelCSEInfo.
Combiner implementation.
Definition Combiner.h:33
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:244
The CSE Analysis object.
Definition CSEInfo.h:72
Simple wrapper observer that takes several observers, and calls each one for each event.
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".
An RAII based helper class to modify MachineFunctionProperties when running pass.
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.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
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.
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.
An efficient, type-erasing, non-owning reference to a callable.
#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
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
char & AMDGPURegBankLegalizeLegacyID
LLVM_ABI void eraseInstr(MachineInstr &MI, MachineRegisterInfo &MRI, LostDebugLocObserver *LocObserver=nullptr)
Definition Utils.cpp:1670
FunctionPass * createAMDGPURegBankLegalizeLegacyPass()
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58