LLVM: lib/Target/AMDGPU/SIPreEmitPeephole.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
28
29using namespace llvm;
30
31#define DEBUG_TYPE "si-pre-emit-peephole"
32
33namespace {
34
35class SIPreEmitPeephole {
36private:
39
46 bool mustRetainExeczBranch(const MachineInstr &Branch,
50
51
52 void collectUnpackingCandidates(MachineInstr &BeginMI,
55
56
57
58
59
60
61
62 bool canUnpackingClobberRegister(const MachineInstr &MI);
63
64
65
67
69
70
71
73 bool IsHiBits);
74
75
78
79public:
81};
82
84public:
85 static char ID;
86
89 }
90
92 return SIPreEmitPeephole().run(MF);
93 }
94};
95
96}
97
99 "SI peephole optimizations", false, false)
100
101char SIPreEmitPeepholeLegacy::ID = 0;
102
104
105bool SIPreEmitPeephole::optimizeVccBranch(MachineInstr &MI) const {
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
126 const GCNSubtarget &ST = MBB.getParent()->getSubtarget();
127 const bool IsWave32 = ST.isWave32();
128 const unsigned CondReg = TRI->getVCC();
129 const unsigned ExecReg = IsWave32 ? AMDGPU::EXEC_LO : AMDGPU::EXEC;
130 const unsigned And = IsWave32 ? AMDGPU::S_AND_B32 : AMDGPU::S_AND_B64;
131 const unsigned AndN2 = IsWave32 ? AMDGPU::S_ANDN2_B32 : AMDGPU::S_ANDN2_B64;
132 const unsigned Mov = IsWave32 ? AMDGPU::S_MOV_B32 : AMDGPU::S_MOV_B64;
133
136 bool ReadsCond = false;
137 unsigned Threshold = 5;
139 if (!--Threshold)
140 return false;
141 if (A->modifiesRegister(ExecReg, TRI))
142 return false;
143 if (A->modifiesRegister(CondReg, TRI)) {
144 if (->definesRegister(CondReg, TRI) ||
145 (A->getOpcode() != And && A->getOpcode() != AndN2))
146 return false;
147 break;
148 }
149 ReadsCond |= A->readsRegister(CondReg, TRI);
150 }
152 return false;
153
156 if (Op1.getReg() != ExecReg && Op2.isReg() && Op2.getReg() == ExecReg) {
157 TII->commuteInstruction(*A);
158 Changed = true;
159 }
164
165 int64_t MaskValue = 0;
168 SReg = Op2.getReg();
169 auto M = std::next(A);
170 bool ReadsSreg = false;
171 bool ModifiesExec = false;
172 for (; M != E; ++M) {
173 if (M->definesRegister(SReg, TRI))
174 break;
175 if (M->modifiesRegister(SReg, TRI))
176 return Changed;
177 ReadsSreg |= M->readsRegister(SReg, TRI);
178 ModifiesExec |= M->modifiesRegister(ExecReg, TRI);
179 }
182
183
184
185
186 if (A->getOpcode() == And && SReg == CondReg && !ModifiesExec &&
187 TII->isVOPC(*M)) {
188 A->eraseFromParent();
189 return true;
190 }
191 if (!M->isMoveImmediate() || !M->getOperand(1).isImm() ||
192 (M->getOperand(1).getImm() != -1 && M->getOperand(1).getImm() != 0))
194 MaskValue = M->getOperand(1).getImm();
195
196
197 if (!ReadsSreg && Op2.isKill()) {
198 A->getOperand(2).ChangeToImmediate(MaskValue);
199 M->eraseFromParent();
200 }
201 } else if (Op2.isImm()) {
202 MaskValue = Op2.getImm();
203 } else {
204 llvm_unreachable("Op2 must be register or immediate");
205 }
206
207
208 assert(MaskValue == 0 || MaskValue == -1);
209 if (A->getOpcode() == AndN2)
210 MaskValue = ~MaskValue;
211
212 if (!ReadsCond && A->registerDefIsDead(AMDGPU::SCC, nullptr)) {
213 if (!MI.killsRegister(CondReg, TRI)) {
214
215 if (MaskValue == 0) {
216 BuildMI(*A->getParent(), *A, A->getDebugLoc(), TII->get(Mov), CondReg)
217 .addImm(0);
218 } else {
219 BuildMI(*A->getParent(), *A, A->getDebugLoc(), TII->get(Mov), CondReg)
220 .addReg(ExecReg);
221 }
222 }
223
224 A->eraseFromParent();
225 }
226
227 bool IsVCCZ = MI.getOpcode() == AMDGPU::S_CBRANCH_VCCZ;
228 if (SReg == ExecReg) {
229
230 if (IsVCCZ) {
231 MI.eraseFromParent();
232 return true;
233 }
234 MI.setDesc(TII->get(AMDGPU::S_BRANCH));
235 } else if (IsVCCZ && MaskValue == 0) {
236
237
240 bool Found = false;
242 if (Found) {
243 if (Term.isBranch())
245 } else {
246 Found = Term.isIdenticalTo(MI);
247 }
248 }
249 assert(Found && "conditional branch is not terminator");
250 for (auto *BranchMI : ToRemove) {
252 assert(Dst.isMBB() && "destination is not basic block");
254 BranchMI->eraseFromParent();
255 }
256
259 }
260
261
262 MI.setDesc(TII->get(AMDGPU::S_BRANCH));
263 } else if (!IsVCCZ && MaskValue == 0) {
264
266 assert(Dst.isMBB() && "destination is not basic block");
267 MI.getParent()->removeSuccessor(Dst.getMBB());
268 MI.eraseFromParent();
269 return true;
270 } else if (MaskValue == -1) {
271
272 MI.setDesc(
273 TII->get(IsVCCZ ? AMDGPU::S_CBRANCH_EXECZ : AMDGPU::S_CBRANCH_EXECNZ));
274 }
275
276 MI.removeOperand(MI.findRegisterUseOperandIdx(CondReg, TRI, false ));
277 MI.addImplicitDefUseOperands(*MBB.getParent());
278
279 return true;
280}
281
284 MachineBasicBlock &MBB = *MI.getParent();
285 const MachineFunction &MF = *MBB.getParent();
286 const MachineRegisterInfo &MRI = MF.getRegInfo();
287 MachineOperand *Idx = TII->getNamedOperand(MI, AMDGPU::OpName::src0);
289 SmallVector<MachineInstr *, 4> ToRemove;
290 bool IdxOn = true;
291
292 if (.isIdenticalTo(First))
293 return false;
294
295
299 if (I->isBundle() || I->isDebugInstr())
300 continue;
301 switch (I->getOpcode()) {
302 case AMDGPU::S_SET_GPR_IDX_MODE:
303 return false;
304 case AMDGPU::S_SET_GPR_IDX_OFF:
305 IdxOn = false;
307 break;
308 default:
309 if (I->modifiesRegister(AMDGPU::M0, TRI))
310 return false;
311 if (IdxReg && I->modifiesRegister(IdxReg, TRI))
312 return false;
313 if (llvm::any_of(I->operands(), [&MRI, this](const MachineOperand &MO) {
314 return MO.isReg() && TRI->isVectorRegister(MRI, MO.getReg());
315 })) {
316
317
318 if (!IdxOn || !(I->getOpcode() == AMDGPU::V_MOV_B32_indirect_write ||
319 I->getOpcode() == AMDGPU::V_MOV_B32_indirect_read))
320 return false;
321 }
322 }
323 }
324
325 MI.eraseFromBundle();
326 for (MachineInstr *RI : ToRemove)
327 RI->eraseFromBundle();
328 return true;
329}
330
331bool SIPreEmitPeephole::getBlockDestinations(
332 MachineBasicBlock &SrcMBB, MachineBasicBlock *&TrueMBB,
333 MachineBasicBlock *&FalseMBB, SmallVectorImpl &Cond) {
335 return false;
336
337 if (!FalseMBB)
339
340 return true;
341}
342
343namespace {
344class BranchWeightCostModel {
345 const SIInstrInfo &TII;
346 const TargetSchedModel &SchedModel;
347 BranchProbability BranchProb;
348 static constexpr uint64_t BranchNotTakenCost = 1;
349 uint64_t BranchTakenCost;
350 uint64_t ThenCyclesCost = 0;
351
352public:
353 BranchWeightCostModel(const SIInstrInfo &TII, const MachineInstr &Branch,
354 const MachineBasicBlock &Succ)
355 : TII(TII), SchedModel(TII.getSchedModel()) {
356 const MachineBasicBlock &Head = *Branch.getParent();
359
363 BranchTakenCost = SchedModel.computeInstrLatency(&Branch);
364 }
365
367 if (TII.isWaitcnt(MI.getOpcode()))
368 return false;
369
370 ThenCyclesCost += SchedModel.computeInstrLatency(&MI);
371
372
373
374
375
376
377
378
379
380 uint64_t Numerator = BranchProb.getNumerator();
382 return (Denominator - Numerator) * ThenCyclesCost <=
383 ((Denominator - Numerator) * BranchTakenCost +
384 Numerator * BranchNotTakenCost);
385 }
386};
387
388bool SIPreEmitPeephole::mustRetainExeczBranch(
389 const MachineInstr &Branch, const MachineBasicBlock &From,
390 const MachineBasicBlock &To) const {
392 BranchWeightCostModel CostModel{*TII, Branch, From};
393
394 const MachineFunction *MF = From.getParent();
397 const MachineBasicBlock &MBB = *MBBI;
398
399 for (const MachineInstr &MI : MBB) {
400
401
402
403 if (MI.isConditionalBranch())
404 return true;
405
406 if (MI.isUnconditionalBranch() &&
408 return true;
409
410 if (MI.isMetaInstruction())
411 continue;
412
413 if (TII->hasUnwantedEffectsWhenEXECEmpty(MI))
414 return true;
415
416 if (!CostModel.isProfitable(MI))
417 return true;
418 }
419 }
420
421 return false;
422}
423}
424
425
426bool SIPreEmitPeephole::removeExeczBranch(MachineInstr &MI,
427 MachineBasicBlock &SrcMBB) {
428
429 if (->getSchedModel().hasInstrSchedModel())
430 return false;
431
432 MachineBasicBlock *TrueMBB = nullptr;
433 MachineBasicBlock *FalseMBB = nullptr;
435
436 if (!getBlockDestinations(SrcMBB, TrueMBB, FalseMBB, Cond))
437 return false;
438
439
441 return false;
442
443
444 if (mustRetainExeczBranch(MI, *FalseMBB, *TrueMBB))
445 return false;
446
448 MI.eraseFromParent();
450
451 return true;
452}
453
454bool SIPreEmitPeephole::canUnpackingClobberRegister(const MachineInstr &MI) {
455 unsigned OpCode = MI.getOpcode();
456 Register DstReg = MI.getOperand(0).getReg();
457
458
459
460
461
462
463
464 Register UnpackedDstReg = TRI->getSubReg(DstReg, AMDGPU::sub0);
465
466 const MachineOperand *Src0MO = TII->getNamedOperand(MI, AMDGPU::OpName::src0);
467 if (Src0MO && Src0MO->isReg()) {
469 unsigned Src0Mods =
470 TII->getNamedOperand(MI, AMDGPU::OpName::src0_modifiers)->getImm();
472 ? TRI->getSubReg(SrcReg0, AMDGPU::sub1)
473 : TRI->getSubReg(SrcReg0, AMDGPU::sub0);
474
475
476 if (TRI->regsOverlap(UnpackedDstReg, HiSrc0Reg))
477 return true;
478 }
479
480 const MachineOperand *Src1MO = TII->getNamedOperand(MI, AMDGPU::OpName::src1);
481 if (Src1MO && Src1MO->isReg()) {
483 unsigned Src1Mods =
484 TII->getNamedOperand(MI, AMDGPU::OpName::src1_modifiers)->getImm();
486 ? TRI->getSubReg(SrcReg1, AMDGPU::sub1)
487 : TRI->getSubReg(SrcReg1, AMDGPU::sub0);
488 if (TRI->regsOverlap(UnpackedDstReg, HiSrc1Reg))
489 return true;
490 }
491
492
493
495 const MachineOperand *Src2MO =
496 TII->getNamedOperand(MI, AMDGPU::OpName::src2);
497 if (Src2MO && Src2MO->isReg()) {
499 unsigned Src2Mods =
500 TII->getNamedOperand(MI, AMDGPU::OpName::src2_modifiers)->getImm();
502 ? TRI->getSubReg(SrcReg2, AMDGPU::sub1)
503 : TRI->getSubReg(SrcReg2, AMDGPU::sub0);
504 if (TRI->regsOverlap(UnpackedDstReg, HiSrc2Reg))
505 return true;
506 }
507 }
508 return false;
509}
510
511uint16_t SIPreEmitPeephole::mapToUnpackedOpcode(MachineInstr &I) {
512 unsigned Opcode = I.getOpcode();
513
514
515
516 switch (Opcode) {
517 case AMDGPU::V_PK_ADD_F32:
518 return AMDGPU::V_ADD_F32_e64;
519 case AMDGPU::V_PK_MUL_F32:
520 return AMDGPU::V_MUL_F32_e64;
521 case AMDGPU::V_PK_FMA_F32:
522 return AMDGPU::V_FMA_F32_e64;
523 default:
524 return std::numeric_limits<uint16_t>::max();
525 }
527}
528
529void SIPreEmitPeephole::addOperandAndMods(MachineInstrBuilder &NewMI,
530 unsigned SrcMods, bool IsHiBits,
531 const MachineOperand &SrcMO) {
532 unsigned NewSrcMods = 0;
535
536
537
538
539
540
541
542
543
544 if (SrcMods & NegModifier)
546
547
548
549 NewMI.addImm(NewSrcMods);
550 if (SrcMO.isImm()) {
552 return;
553 }
554
555 Register UnpackedSrcReg = (SrcMods & OpSelModifier)
556 ? TRI->getSubReg(SrcMO.getReg(), AMDGPU::sub1)
557 : TRI->getSubReg(SrcMO.getReg(), AMDGPU::sub0);
558
559 MachineOperand UnpackedSrcMO =
561 if (SrcMO.isKill()) {
562
563
564
565
566
567
568
569
570
571
572
573
576 bool KillState = true;
577 if ((OpSel == OpSelHi) && !IsHiBits)
578 KillState = false;
579 UnpackedSrcMO.setIsKill(KillState);
580 }
581 NewMI.add(UnpackedSrcMO);
582}
583
584void SIPreEmitPeephole::collectUnpackingCandidates(
585 MachineInstr &BeginMI, SetVector<MachineInstr *> &InstrsToUnpack,
586 uint16_t NumMFMACycles) {
589 int TotalCyclesBetweenCandidates = 0;
590 auto SchedModel = TII->getSchedModel();
592
593 for (auto I = std::next(BeginMI.getIterator()); I != E; ++I) {
595 uint16_t UnpackedOpCode = mapToUnpackedOpcode(Instr);
596 bool IsUnpackable =
597 !(UnpackedOpCode == std::numeric_limits<uint16_t>::max());
598 if (Instr.isMetaInstruction())
599 continue;
600 if ((Instr.isTerminator()) ||
601 (TII->isNeverCoissue(Instr) && !IsUnpackable) ||
603 Instr.modifiesRegister(AMDGPU::EXEC, TRI)))
604 return;
605
606 const MCSchedClassDesc *InstrSchedClassDesc =
610 TotalCyclesBetweenCandidates += Latency;
611
612 if (TotalCyclesBetweenCandidates >= NumMFMACycles - 1)
613 return;
614
615
616
617
618
619 for (const MachineOperand &InstrMO : Instr.operands()) {
620 if (!InstrMO.isReg() || !InstrMO.getReg().isValid())
621 continue;
622 if (TRI->regsOverlap(MFMADef, InstrMO.getReg()))
623 return;
624 }
625 if (!IsUnpackable)
626 continue;
627
628 if (canUnpackingClobberRegister(Instr))
629 return;
630
631
632
633 TotalCyclesBetweenCandidates -= Latency;
634
635 TotalCyclesBetweenCandidates += 2;
636
637 if (TotalCyclesBetweenCandidates < NumMFMACycles - 1)
638 InstrsToUnpack.insert(&Instr);
639 }
640}
641
642void SIPreEmitPeephole::performF32Unpacking(MachineInstr &I) {
643 const MachineOperand &DstOp = I.getOperand(0);
644
645 uint16_t UnpackedOpcode = mapToUnpackedOpcode(I);
646 assert(UnpackedOpcode != std::numeric_limits<uint16_t>::max() &&
647 "Unsupported Opcode");
648
649 MachineInstrBuilder Op0LOp1L =
650 createUnpackedMI(I, UnpackedOpcode, false);
651 MachineOperand LoDstOp = Op0LOp1L->getOperand(0);
652
654
655 MachineInstrBuilder Op0HOp1H =
656 createUnpackedMI(I, UnpackedOpcode, true);
657 MachineOperand HiDstOp = Op0HOp1H->getOperand(0);
658
659 uint32_t IFlags = I.getFlags();
664
665 I.eraseFromParent();
666}
667
668MachineInstrBuilder SIPreEmitPeephole::createUnpackedMI(MachineInstr &I,
669 uint16_t UnpackedOpcode,
670 bool IsHiBits) {
673 const MachineOperand *SrcMO0 = TII->getNamedOperand(I, AMDGPU::OpName::src0);
674 const MachineOperand *SrcMO1 = TII->getNamedOperand(I, AMDGPU::OpName::src1);
675 Register DstReg = I.getOperand(0).getReg();
676 unsigned OpCode = I.getOpcode();
677 Register UnpackedDstReg = IsHiBits ? TRI->getSubReg(DstReg, AMDGPU::sub1)
678 : TRI->getSubReg(DstReg, AMDGPU::sub0);
679
680 int64_t ClampVal = TII->getNamedOperand(I, AMDGPU::OpName::clamp)->getImm();
681 unsigned Src0Mods =
682 TII->getNamedOperand(I, AMDGPU::OpName::src0_modifiers)->getImm();
683 unsigned Src1Mods =
684 TII->getNamedOperand(I, AMDGPU::OpName::src1_modifiers)->getImm();
685
686 MachineInstrBuilder NewMI = BuildMI(MBB, I, DL, TII->get(UnpackedOpcode));
687 NewMI.addDef(UnpackedDstReg);
688 addOperandAndMods(NewMI, Src0Mods, IsHiBits, *SrcMO0);
689 addOperandAndMods(NewMI, Src1Mods, IsHiBits, *SrcMO1);
690
692 const MachineOperand *SrcMO2 =
693 TII->getNamedOperand(I, AMDGPU::OpName::src2);
694 unsigned Src2Mods =
695 TII->getNamedOperand(I, AMDGPU::OpName::src2_modifiers)->getImm();
696 addOperandAndMods(NewMI, Src2Mods, IsHiBits, *SrcMO2);
697 }
698 NewMI.addImm(ClampVal);
699
700
701 NewMI.addImm(0);
702 return NewMI;
703}
704
705PreservedAnalyses
708 if (!SIPreEmitPeephole().run(MF))
710
712}
713
716 TII = ST.getInstrInfo();
717 TRI = &TII->getRegisterInfo();
719
721
724
725 if (TermI != MBB.end()) {
727 switch (MI.getOpcode()) {
728 case AMDGPU::S_CBRANCH_VCCZ:
729 case AMDGPU::S_CBRANCH_VCCNZ:
730 Changed |= optimizeVccBranch(MI);
731 break;
732 case AMDGPU::S_CBRANCH_EXECZ:
734 break;
735 }
736 }
737
738 if (.hasVGPRIndexMode())
739 continue;
740
741 MachineInstr *SetGPRMI = nullptr;
742 const unsigned Threshold = 20;
743 unsigned Count = 0;
744
745
746
747
748
750 if (Count == Threshold)
751 SetGPRMI = nullptr;
752 else
754
755 if (MI.getOpcode() != AMDGPU::S_SET_GPR_IDX_ON)
756 continue;
757
759 if (!SetGPRMI) {
760 SetGPRMI = &MI;
761 continue;
762 }
763
764 if (optimizeSetGPR(*SetGPRMI, MI))
766 else
767 SetGPRMI = &MI;
768 }
769 }
770
771
772
773
774
775 if (.hasGFX940Insts())
777 for (MachineBasicBlock &MBB : MF) {
778
779
780 auto SchedModel = TII->getSchedModel();
781 SetVector<MachineInstr *> InstrsToUnpack;
784 continue;
785 const MCSchedClassDesc *SchedClassDesc =
787 uint16_t NumMFMACycles =
789 collectUnpackingCandidates(MI, InstrsToUnpack, NumMFMACycles);
790 }
791 for (MachineInstr *MI : InstrsToUnpack) {
792 performF32Unpacking(*MI);
793 }
794 }
795
797}
unsigned const MachineRegisterInfo * MRI
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
Provides AMDGPU specific target descriptions.
ReachingDefInfo InstSet & ToRemove
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
AMD GCN specific subclass of TargetSubtarget.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
This file implements a set that has insertion order iteration characteristics.
static bool isProfitable(const StableFunctionMap::StableFunctionEntries &SFS)
static uint32_t getDenominator()
uint32_t getNumerator() const
static BranchProbability getZero()
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
LLVM_ABI MachineBasicBlock * getFallThrough(bool JumpToFallThrough=true)
Return the fallthrough block if the block can implicitly transfer control to the block after it by fa...
LLVM_ABI BranchProbability getSuccProbability(const_succ_iterator Succ) const
Return probability of the edge from this block to MBB.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< iterator > terminators()
iterator_range< succ_iterator > successors()
MachineInstrBundleIterator< MachineInstr > iterator
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
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.
void RenumberBlocks(MachineBasicBlock *MBBFrom=nullptr)
RenumberBlocks - This discards all of the MachineBasicBlock numbers and recomputes them.
BasicBlockListType::const_iterator const_iterator
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
const MachineBasicBlock * getParent() const
void setFlags(unsigned flags)
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
LLVM_ABI void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
void setIsKill(bool Val=true)
LLVM_ABI bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
static bool isMFMA(const MachineInstr &MI)
static bool modifiesModeRegister(const MachineInstr &MI)
Return true if the instruction modifies the mode register.q.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition SIPreEmitPeephole.cpp:706
A vector that has set insertion semantics.
bool insert(const value_type &X)
Insert a new element into the SetVector.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
virtual MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const
LLVM_ABI const MCSchedClassDesc * resolveSchedClass(const MachineInstr *MI) const
Return the MCSchedClassDesc for this instruction.
ProcResIter getWriteProcResBegin(const MCSchedClassDesc *SC) const
self_iterator getIterator()
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_READONLY bool hasNamedOperand(uint64_t Opcode, OpName NamedIdx)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
NodeAddr< InstrNode * > Instr
This is an optimization pass for GlobalISel generic memory operations.
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
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...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
char & SIPreEmitPeepholeID
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void initializeSIPreEmitPeepholeLegacyPass(PassRegistry &)
uint16_t ReleaseAtCycle
Cycle at which the resource will be released by an instruction, relatively to the cycle in which the ...