LLVM: lib/Target/AMDGPU/SIOptimizeExecMasking.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
21
22using namespace llvm;
23
24#define DEBUG_TYPE "si-optimize-exec-masking"
25
26namespace {
27
28class SIOptimizeExecMasking {
29public:
34 bool run();
35
36private:
43
47
58 bool IgnoreStart = false) const;
65 unsigned MaxInstructions = 20) const;
66 bool optimizeExecSequence();
67 void tryRecordVCmpxAndSaveexecSequence(MachineInstr &MI);
68 bool optimizeVCMPSaveExecSequence(MachineInstr &SaveExecInstr,
70
71 void tryRecordOrSaveexecXorSequence(MachineInstr &MI);
72 bool optimizeOrSaveexecXorSequences();
73};
74
76public:
77 static char ID;
78
81 }
82
84
85 StringRef getPassName() const override {
86 return "SI optimize exec mask operations";
87 }
88
89 void getAnalysisUsage(AnalysisUsage &AU) const override {
92 }
93};
94
95}
96
100 SIOptimizeExecMasking Impl(&MF);
101
102 if (!Impl.run())
104
107 return PA;
108}
109
111 "SI optimize exec mask operations", false, false)
114 "SI optimize exec mask operations", false, false)
115
116char SIOptimizeExecMaskingLegacy::ID = 0;
117
119
120
122 switch (MI.getOpcode()) {
123 case AMDGPU::COPY:
124 case AMDGPU::S_MOV_B64:
125 case AMDGPU::S_MOV_B64_term:
126 case AMDGPU::S_MOV_B32:
127 case AMDGPU::S_MOV_B32_term: {
128 const MachineOperand &Src = MI.getOperand(1);
129 if (Src.isReg() && Src.getReg() == LMC.ExecReg)
130 return MI.getOperand(0).getReg();
131 }
132 }
133
134 return AMDGPU::NoRegister;
135}
136
137
139 switch (MI.getOpcode()) {
140 case AMDGPU::COPY:
141 case AMDGPU::S_MOV_B64:
142 case AMDGPU::S_MOV_B32: {
144 if (Dst.isReg() && Dst.getReg() == LMC.ExecReg && MI.getOperand(1).isReg())
145 return MI.getOperand(1).getReg();
146 break;
147 }
148 case AMDGPU::S_MOV_B64_term:
149 case AMDGPU::S_MOV_B32_term:
151 }
152
154}
155
156
157
159 switch (MI.getOpcode()) {
160 case AMDGPU::S_AND_B64:
161 case AMDGPU::S_OR_B64:
162 case AMDGPU::S_XOR_B64:
163 case AMDGPU::S_ANDN2_B64:
164 case AMDGPU::S_ORN2_B64:
165 case AMDGPU::S_NAND_B64:
166 case AMDGPU::S_NOR_B64:
167 case AMDGPU::S_XNOR_B64: {
169 if (Src1.isReg() && Src1.getReg() == AMDGPU::EXEC)
170 return MI.getOperand(0).getReg();
172 if (Src2.isReg() && Src2.getReg() == AMDGPU::EXEC)
173 return MI.getOperand(0).getReg();
174 break;
175 }
176 case AMDGPU::S_AND_B32:
177 case AMDGPU::S_OR_B32:
178 case AMDGPU::S_XOR_B32:
179 case AMDGPU::S_ANDN2_B32:
180 case AMDGPU::S_ORN2_B32:
181 case AMDGPU::S_NAND_B32:
182 case AMDGPU::S_NOR_B32:
183 case AMDGPU::S_XNOR_B32: {
185 if (Src1.isReg() && Src1.getReg() == AMDGPU::EXEC_LO)
186 return MI.getOperand(0).getReg();
188 if (Src2.isReg() && Src2.getReg() == AMDGPU::EXEC_LO)
189 return MI.getOperand(0).getReg();
190 break;
191 }
192 }
193
194 return AMDGPU::NoRegister;
195}
196
198 switch (Opc) {
199 case AMDGPU::S_AND_B64:
200 return AMDGPU::S_AND_SAVEEXEC_B64;
201 case AMDGPU::S_OR_B64:
202 return AMDGPU::S_OR_SAVEEXEC_B64;
203 case AMDGPU::S_XOR_B64:
204 return AMDGPU::S_XOR_SAVEEXEC_B64;
205 case AMDGPU::S_ANDN2_B64:
206 return AMDGPU::S_ANDN2_SAVEEXEC_B64;
207 case AMDGPU::S_ORN2_B64:
208 return AMDGPU::S_ORN2_SAVEEXEC_B64;
209 case AMDGPU::S_NAND_B64:
210 return AMDGPU::S_NAND_SAVEEXEC_B64;
211 case AMDGPU::S_NOR_B64:
212 return AMDGPU::S_NOR_SAVEEXEC_B64;
213 case AMDGPU::S_XNOR_B64:
214 return AMDGPU::S_XNOR_SAVEEXEC_B64;
215 case AMDGPU::S_AND_B32:
216 return AMDGPU::S_AND_SAVEEXEC_B32;
217 case AMDGPU::S_OR_B32:
218 return AMDGPU::S_OR_SAVEEXEC_B32;
219 case AMDGPU::S_XOR_B32:
220 return AMDGPU::S_XOR_SAVEEXEC_B32;
221 case AMDGPU::S_ANDN2_B32:
222 return AMDGPU::S_ANDN2_SAVEEXEC_B32;
223 case AMDGPU::S_ORN2_B32:
224 return AMDGPU::S_ORN2_SAVEEXEC_B32;
225 case AMDGPU::S_NAND_B32:
226 return AMDGPU::S_NAND_SAVEEXEC_B32;
227 case AMDGPU::S_NOR_B32:
228 return AMDGPU::S_NOR_SAVEEXEC_B32;
229 case AMDGPU::S_XNOR_B32:
230 return AMDGPU::S_XNOR_SAVEEXEC_B32;
231 default:
232 return AMDGPU::INSTRUCTION_LIST_END;
233 }
234}
235
236
237
238bool SIOptimizeExecMasking::removeTerminatorBit(MachineInstr &MI) const {
239 switch (MI.getOpcode()) {
240 case AMDGPU::S_MOV_B32_term: {
241 bool RegSrc = MI.getOperand(1).isReg();
242 MI.setDesc(TII->get(RegSrc ? AMDGPU::COPY : AMDGPU::S_MOV_B32));
243 return true;
244 }
245 case AMDGPU::S_MOV_B64_term: {
246 bool RegSrc = MI.getOperand(1).isReg();
247 MI.setDesc(TII->get(RegSrc ? AMDGPU::COPY : AMDGPU::S_MOV_B64));
248 return true;
249 }
250 case AMDGPU::S_XOR_B64_term: {
251
252
253 MI.setDesc(TII->get(AMDGPU::S_XOR_B64));
254 return true;
255 }
256 case AMDGPU::S_XOR_B32_term: {
257
258
259 MI.setDesc(TII->get(AMDGPU::S_XOR_B32));
260 return true;
261 }
262 case AMDGPU::S_OR_B64_term: {
263
264
265 MI.setDesc(TII->get(AMDGPU::S_OR_B64));
266 return true;
267 }
268 case AMDGPU::S_OR_B32_term: {
269
270
271 MI.setDesc(TII->get(AMDGPU::S_OR_B32));
272 return true;
273 }
274 case AMDGPU::S_ANDN2_B64_term: {
275
276
277 MI.setDesc(TII->get(AMDGPU::S_ANDN2_B64));
278 return true;
279 }
280 case AMDGPU::S_ANDN2_B32_term: {
281
282
283 MI.setDesc(TII->get(AMDGPU::S_ANDN2_B32));
284 return true;
285 }
286 case AMDGPU::S_AND_B64_term: {
287
288
289 MI.setDesc(TII->get(AMDGPU::S_AND_B64));
290 return true;
291 }
292 case AMDGPU::S_AND_B32_term: {
293
294
295 MI.setDesc(TII->get(AMDGPU::S_AND_B32));
296 return true;
297 }
298 default:
299 return false;
300 }
301}
302
303
304
305
309
310 bool Seen = false;
313 if (->isTerminator())
314 return Seen ? FirstNonTerm : I;
315
316 if (removeTerminatorBit(*I)) {
317 if (!Seen) {
318 FirstNonTerm = I;
319 Seen = true;
320 }
321 }
322 }
323
324 return FirstNonTerm;
325}
326
329 const unsigned InstLimit = 25;
330
332 for (unsigned N = 0; N <= InstLimit && I != E; ++I, ++N) {
333 Register CopyFromExec = isCopyFromExec(*I);
334 if (CopyFromExec.isValid())
335 return I;
336 }
337
338 return E;
339}
340
341
342
343
346 if (Succ->isLiveIn(Reg))
347 return true;
348 }
349
350 return false;
351}
352
353
354
355
356
357
358MachineInstr *SIOptimizeExecMasking::findInstrBackwards(
362 unsigned MaxInstructions) const {
365 unsigned CurrentIteration = 0;
366
367 for (++A; CurrentIteration < MaxInstructions && A != E; ++A) {
368 if (A->isDebugInstr())
369 continue;
370
371 if (Pred(&*A))
372 return &*A;
373
375 if (A->modifiesRegister(Reg, TRI))
376 return nullptr;
377
378
379
380
381
382 if (Terminator && KillFlagCandidates && A != Terminator &&
383 A->killsRegister(Reg, TRI)) {
385 if (MO.isReg() && MO.isKill()) {
386 Register Candidate = MO.getReg();
387 if (Candidate != Reg && TRI->regsOverlap(Candidate, Reg))
388 KillFlagCandidates->push_back(&MO);
389 }
390 }
391 }
392 }
393
394 ++CurrentIteration;
395 }
396
397 return nullptr;
398}
399
400
401
402
403
404
405
406bool SIOptimizeExecMasking::isRegisterInUseBetween(MachineInstr &Stop,
409 bool UseLiveOuts,
410 bool IgnoreStart) const {
412 if (UseLiveOuts)
413 LR.addLiveOuts(*Stop.getParent());
414
416
417 if (IgnoreStart)
418 ++A;
419
421 LR.stepBackward(*A);
422 }
423
424 return !LR.available(Reg) || MRI->isReserved(Reg);
425}
426
427
428
429bool SIOptimizeExecMasking::isRegisterInUseAfter(MachineInstr &Stop,
431 return isRegisterInUseBetween(Stop, *Stop.getParent()->rbegin(), Reg, true);
432}
433
434
435
436
437
438
439
440
441
442
443
444bool SIOptimizeExecMasking::optimizeExecSequence() {
450 continue;
451
452
453
455
456 unsigned SearchCount = 0;
457 const unsigned SearchLimit = 5;
458 while (I != E && SearchCount++ < SearchLimit) {
459 CopyToExec = isCopyToExec(*I);
460 if (CopyToExec)
461 break;
462 ++I;
463 }
464
465 if (!CopyToExec)
466 continue;
467
468
469 auto *CopyToExecInst = &*I;
470 auto CopyFromExecInst = findExecCopy(MBB, I);
471 if (CopyFromExecInst == E) {
472 auto PrepareExecInst = std::next(I);
473 if (PrepareExecInst == E)
474 continue;
475
476 if (CopyToExecInst->getOperand(1).isKill() &&
478 LLVM_DEBUG(dbgs() << "Fold exec copy: " << *PrepareExecInst);
479
480 PrepareExecInst->getOperand(0).setReg(LMC.ExecReg);
481
482 LLVM_DEBUG(dbgs() << "into: " << *PrepareExecInst << '\n');
483
484 CopyToExecInst->eraseFromParent();
486 }
487
488 continue;
489 }
490
492
493 LLVM_DEBUG(dbgs() << "Exec copy source register is live out\n");
494 continue;
495 }
496
497 Register CopyFromExec = CopyFromExecInst->getOperand(0).getReg();
500
502 J = std::next(CopyFromExecInst->getIterator()),
503 JE = I->getIterator();
504 J != JE; ++J) {
505 if (SaveExecInst && J->readsRegister(LMC.ExecReg, TRI)) {
506 LLVM_DEBUG(dbgs() << "exec read prevents saveexec: " << *J << '\n');
507
508
509 SaveExecInst = nullptr;
510 break;
511 }
512
513 bool ReadsCopyFromExec = J->readsRegister(CopyFromExec, TRI);
514
515 if (J->modifiesRegister(CopyToExec, TRI)) {
516 if (SaveExecInst) {
519 SaveExecInst = nullptr;
520 break;
521 }
522
523 unsigned SaveExecOp = getSaveExecOp(J->getOpcode());
524 if (SaveExecOp == AMDGPU::INSTRUCTION_LIST_END)
525 break;
526
527 if (ReadsCopyFromExec) {
528 SaveExecInst = &*J;
529 LLVM_DEBUG(dbgs() << "Found save exec op: " << *SaveExecInst << '\n');
530 continue;
531 }
532 LLVM_DEBUG(dbgs() << "Instruction does not read exec copy: " << *J
533 << '\n');
534 break;
535 }
536 if (ReadsCopyFromExec && !SaveExecInst) {
537
538
539
540
541
542
543
544
545 LLVM_DEBUG(dbgs() << "Found second use of save inst candidate: " << *J
546 << '\n');
547 break;
548 }
549
550 if (SaveExecInst && J->readsRegister(CopyToExec, TRI)) {
551 assert(SaveExecInst != &*J);
553 }
554 }
555
556 if (!SaveExecInst)
557 continue;
558
559 LLVM_DEBUG(dbgs() << "Insert save exec op: " << *SaveExecInst << '\n');
560
563
565
566 if (Src0.isReg() && Src0.getReg() == CopyFromExec) {
567 OtherOp = &Src1;
568 } else if (Src1.isReg() && Src1.getReg() == CopyFromExec) {
570 break;
571
572 OtherOp = &Src0;
573 } else
575
576 CopyFromExecInst->eraseFromParent();
577
578 auto InsPt = SaveExecInst->getIterator();
580
582 CopyFromExec)
585
586 CopyToExecInst->eraseFromParent();
587
588 for (MachineInstr *OtherInst : OtherUseInsts) {
589 OtherInst->substituteRegister(CopyToExec, LMC.ExecReg,
590 AMDGPU::NoSubRegister, *TRI);
591 }
592
594 }
595
597}
598
599
600
601bool SIOptimizeExecMasking::optimizeVCMPSaveExecSequence(
604
605 if (NewOpcode == -1)
606 return false;
607
608 MachineOperand *Src0 = TII->getNamedOperand(VCmp, AMDGPU::OpName::src0);
609 MachineOperand *Src1 = TII->getNamedOperand(VCmp, AMDGPU::OpName::src1);
610
612
614 if (!SaveExecInstr.uses().empty()) {
615 bool IsSGPR32 = TRI->getRegSizeInBits(MoveDest, *MRI) == 32;
616 unsigned MovOpcode = IsSGPR32 ? AMDGPU::S_MOV_B32 : AMDGPU::S_MOV_B64;
618 SaveExecInstr.getDebugLoc(), TII->get(MovOpcode), MoveDest)
619 .addReg(LMC.ExecReg);
620 }
621
622
623
624 auto Builder = BuildMI(*VCmp.getParent(), std::next(InsertPosIt),
626
627 auto TryAddImmediateValueFromNamedOperand =
628 [&](AMDGPU::OpName OperandName) -> void {
629 if (auto *Mod = TII->getNamedOperand(VCmp, OperandName))
630 Builder.addImm(Mod->getImm());
631 };
632
633 TryAddImmediateValueFromNamedOperand(AMDGPU::OpName::src0_modifiers);
634 Builder.add(*Src0);
635
636 TryAddImmediateValueFromNamedOperand(AMDGPU::OpName::src1_modifiers);
637 Builder.add(*Src1);
638
639 TryAddImmediateValueFromNamedOperand(AMDGPU::OpName::clamp);
640
641 TryAddImmediateValueFromNamedOperand(AMDGPU::OpName::op_sel);
642
643
644 if (Src0->isReg())
645 MRI->clearKillFlags(Src0->getReg());
646 if (Src1->isReg())
647 MRI->clearKillFlags(Src1->getReg());
648
650 MO->setIsKill(false);
651
654
655 return true;
656}
657
658
659
660
661
662
663
664
665void SIOptimizeExecMasking::tryRecordVCmpxAndSaveexecSequence(
667 if (->hasGFX10_3Insts())
668 return;
669
670 if (MI.getOpcode() != LMC.AndSaveExecOpc)
671 return;
672
673 Register SaveExecDest = MI.getOperand(0).getReg();
674 if (->isSGPRReg(*MRI, SaveExecDest))
675 return;
676
677 MachineOperand *SaveExecSrc0 = TII->getNamedOperand(MI, AMDGPU::OpName::src0);
678 if (!SaveExecSrc0->isReg())
679 return;
680
681
682
683
684
685
687
688
689
690 VCmp = findInstrBackwards(
694 Check->modifiesRegister(SaveExecSrc0->getReg(), TRI);
695 },
696 {LMC.ExecReg, SaveExecSrc0->getReg()});
697
698 if (!VCmp)
699 return;
700
701 MachineOperand *VCmpDest = TII->getNamedOperand(*VCmp, AMDGPU::OpName::sdst);
702 assert(VCmpDest && "Should have an sdst operand!");
703
704
705 MachineOperand *Src0 = TII->getNamedOperand(*VCmp, AMDGPU::OpName::src0);
707 MI.modifiesRegister(Src0->getReg(), TRI))
708 return;
709
710 MachineOperand *Src1 = TII->getNamedOperand(*VCmp, AMDGPU::OpName::src1);
712 MI.modifiesRegister(Src1->getReg(), TRI))
713 return;
714
715
716
717
718
720 return;
721
722
723
724 if (isRegisterInUseBetween(*VCmp, MI, VCmpDest->getReg(), false, true) ||
725 isRegisterInUseAfter(MI, VCmpDest->getReg()))
726 return;
727
728
729
730
731
733 if (Src0->isReg())
735
736 if (Src1->isReg())
738
739 if (!findInstrBackwards(
741 VCmp, &KillFlagCandidates))
742 return;
743
744 if (VCmp)
745 SaveExecVCmpMapping[&MI] = VCmp;
746}
747
748
749
750
751
752
753void SIOptimizeExecMasking::tryRecordOrSaveexecXorSequence(MachineInstr &MI) {
754 if (MI.getOpcode() == LMC.XorOpc && &MI != &MI.getParent()->front()) {
758
759 if (XorDst.isReg() && XorDst.getReg() == LMC.ExecReg && XorSrc0.isReg() &&
760 XorSrc1.isReg() &&
761 (XorSrc0.getReg() == LMC.ExecReg || XorSrc1.getReg() == LMC.ExecReg)) {
762
763
764
765 MachineInstr &PossibleOrSaveexec = *MI.getPrevNode();
766 if (PossibleOrSaveexec.getOpcode() != LMC.OrSaveExecOpc)
767 return;
768
771 if (OrDst.isReg() && OrSrc0.isReg()) {
772 if ((XorSrc0.getReg() == LMC.ExecReg &&
775 XorSrc1.getReg() == LMC.ExecReg)) {
776 OrXors.emplace_back(&PossibleOrSaveexec, &MI);
777 }
778 }
779 }
780 }
781}
782
783bool SIOptimizeExecMasking::optimizeOrSaveexecXorSequences() {
784 if (OrXors.empty()) {
785 return false;
786 }
787
789
790 for (const auto &Pair : OrXors) {
794 BuildMI(*Or->getParent(), Or->getIterator(), Or->getDebugLoc(),
795 TII->get(LMC.AndN2SaveExecOpc), Or->getOperand(0).getReg())
796 .addReg(Or->getOperand(1).getReg());
797
798 Or->eraseFromParent();
799 Xor->eraseFromParent();
800
802 }
803
805}
806
807bool SIOptimizeExecMaskingLegacy::runOnMachineFunction(MachineFunction &MF) {
809 return false;
810
811 return SIOptimizeExecMasking(&MF).run();
812}
813
814bool SIOptimizeExecMasking::run() {
815 bool Changed = optimizeExecSequence();
816
817 OrXors.clear();
818 SaveExecVCmpMapping.clear();
819 KillFlagCandidates.clear();
820 static unsigned SearchWindow = 10;
822 unsigned SearchCount = 0;
823
825 if (MI.isDebugInstr())
826 continue;
827
828 if (SearchCount >= SearchWindow) {
829 break;
830 }
831
832 tryRecordOrSaveexecXorSequence(MI);
833 tryRecordVCmpxAndSaveexecSequence(MI);
834
835 if (MI.modifiesRegister(LMC.ExecReg, TRI)) {
836 break;
837 }
838
839 ++SearchCount;
840 }
841 }
842
843 Changed |= optimizeOrSaveexecXorSequences();
844 for (const auto &Entry : SaveExecVCmpMapping) {
847
848 Changed |= optimizeVCMPSaveExecSequence(*SaveExecInstr, *VCmpInstr);
849 }
850
852}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Provides AMDGPU specific target descriptions.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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.
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static unsigned getSaveExecOp(unsigned Opc)
Definition SIOptimizeExecMasking.cpp:197
static Register isLogicalOpOnExec(const MachineInstr &MI)
If MI is a logical operation on an exec value, return the register copied to.
Definition SIOptimizeExecMasking.cpp:158
static bool isLiveOut(const MachineBasicBlock &MBB, unsigned Reg)
Definition SIOptimizeExecMasking.cpp:344
Interface definition for SIRegisterInfo.
This file defines the SmallVector class.
static const LaneMaskConstants & get(const GCNSubtarget &ST)
Represent the analysis usage information of a pass.
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Represents analyses that only rely on functions' control flow.
A set of register units used to track register liveness.
Wrapper class representing physical registers. Should be passed by value.
Instructions::iterator instr_iterator
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
reverse_iterator rbegin()
MachineInstrBundleIterator< MachineInstr > iterator
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, unsigned flags=0, 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
bool isCommutable(QueryType Type=IgnoreBundle) const
Return true if this may be a 2- or 3-address instruction (of the form "X = op Y, Z,...
mop_range uses()
Returns all operands which may be register uses.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition SIOptimizeExecMasking.cpp:98
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.
StringRef - Represent a constant reference to a string, i.e.
reverse_self_iterator getReverseIterator()
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVM_READONLY int getVCMPXOpFromVCMP(uint16_t Opcode)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
std::reverse_iterator< iterator > rend() const
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.
char & SIOptimizeExecMaskingLegacyID
Definition SIOptimizeExecMasking.cpp:118
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
@ Mod
The access may modify the value stored in memory.
@ Xor
Bitwise or logical XOR of integers.
void initializeSIOptimizeExecMaskingLegacyPass(PassRegistry &)
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.