LLVM 24.0.0git
SIOptimizeExecMaskingPreRA.cpp
Go to the documentation of this file.
1//===-- SIOptimizeExecMaskingPreRA.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/// \file
10/// This pass performs exec mask handling peephole optimizations which needs
11/// to be done before register allocation to reduce register pressure.
12///
13//===----------------------------------------------------------------------===//
14
16#include "AMDGPU.h"
17#include "AMDGPULaneMaskUtils.h"
18#include "GCNSubtarget.h"
22
23using namespace llvm;
24
25#define DEBUG_TYPE "si-optimize-exec-masking-pre-ra"
26
27namespace {
28
29class SIOptimizeExecMaskingPreRA {
30private:
31 const GCNSubtarget &ST;
32 const SIRegisterInfo *TRI;
33 const SIInstrInfo *TII;
35 LiveIntervals *LIS;
37
38 MCRegister CondReg;
39 MCRegister ExecReg;
40
41 bool optimizeVcndVcmpPair(MachineBasicBlock &MBB);
42 bool optimizeElseBranch(MachineBasicBlock &MBB);
43
44public:
45 SIOptimizeExecMaskingPreRA(MachineFunction &MF, LiveIntervals *LIS)
46 : ST(MF.getSubtarget<GCNSubtarget>()), TRI(ST.getRegisterInfo()),
47 TII(ST.getInstrInfo()), MRI(&MF.getRegInfo()), LIS(LIS),
49 bool run(MachineFunction &MF);
50};
51
52class SIOptimizeExecMaskingPreRALegacy : public MachineFunctionPass {
53public:
54 static char ID;
55
56 SIOptimizeExecMaskingPreRALegacy() : MachineFunctionPass(ID) {}
57
58 bool runOnMachineFunction(MachineFunction &MF) override;
59
60 StringRef getPassName() const override {
61 return "SI optimize exec mask operations pre-RA";
62 }
63
64 void getAnalysisUsage(AnalysisUsage &AU) const override {
66 AU.setPreservesAll();
68 }
69};
70
71} // End anonymous namespace.
72
73INITIALIZE_PASS_BEGIN(SIOptimizeExecMaskingPreRALegacy, DEBUG_TYPE,
74 "SI optimize exec mask operations pre-RA", false, false)
76INITIALIZE_PASS_END(SIOptimizeExecMaskingPreRALegacy, DEBUG_TYPE,
77 "SI optimize exec mask operations pre-RA", false, false)
78
79char SIOptimizeExecMaskingPreRALegacy::ID = 0;
80
81char &llvm::SIOptimizeExecMaskingPreRAID = SIOptimizeExecMaskingPreRALegacy::ID;
82
84 return new SIOptimizeExecMaskingPreRALegacy();
85}
86
87// See if there is a def between \p AndIdx and \p SelIdx that needs to live
88// beyond \p AndIdx.
89static bool isDefBetween(const LiveRange &LR, SlotIndex AndIdx,
90 SlotIndex SelIdx) {
91 LiveQueryResult AndLRQ = LR.Query(AndIdx);
92 return (!AndLRQ.isKill() && AndLRQ.valueIn() != LR.Query(SelIdx).valueOut());
93}
94
95// FIXME: Why do we bother trying to handle physical registers here?
96static bool isDefBetween(const SIRegisterInfo &TRI,
98 const MachineInstr &Sel, const MachineInstr &And) {
100 SlotIndex SelIdx = LIS->getInstructionIndex(Sel).getRegSlot();
101
102 if (Reg.isVirtual())
103 return isDefBetween(LIS->getInterval(Reg), AndIdx, SelIdx);
104
105 for (MCRegUnit Unit : TRI.regunits(Reg.asMCReg())) {
106 if (isDefBetween(LIS->getRegUnit(Unit), AndIdx, SelIdx))
107 return true;
108 }
109
110 return false;
111}
112
113// Optimize sequence
114// %sel = V_CNDMASK_B32_e64 0, 1, %cc
115// %cmp = V_CMP_NE_U32 1, %sel
116// $vcc = S_AND_B64 $exec, %cmp
117// S_CBRANCH_VCC[N]Z
118// =>
119// $vcc = S_ANDN2_B64 $exec, %cc
120// S_CBRANCH_VCC[N]Z
121//
122// It is the negation pattern inserted by DAGCombiner::visitBRCOND() in the
123// rebuildSetCC(). We start with S_CBRANCH to avoid exhaustive search, but
124// only 3 first instructions are really needed. S_AND_B64 with exec is a
125// required part of the pattern since V_CNDMASK_B32 writes zeroes for inactive
126// lanes.
127//
128// Returns true on success.
129bool SIOptimizeExecMaskingPreRA::optimizeVcndVcmpPair(MachineBasicBlock &MBB) {
130 auto I = llvm::find_if(MBB.terminators(), [](const MachineInstr &MI) {
131 unsigned Opc = MI.getOpcode();
132 return Opc == AMDGPU::S_CBRANCH_VCCZ ||
133 Opc == AMDGPU::S_CBRANCH_VCCNZ; });
134 if (I == MBB.terminators().end())
135 return false;
136
137 auto *And =
138 TRI->findReachingDef(CondReg, AMDGPU::NoSubRegister, *I, *MRI, LIS);
139 if (!And || And->getOpcode() != LMC.AndOpc || !And->getOperand(1).isReg() ||
140 !And->getOperand(2).isReg())
141 return false;
142
143 MachineOperand *AndCC = &And->getOperand(1);
144 Register CmpReg = AndCC->getReg();
145 unsigned CmpSubReg = AndCC->getSubReg();
146 if (CmpReg == Register(ExecReg)) {
147 AndCC = &And->getOperand(2);
148 CmpReg = AndCC->getReg();
149 CmpSubReg = AndCC->getSubReg();
150 } else if (And->getOperand(2).getReg() != Register(ExecReg)) {
151 return false;
152 }
153
154 auto *Cmp = TRI->findReachingDef(CmpReg, CmpSubReg, *And, *MRI, LIS);
155 if (!Cmp || !(Cmp->getOpcode() == AMDGPU::V_CMP_NE_U32_e32 ||
156 Cmp->getOpcode() == AMDGPU::V_CMP_NE_U32_e64) ||
157 Cmp->getParent() != And->getParent())
158 return false;
159
160 MachineOperand *Op1 = TII->getNamedOperand(*Cmp, AMDGPU::OpName::src0);
161 MachineOperand *Op2 = TII->getNamedOperand(*Cmp, AMDGPU::OpName::src1);
162 if (Op1->isImm() && Op2->isReg())
163 std::swap(Op1, Op2);
164 if (!Op1->isReg() || !Op2->isImm() || Op2->getImm() != 1)
165 return false;
166
167 Register SelReg = Op1->getReg();
168 if (SelReg.isPhysical())
169 return false;
170
171 auto *Sel = TRI->findReachingDef(SelReg, Op1->getSubReg(), *Cmp, *MRI, LIS);
172 if (!Sel || Sel->getOpcode() != AMDGPU::V_CNDMASK_B32_e64)
173 return false;
174
175 if (TII->hasModifiersSet(*Sel, AMDGPU::OpName::src0_modifiers) ||
176 TII->hasModifiersSet(*Sel, AMDGPU::OpName::src1_modifiers))
177 return false;
178
179 Op1 = TII->getNamedOperand(*Sel, AMDGPU::OpName::src0);
180 Op2 = TII->getNamedOperand(*Sel, AMDGPU::OpName::src1);
181 MachineOperand *CC = TII->getNamedOperand(*Sel, AMDGPU::OpName::src2);
182 if (!Op1->isImm() || !Op2->isImm() || !CC->isReg() ||
183 Op1->getImm() != 0 || Op2->getImm() != 1)
184 return false;
185
186 Register CCReg = CC->getReg();
187
188 // If there was a def between the select and the and, we would need to move it
189 // to fold this.
190 if (isDefBetween(*TRI, LIS, CCReg, *Sel, *And))
191 return false;
192
193 // Cannot safely mirror live intervals with PHI nodes, so check for these
194 // before optimization.
195 SlotIndex SelIdx = LIS->getInstructionIndex(*Sel);
196 LiveInterval *SelLI = &LIS->getInterval(SelReg);
197 if (llvm::any_of(SelLI->vnis(),
198 [](const VNInfo *VNI) {
199 return VNI->isPHIDef();
200 }))
201 return false;
202
203 // TODO: Guard against implicit def operands?
204 LLVM_DEBUG(dbgs() << "Folding sequence:\n\t" << *Sel << '\t' << *Cmp << '\t'
205 << *And);
206
207 MachineInstr *Andn2 =
208 BuildMI(MBB, *And, And->getDebugLoc(), TII->get(LMC.AndN2Opc),
209 And->getOperand(0).getReg())
210 .addReg(ExecReg)
211 .addReg(CCReg, getUndefRegState(CC->isUndef()), CC->getSubReg());
212 MachineOperand &AndSCC = And->getOperand(3);
213 assert(AndSCC.getReg() == AMDGPU::SCC);
214 MachineOperand &Andn2SCC = Andn2->getOperand(3);
215 assert(Andn2SCC.getReg() == AMDGPU::SCC);
216 Andn2SCC.setIsDead(AndSCC.isDead());
217
218 SlotIndex AndIdx = LIS->ReplaceMachineInstrInMaps(*And, *Andn2);
219 And->eraseFromParent();
220
221 LLVM_DEBUG(dbgs() << "=>\n\t" << *Andn2 << '\n');
222
223 // Update live intervals for CCReg before potentially removing CmpReg/SelReg,
224 // and their associated liveness information.
225 SlotIndex CmpIdx = LIS->getInstructionIndex(*Cmp);
226 if (CCReg.isVirtual()) {
227 LiveInterval &CCLI = LIS->getInterval(CCReg);
228 auto CCQ = CCLI.Query(SelIdx.getRegSlot());
229 if (CCQ.valueIn()) {
230 LIS->removeInterval(CCReg);
232 }
233 } else
234 LIS->removeAllRegUnitsForPhysReg(CCReg);
235
236 // Try to remove compare. Cmp value should not used in between of cmp
237 // and s_and_b64 if VCC or just unused if any other register.
238 LiveInterval *CmpLI = CmpReg.isVirtual() ? &LIS->getInterval(CmpReg) : nullptr;
239 if ((CmpLI && CmpLI->Query(AndIdx.getRegSlot()).isKill()) ||
240 (CmpReg == Register(CondReg) &&
241 std::none_of(std::next(Cmp->getIterator()), Andn2->getIterator(),
242 [&](const MachineInstr &MI) {
243 return MI.readsRegister(CondReg, TRI);
244 }))) {
245 LLVM_DEBUG(dbgs() << "Erasing: " << *Cmp << '\n');
246 if (CmpLI)
247 LIS->removeVRegDefAt(*CmpLI, CmpIdx.getRegSlot());
249 Cmp->eraseFromParent();
250
251 // Try to remove v_cndmask_b32.
252 // Kill status must be checked before shrinking the live range.
253 bool IsKill = SelLI->Query(CmpIdx.getRegSlot()).isKill();
254 LIS->shrinkToUses(SelLI);
255 bool IsDead = SelLI->Query(SelIdx.getRegSlot()).isDeadDef();
256 if (MRI->use_nodbg_empty(SelReg) && (IsKill || IsDead)) {
257 LLVM_DEBUG(dbgs() << "Erasing: " << *Sel << '\n');
258
259 LIS->removeVRegDefAt(*SelLI, SelIdx.getRegSlot());
261 bool ShrinkSel = Sel->getOperand(0).readsReg();
262 Sel->eraseFromParent();
263 if (ShrinkSel) {
264 // The result of the V_CNDMASK was a subreg def which counted as a read
265 // from the other parts of the reg. Shrink their live ranges.
266 LIS->shrinkToUses(SelLI);
267 }
268 }
269 }
270
271 return true;
272}
273
274// Optimize sequence
275// %dst = S_OR_SAVEEXEC %src
276// ... instructions not modifying exec ...
277// %tmp = S_AND $exec, %dst
278// $exec = S_XOR_term $exec, %tmp
279// =>
280// %dst = S_OR_SAVEEXEC %src
281// ... instructions not modifying exec ...
282// $exec = S_XOR_term $exec, %dst
283//
284// Clean up potentially unnecessary code added for safety during
285// control flow lowering.
286//
287// Return whether any changes were made to MBB.
288bool SIOptimizeExecMaskingPreRA::optimizeElseBranch(MachineBasicBlock &MBB) {
289 if (MBB.empty())
290 return false;
291
292 // Check this is an else block.
293 auto First = MBB.begin();
294 MachineInstr &SaveExecMI = *First;
295 if (SaveExecMI.getOpcode() != LMC.OrSaveExecOpc)
296 return false;
297
298 auto I = llvm::find_if(MBB.terminators(), [this](const MachineInstr &MI) {
299 return MI.getOpcode() == LMC.XorTermOpc;
300 });
301 if (I == MBB.terminators().end())
302 return false;
303
304 MachineInstr &XorTermMI = *I;
305 if (XorTermMI.getOperand(1).getReg() != Register(ExecReg))
306 return false;
307
308 Register SavedExecReg = SaveExecMI.getOperand(0).getReg();
309 Register DstReg = XorTermMI.getOperand(2).getReg();
310
311 // Find potentially unnecessary S_AND
312 MachineInstr *AndExecMI = nullptr;
313 I--;
314 while (I != First && !AndExecMI) {
315 if (I->getOpcode() == LMC.AndOpc && I->getOperand(0).getReg() == DstReg &&
316 I->getOperand(1).getReg() == Register(ExecReg))
317 AndExecMI = &*I;
318 I--;
319 }
320 if (!AndExecMI)
321 return false;
322
323 // Check for exec modifying instructions.
324 // Note: exec defs do not create live ranges beyond the
325 // instruction so isDefBetween cannot be used.
326 // Instead just check that the def segments are adjacent.
327 SlotIndex StartIdx = LIS->getInstructionIndex(SaveExecMI);
328 SlotIndex EndIdx = LIS->getInstructionIndex(*AndExecMI);
329 for (MCRegUnit Unit : TRI->regunits(ExecReg)) {
330 LiveRange &RegUnit = LIS->getRegUnit(Unit);
331 if (RegUnit.find(StartIdx) != std::prev(RegUnit.find(EndIdx)))
332 return false;
333 }
334
335 // Remove unnecessary S_AND
336 LIS->removeInterval(SavedExecReg);
337 LIS->removeInterval(DstReg);
338
339 SaveExecMI.getOperand(0).setReg(DstReg);
340
341 LIS->RemoveMachineInstrFromMaps(*AndExecMI);
342 AndExecMI->eraseFromParent();
343
345
346 return true;
347}
348
349PreservedAnalyses
352 auto &LIS = MFAM.getResult<LiveIntervalsAnalysis>(MF);
353 SIOptimizeExecMaskingPreRA(MF, &LIS).run(MF);
354 return PreservedAnalyses::all();
355}
356
357bool SIOptimizeExecMaskingPreRALegacy::runOnMachineFunction(
358 MachineFunction &MF) {
359 if (skipFunction(MF.getFunction()))
360 return false;
361
362 auto *LIS = &getAnalysis<LiveIntervalsWrapperPass>().getLIS();
363 return SIOptimizeExecMaskingPreRA(MF, LIS).run(MF);
364}
365
366bool SIOptimizeExecMaskingPreRA::run(MachineFunction &MF) {
367 CondReg = MCRegister::from(LMC.VccReg);
368 ExecReg = MCRegister::from(LMC.ExecReg);
369
370 DenseSet<Register> RecalcRegs({AMDGPU::EXEC_LO, AMDGPU::EXEC_HI});
371 bool Changed = false;
372
373 for (MachineBasicBlock &MBB : MF) {
374
375 if (optimizeElseBranch(MBB)) {
376 RecalcRegs.insert(AMDGPU::SCC);
377 Changed = true;
378 }
379
380 if (optimizeVcndVcmpPair(MBB)) {
381 RecalcRegs.insert(AMDGPU::VCC_LO);
382 RecalcRegs.insert(AMDGPU::VCC_HI);
383 RecalcRegs.insert(AMDGPU::SCC);
384 Changed = true;
385 }
386
387 // Try to remove unneeded instructions before s_endpgm.
388 if (MBB.succ_empty()) {
389 if (MBB.empty())
390 continue;
391
392 // Skip this if the endpgm has any implicit uses, otherwise we would need
393 // to be careful to update / remove them.
394 // S_ENDPGM always has a single imm operand that is not used other than to
395 // end up in the encoding
396 MachineInstr &Term = MBB.back();
397 if (Term.getOpcode() != AMDGPU::S_ENDPGM || Term.getNumOperands() != 1)
398 continue;
399
400 SmallVector<MachineBasicBlock*, 4> Blocks({&MBB});
401
402 while (!Blocks.empty()) {
403 auto *CurBB = Blocks.pop_back_val();
404 auto I = CurBB->rbegin(), E = CurBB->rend();
405 if (I != E) {
406 if (I->isUnconditionalBranch() || I->getOpcode() == AMDGPU::S_ENDPGM)
407 ++I;
408 else if (I->isBranch())
409 continue;
410 }
411
412 while (I != E) {
413 if (I->isDebugInstr()) {
414 I = std::next(I);
415 continue;
416 }
417
418 if (I->mayStore() || I->isBarrier() || I->isCall() ||
419 I->hasUnmodeledSideEffects() || I->hasOrderedMemoryRef())
420 break;
421
423 << "Removing no effect instruction: " << *I << '\n');
424
425 for (auto &Op : I->operands()) {
426 if (Op.isReg())
427 RecalcRegs.insert(Op.getReg());
428 }
429
430 auto Next = std::next(I);
432 I->eraseFromParent();
433 I = Next;
434
435 Changed = true;
436 }
437
438 if (I != E)
439 continue;
440
441 // Try to ascend predecessors.
442 for (auto *Pred : CurBB->predecessors()) {
443 if (Pred->succ_size() == 1)
444 Blocks.push_back(Pred);
445 }
446 }
447 continue;
448 }
449
450 // If the only user of a logical operation is move to exec, fold it now
451 // to prevent forming of saveexec. I.e.:
452 //
453 // %0:sreg_64 = COPY $exec
454 // %1:sreg_64 = S_AND_B64 %0:sreg_64, %2:sreg_64
455 // =>
456 // %1 = S_AND_B64 $exec, %2:sreg_64
457 unsigned ScanThreshold = 10;
458 for (auto I = MBB.rbegin(), E = MBB.rend(); I != E
459 && ScanThreshold--; ++I) {
460 // Continue scanning if this is not a full exec copy
461 if (!(I->isFullCopy() && I->getOperand(1).getReg() == Register(ExecReg)))
462 continue;
463
464 Register SavedExec = I->getOperand(0).getReg();
465 if (SavedExec.isVirtual() && MRI->hasOneNonDBGUse(SavedExec)) {
466 MachineInstr *SingleExecUser = &*MRI->use_instr_nodbg_begin(SavedExec);
467 int Idx = SingleExecUser->findRegisterUseOperandIdx(SavedExec,
468 /*TRI=*/nullptr);
469 assert(Idx != -1);
470 if (SingleExecUser->getParent() == I->getParent() &&
471 !SingleExecUser->getOperand(Idx).isImplicit() &&
472 static_cast<unsigned>(Idx) <
473 SingleExecUser->getDesc().getNumOperands() &&
474 TII->isOperandLegal(*SingleExecUser, Idx, &I->getOperand(1))) {
475 LLVM_DEBUG(dbgs() << "Redundant EXEC COPY: " << *I << '\n');
477 I->eraseFromParent();
478 MRI->replaceRegWith(SavedExec, ExecReg);
479 LIS->removeInterval(SavedExec);
480 Changed = true;
481 }
482 }
483 break;
484 }
485 }
486
487 if (Changed) {
488 for (auto Reg : RecalcRegs) {
489 if (Reg.isVirtual()) {
490 LIS->removeInterval(Reg);
491 if (!MRI->reg_empty(Reg))
493 } else {
495 }
496 }
497 }
498
499 return Changed;
500}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
AMD GCN specific subclass of TargetSubtarget.
#define DEBUG_TYPE
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
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
bool IsDead
static bool isDefBetween(Register Reg, SlotIndex First, SlotIndex Last, const MachineRegisterInfo *MRI, const LiveIntervals *LIS)
static bool isDefBetween(const LiveRange &LR, SlotIndex AndIdx, SlotIndex SelIdx)
SI Optimize VGPR LiveRange
#define LLVM_DEBUG(...)
Definition Debug.h:119
static const LaneMaskConstants & get(const GCNSubtarget &ST)
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()
void setPreservesAll()
Set by analyses that do not transform their input at all.
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:314
LLVM_ABI Result run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
void removeAllRegUnitsForPhysReg(MCRegister Reg)
Remove associated live ranges for the register units associated with Reg.
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
LiveInterval & getInterval(Register Reg)
void removeInterval(Register Reg)
Interval removal.
LiveRange & getRegUnit(MCRegUnit Unit)
Return the live range for register unit Unit.
LLVM_ABI void removeVRegDefAt(LiveInterval &LI, SlotIndex Pos)
Remove value number and related live segments of LI and its subranges that start at position Pos.
LLVM_ABI bool shrinkToUses(LiveInterval *li, SmallVectorImpl< MachineInstr * > *dead=nullptr)
After removing some uses of a register, shrink its live range to just the remaining uses.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
Result of a LiveRange query.
bool isDeadDef() const
Return true if this instruction has a dead def.
VNInfo * valueIn() const
Return the value that is live-in to the instruction.
VNInfo * valueOut() const
Return the value leaving the instruction, if any.
bool isKill() const
Return true if the live-in value is killed by this instruction.
This class represents the liveness of a register, stack slot, etc.
iterator_range< vni_iterator > vnis()
LiveQueryResult Query(SlotIndex Idx) const
Query Liveness at Idx.
LLVM_ABI iterator find(SlotIndex Pos)
find - Return an iterator pointing to the first segment that ends after Pos, or end().
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Wrapper class representing physical registers. Should be passed by value.
Definition MCRegister.h:41
static MCRegister from(unsigned Val)
Check the provided unsigned value is a valid MCRegister.
Definition MCRegister.h:77
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< iterator > terminators()
reverse_iterator rbegin()
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.
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.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
LLVM_ABI int findRegisterUseOperandIdx(Register Reg, const TargetRegisterInfo *TRI, bool isKill=false) const
Returns the operand index that is a use of the specific register or -1 if it is not found.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
unsigned getSubReg() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setIsDead(bool Val=true)
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
bool use_nodbg_empty(Register RegNo) const
use_nodbg_empty - Return true if there are no non-Debug instructions using the specified register.
use_instr_nodbg_iterator use_instr_nodbg_begin(Register RegNo) const
bool reg_empty(Register RegNo) const
reg_empty - Return true if there are no instructions using or defining the specified register (it may...
LLVM_ABI void replaceRegWith(Register FromReg, Register ToReg)
replaceRegWith - Replace all instances of FromReg with ToReg in the machine function.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
Definition Register.h:79
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
self_iterator getIterator()
Definition ilist_node.h:123
IteratorT end() const
Changed
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
char & SIOptimizeExecMaskingPreRAID
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
@ And
Bitwise or logical AND of integers.
DWARFExpression::Operation Op
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1772
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Next
Definition InstrProf.h:147
FunctionPass * createSIOptimizeExecMaskingPreRAPass()
constexpr RegState getUndefRegState(bool B)
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:880
Matching combinators.