LLVM 24.0.0git
AMDGPUPostLegalizerCombiner.cpp
Go to the documentation of this file.
1//=== lib/CodeGen/GlobalISel/AMDGPUPostLegalizerCombiner.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// This pass does combining of machine instructions at the generic MI level,
10// after the legalizer.
11//
12//===----------------------------------------------------------------------===//
13
14#include "AMDGPU.h"
16#include "AMDGPULegalizerInfo.h"
17#include "GCNSubtarget.h"
28#include "llvm/IR/IntrinsicsAMDGPU.h"
30
31#define GET_GICOMBINER_DEPS
32#include "AMDGPUGenPreLegalizeGICombiner.inc"
33#undef GET_GICOMBINER_DEPS
34
35#define DEBUG_TYPE "amdgpu-postlegalizer-combiner"
36
37using namespace llvm;
38using namespace MIPatternMatch;
39
40namespace {
41#define GET_GICOMBINER_TYPES
42#include "AMDGPUGenPostLegalizeGICombiner.inc"
43#undef GET_GICOMBINER_TYPES
44
45class AMDGPUPostLegalizerCombinerImpl : public Combiner {
46protected:
47 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig;
48 const GCNSubtarget &STI;
49 const SIInstrInfo &TII;
50 // TODO: Make CombinerHelper methods const.
51 mutable AMDGPUCombinerHelper Helper;
52
53public:
54 AMDGPUPostLegalizerCombinerImpl(
56 GISelCSEInfo *CSEInfo,
57 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig,
58 const GCNSubtarget &STI, MachineDominatorTree *MDT,
59 const LegalizerInfo *LI);
60
61 static const char *getName() { return "AMDGPUPostLegalizerCombinerImpl"; }
62
63 bool tryCombineAllImpl(MachineInstr &I) const;
64 bool tryCombineAll(MachineInstr &I) const override;
65
66 struct FMinFMaxLegacyInfo {
70 };
71
72 // TODO: Make sure fmin_legacy/fmax_legacy don't canonicalize
73 bool matchFMinFMaxLegacy(MachineInstr &MI, MachineInstr &FCmp,
74 FMinFMaxLegacyInfo &Info) const;
75 void applySelectFCmpToFMinFMaxLegacy(MachineInstr &MI,
76 const FMinFMaxLegacyInfo &Info) const;
77
78 bool matchUCharToFloat(MachineInstr &MI) const;
79 void applyUCharToFloat(MachineInstr &MI) const;
80
81 bool matchFDivSqrtToRsqF16(MachineInstr &MI) const;
82 void applyFDivSqrtToRsqF16(MachineInstr &MI, const Register &X) const;
83
84 // FIXME: Should be able to have 2 separate matchdatas rather than custom
85 // struct boilerplate.
86 struct CvtF32UByteMatchInfo {
87 Register CvtVal;
88 unsigned ShiftOffset;
89 };
90
91 bool matchCvtF32UByteN(MachineInstr &MI,
92 CvtF32UByteMatchInfo &MatchInfo) const;
93 void applyCvtF32UByteN(MachineInstr &MI,
94 const CvtF32UByteMatchInfo &MatchInfo) const;
95
96 bool matchRemoveFcanonicalize(MachineInstr &MI) const;
97
98 // Combine unsigned buffer load and signed extension instructions to generate
99 // signed buffer load instructions.
100 bool matchCombineSignExtendInReg(
101 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchInfo) const;
102 void applyCombineSignExtendInReg(
103 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchInfo) const;
104
105 // Find the s_mul_u64 instructions where the higher bits are either
106 // zero-extended or sign-extended.
107 // Replace the s_mul_u64 instructions with S_MUL_I64_I32_PSEUDO if the higher
108 // 33 bits are sign extended and with S_MUL_U64_U32_PSEUDO if the higher 32
109 // bits are zero extended.
110 bool matchCombine_s_mul_u64(MachineInstr &MI, unsigned &NewOpcode) const;
111
112private:
113#define GET_GICOMBINER_CLASS_MEMBERS
114#define AMDGPUSubtarget GCNSubtarget
115#include "AMDGPUGenPostLegalizeGICombiner.inc"
116#undef GET_GICOMBINER_CLASS_MEMBERS
117#undef AMDGPUSubtarget
118};
119
120#define GET_GICOMBINER_IMPL
121#define AMDGPUSubtarget GCNSubtarget
122#include "AMDGPUGenPostLegalizeGICombiner.inc"
123#undef AMDGPUSubtarget
124#undef GET_GICOMBINER_IMPL
125
126AMDGPUPostLegalizerCombinerImpl::AMDGPUPostLegalizerCombinerImpl(
128 GISelCSEInfo *CSEInfo,
129 const AMDGPUPostLegalizerCombinerImplRuleConfig &RuleConfig,
130 const GCNSubtarget &STI, MachineDominatorTree *MDT, const LegalizerInfo *LI)
131 : Combiner(MF, CInfo, &VT, CSEInfo), RuleConfig(RuleConfig), STI(STI),
132 TII(*STI.getInstrInfo()),
133 Helper(Observer, B, /*IsPreLegalize*/ false, &VT, MDT, LI, STI),
135#include "AMDGPUGenPostLegalizeGICombiner.inc"
137{
138}
139
140bool AMDGPUPostLegalizerCombinerImpl::tryCombineAll(MachineInstr &MI) const {
141 if (tryCombineAllImpl(MI))
142 return true;
143
144 switch (MI.getOpcode()) {
145 case TargetOpcode::G_SHL:
146 case TargetOpcode::G_LSHR:
147 case TargetOpcode::G_ASHR:
148 // On some subtargets, 64-bit shift is a quarter rate instruction. In the
149 // common case, splitting this into a move and a 32-bit shift is faster and
150 // the same code size.
151 return Helper.tryCombineShiftToUnmerge(MI, 32);
152 }
153
154 return false;
155}
156
157bool AMDGPUPostLegalizerCombinerImpl::matchFMinFMaxLegacy(
158 MachineInstr &MI, MachineInstr &FCmp, FMinFMaxLegacyInfo &Info) const {
159 if (!MRI.hasOneNonDBGUse(FCmp.getOperand(0).getReg()))
160 return false;
161
162 Info.Pred =
163 static_cast<CmpInst::Predicate>(FCmp.getOperand(1).getPredicate());
164 Info.LHS = FCmp.getOperand(2).getReg();
165 Info.RHS = FCmp.getOperand(3).getReg();
166 Register True = MI.getOperand(2).getReg();
167 Register False = MI.getOperand(3).getReg();
168
169 // TODO: Handle case where the the selected value is an fneg and the compared
170 // constant is the negation of the selected value.
171 if ((Info.LHS != True || Info.RHS != False) &&
172 (Info.LHS != False || Info.RHS != True))
173 return false;
174
175 // Invert the predicate if necessary so that the apply function can assume
176 // that the select operands are the same as the fcmp operands.
177 // (select (fcmp P, L, R), R, L) -> (select (fcmp !P, L, R), L, R)
178 if (Info.LHS != True)
180
181 // Only match </<=/>=/> not ==/!= etc.
182 return Info.Pred != CmpInst::getSwappedPredicate(Info.Pred);
183}
184
185void AMDGPUPostLegalizerCombinerImpl::applySelectFCmpToFMinFMaxLegacy(
186 MachineInstr &MI, const FMinFMaxLegacyInfo &Info) const {
187 unsigned Opc = (Info.Pred & CmpInst::FCMP_OGT) ? AMDGPU::G_AMDGPU_FMAX_LEGACY
188 : AMDGPU::G_AMDGPU_FMIN_LEGACY;
189 Register X = Info.LHS;
190 Register Y = Info.RHS;
191 if (Info.Pred == CmpInst::getUnorderedPredicate(Info.Pred)) {
192 // We need to permute the operands to get the correct NaN behavior. The
193 // selected operand is the second one based on the failing compare with NaN,
194 // so permute it based on the compare type the hardware uses.
195 std::swap(X, Y);
196 }
197
198 B.buildInstr(Opc, {MI.getOperand(0)}, {X, Y}, MI.getFlags());
199
200 MI.eraseFromParent();
201}
202
203bool AMDGPUPostLegalizerCombinerImpl::matchUCharToFloat(
204 MachineInstr &MI) const {
205 Register DstReg = MI.getOperand(0).getReg();
206
207 // TODO: We could try to match extracting the higher bytes, which would be
208 // easier if i8 vectors weren't promoted to i32 vectors, particularly after
209 // types are legalized. v4i8 -> v4f32 is probably the only case to worry
210 // about in practice.
211 LLT Ty = MRI.getType(DstReg);
212 if (Ty == LLT::scalar(32) || Ty == LLT::scalar(16)) {
213 Register SrcReg = MI.getOperand(1).getReg();
214 unsigned SrcSize = MRI.getType(SrcReg).getSizeInBits();
215 assert(SrcSize == 16 || SrcSize == 32 || SrcSize == 64);
216 const APInt Mask = APInt::getHighBitsSet(SrcSize, SrcSize - 8);
217 return Helper.getValueTracking()->maskedValueIsZero(SrcReg, Mask);
218 }
219
220 return false;
221}
222
223void AMDGPUPostLegalizerCombinerImpl::applyUCharToFloat(
224 MachineInstr &MI) const {
225 const LLT S32 = LLT::scalar(32);
226
227 Register DstReg = MI.getOperand(0).getReg();
228 Register SrcReg = MI.getOperand(1).getReg();
229 LLT Ty = MRI.getType(DstReg);
230 LLT SrcTy = MRI.getType(SrcReg);
231 if (SrcTy != S32)
232 SrcReg = B.buildAnyExtOrTrunc(S32, SrcReg).getReg(0);
233
234 if (Ty == S32) {
235 B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {DstReg}, {SrcReg},
236 MI.getFlags());
237 } else {
238 auto Cvt0 = B.buildInstr(AMDGPU::G_AMDGPU_CVT_F32_UBYTE0, {S32}, {SrcReg},
239 MI.getFlags());
240 B.buildFPTrunc(DstReg, Cvt0, MI.getFlags());
241 }
242
243 MI.eraseFromParent();
244}
245
246bool AMDGPUPostLegalizerCombinerImpl::matchFDivSqrtToRsqF16(
247 MachineInstr &MI) const {
248 Register Sqrt = MI.getOperand(2).getReg();
249 return MRI.hasOneNonDBGUse(Sqrt);
250}
251
252void AMDGPUPostLegalizerCombinerImpl::applyFDivSqrtToRsqF16(
253 MachineInstr &MI, const Register &X) const {
254 Register Dst = MI.getOperand(0).getReg();
255 Register Y = MI.getOperand(1).getReg();
256 LLT DstTy = MRI.getType(Dst);
257 uint32_t Flags = MI.getFlags();
258 Register RSQ = B.buildIntrinsic(Intrinsic::amdgcn_rsq, {DstTy})
259 .addUse(X)
260 .setMIFlags(Flags)
261 .getReg(0);
262 B.buildFMul(Dst, RSQ, Y, Flags);
263 MI.eraseFromParent();
264}
265
266bool AMDGPUPostLegalizerCombinerImpl::matchCvtF32UByteN(
267 MachineInstr &MI, CvtF32UByteMatchInfo &MatchInfo) const {
268 Register SrcReg = MI.getOperand(1).getReg();
269
270 // Look through G_ZEXT.
271 bool IsShr = mi_match(SrcReg, MRI, m_GZExt(m_Reg(SrcReg)));
272
273 Register Src0;
274 int64_t ShiftAmt;
275 IsShr = mi_match(SrcReg, MRI, m_GLShr(m_Reg(Src0), m_ICst(ShiftAmt)));
276 if (IsShr || mi_match(SrcReg, MRI, m_GShl(m_Reg(Src0), m_ICst(ShiftAmt)))) {
277 const unsigned Offset = MI.getOpcode() - AMDGPU::G_AMDGPU_CVT_F32_UBYTE0;
278
279 unsigned ShiftOffset = 8 * Offset;
280 if (IsShr)
281 ShiftOffset += ShiftAmt;
282 else
283 ShiftOffset -= ShiftAmt;
284
285 MatchInfo.CvtVal = Src0;
286 MatchInfo.ShiftOffset = ShiftOffset;
287 return ShiftOffset < 32 && ShiftOffset >= 8 && (ShiftOffset % 8) == 0;
288 }
289
290 // TODO: Simplify demanded bits.
291 return false;
292}
293
294void AMDGPUPostLegalizerCombinerImpl::applyCvtF32UByteN(
295 MachineInstr &MI, const CvtF32UByteMatchInfo &MatchInfo) const {
296 unsigned NewOpc = AMDGPU::G_AMDGPU_CVT_F32_UBYTE0 + MatchInfo.ShiftOffset / 8;
297
298 const LLT S32 = LLT::scalar(32);
299 Register CvtSrc = MatchInfo.CvtVal;
300 LLT SrcTy = MRI.getType(MatchInfo.CvtVal);
301 if (SrcTy != S32) {
302 assert(SrcTy.isScalar() && SrcTy.getSizeInBits() >= 8);
303 CvtSrc = B.buildAnyExt(S32, CvtSrc).getReg(0);
304 }
305
306 assert(MI.getOpcode() != NewOpc);
307 B.buildInstr(NewOpc, {MI.getOperand(0)}, {CvtSrc}, MI.getFlags());
308 MI.eraseFromParent();
309}
310
311bool AMDGPUPostLegalizerCombinerImpl::matchRemoveFcanonicalize(
312 MachineInstr &MI) const {
313 const SITargetLowering *TLI = static_cast<const SITargetLowering *>(
314 MF.getSubtarget().getTargetLowering());
315 return TLI->isCanonicalized(MI.getOperand(1).getReg(), MF);
316}
317
318// The buffer_load_{i8, i16} intrinsics are initially lowered as
319// buffer_load_{u8, u16} instructions. Here, the buffer_load_{u8, u16}
320// instructions are combined with sign extension instrucions in order to
321// generate buffer_load_{i8, i16} instructions.
322
323// Identify buffer_load_{u8, u16}.
324bool AMDGPUPostLegalizerCombinerImpl::matchCombineSignExtendInReg(
325 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchData) const {
326 Register LoadReg = MI.getOperand(1).getReg();
327 if (!MRI.hasOneNonDBGUse(LoadReg))
328 return false;
329
330 // Check if the first operand of the sign extension is a subword buffer load
331 // instruction.
332 MachineInstr *LoadMI = MRI.getVRegDef(LoadReg);
333 int64_t Width = MI.getOperand(2).getImm();
334 switch (LoadMI->getOpcode()) {
335 case AMDGPU::G_AMDGPU_BUFFER_LOAD_UBYTE:
336 MatchData = {LoadMI, AMDGPU::G_AMDGPU_BUFFER_LOAD_SBYTE};
337 return Width == 8;
338 case AMDGPU::G_AMDGPU_BUFFER_LOAD_USHORT:
339 MatchData = {LoadMI, AMDGPU::G_AMDGPU_BUFFER_LOAD_SSHORT};
340 return Width == 16;
341 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD_UBYTE:
342 MatchData = {LoadMI, AMDGPU::G_AMDGPU_S_BUFFER_LOAD_SBYTE};
343 return Width == 8;
344 case AMDGPU::G_AMDGPU_S_BUFFER_LOAD_USHORT:
345 MatchData = {LoadMI, AMDGPU::G_AMDGPU_S_BUFFER_LOAD_SSHORT};
346 return Width == 16;
347 }
348 return false;
349}
350
351// Combine buffer_load_{u8, u16} and the sign extension instruction to generate
352// buffer_load_{i8, i16}.
353void AMDGPUPostLegalizerCombinerImpl::applyCombineSignExtendInReg(
354 MachineInstr &MI, std::pair<MachineInstr *, unsigned> &MatchData) const {
355 auto [LoadMI, NewOpcode] = MatchData;
356 LoadMI->setDesc(TII.get(NewOpcode));
357 // Update the destination register of the load with the destination register
358 // of the sign extension.
359 Register SignExtendInsnDst = MI.getOperand(0).getReg();
360 LoadMI->getOperand(0).setReg(SignExtendInsnDst);
361 // Remove the sign extension.
362 MI.eraseFromParent();
363}
364
365bool AMDGPUPostLegalizerCombinerImpl::matchCombine_s_mul_u64(
366 MachineInstr &MI, unsigned &NewOpcode) const {
367 Register Src0 = MI.getOperand(1).getReg();
368 Register Src1 = MI.getOperand(2).getReg();
369 if (MRI.getType(Src0) != LLT::scalar(64))
370 return false;
371
372 if (VT->getKnownBits(Src1).countMinLeadingZeros() >= 32 &&
373 VT->getKnownBits(Src0).countMinLeadingZeros() >= 32) {
374 NewOpcode = AMDGPU::G_AMDGPU_S_MUL_U64_U32;
375 return true;
376 }
377
378 if (VT->computeNumSignBits(Src1) >= 33 &&
379 VT->computeNumSignBits(Src0) >= 33) {
380 NewOpcode = AMDGPU::G_AMDGPU_S_MUL_I64_I32;
381 return true;
382 }
383 return false;
384}
385
386// Pass boilerplate
387// ================
388
389class AMDGPUPostLegalizerCombiner : public MachineFunctionPass {
390public:
391 static char ID;
392
393 AMDGPUPostLegalizerCombiner(bool IsOptNone = false);
394
395 StringRef getPassName() const override {
396 return "AMDGPUPostLegalizerCombiner";
397 }
398
399 bool runOnMachineFunction(MachineFunction &MF) override;
400
401 void getAnalysisUsage(AnalysisUsage &AU) const override;
402
403private:
404 bool IsOptNone;
405 AMDGPUPostLegalizerCombinerImplRuleConfig RuleConfig;
406};
407} // end anonymous namespace
408
409void AMDGPUPostLegalizerCombiner::getAnalysisUsage(AnalysisUsage &AU) const {
410 AU.setPreservesCFG();
412 AU.addRequired<GISelValueTrackingAnalysisLegacy>();
413 AU.addPreserved<GISelValueTrackingAnalysisLegacy>();
414 if (!IsOptNone) {
415 AU.addRequired<MachineDominatorTreeWrapperPass>();
416 }
418}
419
420AMDGPUPostLegalizerCombiner::AMDGPUPostLegalizerCombiner(bool IsOptNone)
421 : MachineFunctionPass(ID), IsOptNone(IsOptNone) {
422 if (!RuleConfig.parseCommandLineOption())
423 report_fatal_error("Invalid rule identifier");
424}
425
426bool AMDGPUPostLegalizerCombiner::runOnMachineFunction(MachineFunction &MF) {
427 if (MF.getProperties().hasFailedISel())
428 return false;
429 const Function &F = MF.getFunction();
430 bool EnableOpt =
431 MF.getTarget().getOptLevel() != CodeGenOptLevel::None && !skipFunction(F);
432
434 const AMDGPULegalizerInfo *LI =
435 static_cast<const AMDGPULegalizerInfo *>(ST.getLegalizerInfo());
436
438 &getAnalysis<GISelValueTrackingAnalysisLegacy>().get(MF);
440 IsOptNone ? nullptr
441 : &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
442
443 CombinerInfo CInfo(/*AllowIllegalOps*/ false, /*ShouldLegalizeIllegal*/ true,
444 LI, EnableOpt, F.hasOptSize(), F.hasMinSize());
445 // Disable fixed-point iteration to reduce compile-time
446 CInfo.MaxIterations = 1;
447 CInfo.ObserverLvl = CombinerInfo::ObserverLevel::SinglePass;
448 // Legalizer performs DCE, so a full DCE pass is unnecessary.
449 CInfo.EnableFullDCE = false;
450 AMDGPUPostLegalizerCombinerImpl Impl(MF, CInfo, *VT, /*CSEInfo*/ nullptr,
451 RuleConfig, ST, MDT, LI);
452 return Impl.combineMachineInstrs();
453}
454
455char AMDGPUPostLegalizerCombiner::ID = 0;
456INITIALIZE_PASS_BEGIN(AMDGPUPostLegalizerCombiner, DEBUG_TYPE,
457 "Combine AMDGPU machine instrs after legalization", false,
458 false)
460INITIALIZE_PASS_END(AMDGPUPostLegalizerCombiner, DEBUG_TYPE,
461 "Combine AMDGPU machine instrs after legalization", false,
462 false)
463
465 return new AMDGPUPostLegalizerCombiner(IsOptNone);
466}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define GET_GICOMBINER_CONSTRUCTOR_INITS
This contains common combine transformations that may be used in a combine pass.
constexpr LLT S32
This file declares the targeting of the Machinelegalizer class for AMDGPU.
Provides AMDGPU specific target descriptions.
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This contains common combine transformations that may be used in a combine pass,or by the target else...
Option class for Targets to specify which operations are combined how and when.
This contains the base class for all Combiners generated by TableGen.
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...
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Contains matchers for matching SSA Machine Instructions.
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
static StringRef getName(Value *V)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Target-Independent Code Generator Pass Configuration Options pass.
Value * RHS
Value * LHS
static APInt getHighBitsSet(unsigned numBits, unsigned hiBitsSet)
Constructs an APInt value that has the top hiBitsSet bits set.
Definition APInt.h:293
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:275
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition InstrTypes.h:740
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
Definition InstrTypes.h:744
Predicate getSwappedPredicate() const
For example, EQ->EQ, SLE->SGE, ULT->UGT, OEQ->OEQ, ULE->UGE, OLT->OGT, etc.
Definition InstrTypes.h:890
Predicate getInversePredicate() const
For example, EQ -> NE, UGT -> ULE, SLT -> SGE, OEQ -> UNE, UGT -> OLE, OLT -> UGE,...
Definition InstrTypes.h:852
Predicate getUnorderedPredicate() const
Definition InstrTypes.h:874
GISelValueTracking * getValueTracking() const
LLVM_ABI bool tryCombineShiftToUnmerge(MachineInstr &MI, unsigned TargetShiftAmount) const
Combiner implementation.
Definition Combiner.h:33
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
The CSE Analysis object.
Definition CSEInfo.h:72
To use KnownBitsInfo analysis in a pass, KnownBitsInfo &Info = getAnalysis<GISelValueTrackingInfoAnal...
bool maskedValueIsZero(Register Val, const APInt &Mask)
constexpr bool isScalar() const
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
constexpr TypeSize getSizeInBits() const
Returns the total size of the type. Must only be called on sized types.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
LLVM_ABI void setDesc(const MCInstrDesc &TID)
Replace the instruction descriptor (thus opcode) of the current instruction with a new one.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
Register getReg() const
getReg - Returns the register number.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
bool isCanonicalized(SelectionDAG &DAG, SDValue Op, SDNodeFlags UserFlags={}, unsigned MaxDepth=5) const
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
operand_type_match m_Reg()
UnaryOp_match< SrcTy, TargetOpcode::G_ZEXT > m_GZExt(const SrcTy &Src)
ConstantMatch< APInt > m_ICst(APInt &Cst)
bool mi_match(Reg R, const MachineRegisterInfo &MRI, Pattern &&P)
BinaryOp_match< LHS, RHS, TargetOpcode::G_SHL, false > m_GShl(const LHS &L, const RHS &R)
BinaryOp_match< LHS, RHS, TargetOpcode::G_LSHR, false > m_GLShr(const LHS &L, const RHS &R)
Predicate getPredicate(unsigned Condition, unsigned Hint)
Return predicate consisting of specified condition and hint bits.
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:578
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
LLVM_ABI void getSelectionDAGFallbackAnalysisUsage(AnalysisUsage &AU)
Modify analysis usage so it preserves passes required for the SelectionDAG fallback.
Definition Utils.cpp:1137
FunctionPass * createAMDGPUPostLegalizeCombiner(bool IsOptNone)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
@ SinglePass
Enables Observer-based DCE and additional heuristics that retry combining defined and used instructio...