LLVM: lib/Target/AMDGPU/SILowerControlFlow.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
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
63
64using namespace llvm;
65
66#define DEBUG_TYPE "si-lower-control-flow"
67
71
72namespace {
73
74class SILowerControlFlow {
75private:
87
90
91 bool EnableOptimizeEndCf = false;
92
94
99
101
102 void findMaskOperands(MachineInstr &MI, unsigned OpNo,
104
106
108
110
111
112
113
117
118
122 assert(I->isTerminator());
123
124
126 while (I != End && ->isUnconditionalBranch())
127 ++I;
128 return I;
129 }
130
131
132 void optimizeEndCf();
133
134public:
135 SILowerControlFlow(const GCNSubtarget *ST, LiveIntervals *LIS,
136 LiveVariables *LV, MachineDominatorTree *MDT,
137 MachinePostDominatorTree *PDT)
138 : LIS(LIS), LV(LV), MDT(MDT), PDT(PDT),
139 LMC(AMDGPU::LaneMaskConstants::get(*ST)) {}
140 bool run(MachineFunction &MF);
141};
142
144public:
145 static char ID;
146
147 SILowerControlFlowLegacy() : MachineFunctionPass(ID) {}
148
149 bool runOnMachineFunction(MachineFunction &MF) override;
150
151 StringRef getPassName() const override {
152 return "SI Lower control flow pseudo instructions";
153 }
154
155 void getAnalysisUsage(AnalysisUsage &AU) const override {
157
158 AU.addPreserved();
159 AU.addPreserved();
164 }
165};
166
167}
168
169char SILowerControlFlowLegacy::ID = 0;
170
172 false, false)
173
177
179}
180
182
187
188 while (!Worklist.empty()) {
190
191 if (MBB == End || !Visited.insert(MBB).second)
192 continue;
194 return true;
195
196 Worklist.append(MBB->succ_begin(), MBB->succ_end());
197 }
198
199 return false;
200}
201
203 Register SaveExecReg = MI.getOperand(0).getReg();
204 auto U = MRI->use_instr_nodbg_begin(SaveExecReg);
205
206 if (U == MRI->use_instr_nodbg_end() ||
207 std::next(U) != MRI->use_instr_nodbg_end() ||
208 U->getOpcode() != AMDGPU::SI_END_CF)
209 return false;
210
211 return true;
212}
213
214void SILowerControlFlow::emitIf(MachineInstr &MI) {
215 MachineBasicBlock &MBB = *MI.getParent();
218 Register SaveExecReg = MI.getOperand(0).getReg();
219 MachineOperand& Cond = MI.getOperand(1);
220 assert(Cond.getSubReg() == AMDGPU::NoSubRegister);
221
222 MachineOperand &ImpDefSCC = MI.getOperand(4);
224
225
226
227
229
230 if (SimpleIf) {
231
232
233 auto UseMI = MRI->use_instr_nodbg_begin(SaveExecReg);
235 }
236
237
238
239 Register CopyReg = SimpleIf ? SaveExecReg
240 : MRI->createVirtualRegister(BoolRC);
241 MachineInstr *CopyExec = BuildMI(MBB, I, DL, TII->get(AMDGPU::COPY), CopyReg)
244 LoweredIf.insert(CopyReg);
245
246 Register Tmp = MRI->createVirtualRegister(BoolRC);
247
248 MachineInstr *And =
250 if (LV)
252
253 setImpSCCDefDead(*And, true);
254
255 MachineInstr *Xor = nullptr;
256 if (!SimpleIf) {
260 setImpSCCDefDead(*Xor, ImpDefSCC.isDead());
261 }
262
263
264
265 MachineInstr *SetExec =
268 if (LV)
270
271
272
273 I = skipToUncondBrOrEnd(MBB, I);
274
275
276
277 MachineInstr *NewBr = BuildMI(MBB, I, DL, TII->get(AMDGPU::S_CBRANCH_EXECZ))
279
280 if (!LIS) {
281 MI.eraseFromParent();
282 return;
283 }
284
286
287
288
290
291 if (!SimpleIf)
295
296 MI.eraseFromParent();
297
298
299
300
301 RecomputeRegs.insert(SaveExecReg);
303 if (!SimpleIf)
305}
306
307void SILowerControlFlow::emitElse(MachineInstr &MI) {
308 MachineBasicBlock &MBB = *MI.getParent();
310
311 Register DstReg = MI.getOperand(0).getReg();
312 Register SrcReg = MI.getOperand(1).getReg();
313
315
316
317
318 Register SaveReg = MRI->createVirtualRegister(BoolRC);
319 MachineInstr *OrSaveExec =
322 if (LV)
324
325 MachineBasicBlock *DestBB = MI.getOperand(2).getMBB();
326
328
329
330
334
335 MachineInstr *Xor =
339
340
341
342 ElsePt = skipToUncondBrOrEnd(MBB, ElsePt);
343
344 MachineInstr *Branch =
347
348 if (!LIS) {
349 MI.eraseFromParent();
350 return;
351 }
352
354 MI.eraseFromParent();
355
358
361
362 RecomputeRegs.insert(SrcReg);
363 RecomputeRegs.insert(DstReg);
365}
366
367void SILowerControlFlow::emitIfBreak(MachineInstr &MI) {
368 MachineBasicBlock &MBB = *MI.getParent();
370 auto Dst = MI.getOperand(0).getReg();
371
372
373
374
375
376 bool SkipAnding = false;
377 if (MI.getOperand(1).isReg()) {
378 if (MachineInstr *Def = MRI->getUniqueVRegDef(MI.getOperand(1).getReg())) {
379 SkipAnding = Def->getParent() == MI.getParent()
381 }
382 }
383
384
385
386 MachineInstr *And = nullptr, *Or = nullptr;
388 if (!SkipAnding) {
389 AndReg = MRI->createVirtualRegister(BoolRC);
393 if (LV)
398 } else {
402 if (LV)
404 }
405 if (LV)
407
408 if (LIS) {
410 if (And) {
411
412 RecomputeRegs.insert(And->getOperand(2).getReg());
415 }
416 }
417
418 MI.eraseFromParent();
419}
420
421void SILowerControlFlow::emitLoop(MachineInstr &MI) {
422 MachineBasicBlock &MBB = *MI.getParent();
424
425 MachineInstr *AndN2 =
429 if (LV)
431
432 auto BranchPt = skipToUncondBrOrEnd(MBB, MI.getIterator());
433 MachineInstr *Branch =
436
437 if (LIS) {
438 RecomputeRegs.insert(MI.getOperand(0).getReg());
441 }
442
443 MI.eraseFromParent();
444}
445
447SILowerControlFlow::skipIgnoreExecInstsTrivialSucc(
449
450 SmallPtrSet<const MachineBasicBlock *, 4> Visited;
451 MachineBasicBlock *B = &MBB;
452 do {
453 if (!Visited.insert(B).second)
455
457 for ( ; It != E; ++It) {
458 if (TII->mayReadEXEC(*MRI, *It))
459 break;
460 }
461
462 if (It != E)
463 return It;
464
465 if (B->succ_size() != 1)
467
468
469 MachineBasicBlock *Succ = *B->succ_begin();
470
471 It = Succ->begin();
472 B = Succ;
473 } while (true);
474}
475
476MachineBasicBlock *SILowerControlFlow::emitEndCf(MachineInstr &MI) {
477 MachineBasicBlock &MBB = *MI.getParent();
479
481
482
483
484
485 bool NeedBlockSplit = false;
486 Register DataReg = MI.getOperand(0).getReg();
489 if (I->modifiesRegister(DataReg, TRI)) {
490 NeedBlockSplit = true;
491 break;
492 }
493 }
494
495 unsigned Opcode = LMC.OrOpc;
496 MachineBasicBlock *SplitBB = &MBB;
497 if (NeedBlockSplit) {
498 SplitBB = MBB.splitAt(MI, true, LIS);
499 if (SplitBB != &MBB && (MDT || PDT)) {
502 for (MachineBasicBlock *Succ : SplitBB->successors()) {
503 DTUpdates.push_back({DomTreeT::Insert, SplitBB, Succ});
504 DTUpdates.push_back({DomTreeT::Delete, &MBB, Succ});
505 }
506 DTUpdates.push_back({DomTreeT::Insert, &MBB, SplitBB});
507 if (MDT)
509 if (PDT)
511 }
513 InsPt = MI;
514 }
515
519 if (LV) {
521
522 if (SplitBB != &MBB) {
523
524
525
526
527 DenseSet DefInOrigBlock;
528
529 for (MachineBasicBlock *BlockPiece : {&MBB, SplitBB}) {
530 for (MachineInstr &X : *BlockPiece) {
531 for (MachineOperand &Op : X.all_defs()) {
532 if (Op.getReg().isVirtual())
533 DefInOrigBlock.insert(Op.getReg());
534 }
535 }
536 }
537
538 for (unsigned i = 0, e = MRI->getNumVirtRegs(); i != e; ++i) {
539 Register Reg = Register::index2VirtReg(i);
541
543 VI.AliveBlocks.set(SplitBB->getNumber());
544 else {
545 for (MachineInstr *Kill : VI.Kills) {
546 if (Kill->getParent() == SplitBB && !DefInOrigBlock.contains(Reg))
548 }
549 }
550 }
551 }
552 }
553
554 LoweredEndCf.insert(NewMI);
555
556 if (LIS)
558
559 MI.eraseFromParent();
560
561 if (LIS)
563 return SplitBB;
564}
565
566
567
568void SILowerControlFlow::findMaskOperands(MachineInstr &MI, unsigned OpNo,
569 SmallVectorImpl &Src) const {
570 MachineOperand &Op = MI.getOperand(OpNo);
571 if (.isReg() ||
.getReg().isVirtual()) {
572 Src.push_back(Op);
573 return;
574 }
575
576 MachineInstr *Def = MRI->getUniqueVRegDef(Op.getReg());
577 if (!Def || Def->getParent() != MI.getParent() ||
578 !(Def->isFullCopy() || (Def->getOpcode() == MI.getOpcode())))
579 return;
580
581
582
583
584 for (auto I = Def->getIterator(); I != MI.getIterator(); ++I)
585 if (I->modifiesRegister(AMDGPU::EXEC, TRI) &&
586 !(I->isCopy() && I->getOperand(0).getReg() != LMC.ExecReg))
587 return;
588
589 for (const auto &SrcOp : Def->explicit_operands())
590 if (SrcOp.isReg() && SrcOp.isUse() &&
591 (SrcOp.getReg().isVirtual() || SrcOp.getReg() == LMC.ExecReg))
592 Src.push_back(SrcOp);
593}
594
595
596
597
598
599void SILowerControlFlow::combineMasks(MachineInstr &MI) {
600 assert(MI.getNumExplicitOperands() == 3);
602 unsigned OpToReplace = 1;
603 findMaskOperands(MI, 1, Ops);
604 if (Ops.size() == 1) OpToReplace = 2;
605 findMaskOperands(MI, 2, Ops);
606 if (Ops.size() != 3) return;
607
608 unsigned UniqueOpndIdx;
609 if (Ops[0].isIdenticalTo(Ops[1])) UniqueOpndIdx = 2;
610 else if (Ops[0].isIdenticalTo(Ops[2])) UniqueOpndIdx = 1;
611 else if (Ops[1].isIdenticalTo(Ops[2])) UniqueOpndIdx = 1;
612 else return;
613
614 Register Reg = MI.getOperand(OpToReplace).getReg();
615 MI.removeOperand(OpToReplace);
616 MI.addOperand(Ops[UniqueOpndIdx]);
618 MRI->getUniqueVRegDef(Reg)->eraseFromParent();
619}
620
621void SILowerControlFlow::optimizeEndCf() {
622
623
624 if (!EnableOptimizeEndCf)
625 return;
626
627 for (MachineInstr *MI : reverse(LoweredEndCf)) {
628 MachineBasicBlock &MBB = *MI->getParent();
630 skipIgnoreExecInstsTrivialSucc(MBB, std::next(MI->getIterator()));
632 continue;
633
634
636 = TII->getNamedOperand(*Next, AMDGPU::OpName::src1)->getReg();
637 assert(SavedExec.isVirtual() && "Expected saved exec to be src1!");
638
639 const MachineInstr *Def = MRI->getUniqueVRegDef(SavedExec);
640 if (Def && LoweredIf.count(SavedExec)) {
642 if (LIS)
645 if (LV)
646 Reg = TII->getNamedOperand(*MI, AMDGPU::OpName::src1)->getReg();
647 MI->eraseFromParent();
648 if (LV)
650 removeMBBifRedundant(MBB);
651 }
652 }
653}
654
655MachineBasicBlock *SILowerControlFlow::process(MachineInstr &MI) {
656 MachineBasicBlock &MBB = *MI.getParent();
658 MachineInstr *Prev = (I != MBB.begin()) ? &*(std::prev(I)) : nullptr;
659
660 MachineBasicBlock *SplitBB = &MBB;
661
662 switch (MI.getOpcode()) {
663 case AMDGPU::SI_IF:
664 emitIf(MI);
665 break;
666
667 case AMDGPU::SI_ELSE:
668 emitElse(MI);
669 break;
670
671 case AMDGPU::SI_IF_BREAK:
672 emitIfBreak(MI);
673 break;
674
675 case AMDGPU::SI_LOOP:
676 emitLoop(MI);
677 break;
678
679 case AMDGPU::SI_WATERFALL_LOOP:
680 MI.setDesc(TII->get(AMDGPU::S_CBRANCH_EXECNZ));
681 break;
682
683 case AMDGPU::SI_END_CF:
684 SplitBB = emitEndCf(MI);
685 break;
686
687 default:
688 assert(false && "Attempt to process unsupported instruction");
689 break;
690 }
691
695 MachineInstr &MaskMI = *I;
697 case AMDGPU::S_AND_B64:
698 case AMDGPU::S_OR_B64:
699 case AMDGPU::S_AND_B32:
700 case AMDGPU::S_OR_B32:
701
702 combineMasks(MaskMI);
703 break;
704 default:
706 break;
707 }
708 }
709
710 return SplitBB;
711}
712
713bool SILowerControlFlow::removeMBBifRedundant(MachineBasicBlock &MBB) {
715 if (.isDebugInstr() &&
.isUnconditionalBranch())
716 return false;
717 }
718
720
722 MachineBasicBlock *FallThrough = nullptr;
723
726
729 if (P->getFallThrough(false) == &MBB)
730 FallThrough = P;
732 DTUpdates.push_back({DomTreeT::Insert, P, Succ});
733 DTUpdates.push_back({DomTreeT::Delete, P, &MBB});
734 }
736 if (LIS) {
739 }
740 if (MDT)
742 if (PDT)
744
748
749
750 MachineInstr *BranchMI = BuildMI(*FallThrough, FallThrough->end(),
753 if (LIS)
755 }
756
757 return true;
758}
759
760bool SILowerControlFlow::run(MachineFunction &MF) {
761 const GCNSubtarget &ST = MF.getSubtarget();
766
768 BoolRC = TRI->getBoolRC();
769
770
771 const bool CanDemote =
773 for (auto &MBB : MF) {
774 bool IsKillBlock = false;
776 if (TII->isKillTerminator(Term.getOpcode())) {
778 IsKillBlock = true;
779 break;
780 }
781 }
782 if (CanDemote && !IsKillBlock) {
784 if (MI.getOpcode() == AMDGPU::SI_DEMOTE_I1) {
786 break;
787 }
788 }
789 }
790 }
791
795 BI != MF.end(); BI = NextBB) {
796 NextBB = std::next(BI);
797 MachineBasicBlock *MBB = &*BI;
798
804 MachineBasicBlock *SplitMBB = MBB;
805
806 switch (MI.getOpcode()) {
807 case AMDGPU::SI_IF:
808 case AMDGPU::SI_ELSE:
809 case AMDGPU::SI_IF_BREAK:
810 case AMDGPU::SI_WATERFALL_LOOP:
811 case AMDGPU::SI_LOOP:
812 case AMDGPU::SI_END_CF:
813 SplitMBB = process(MI);
815 break;
816 }
817
818 if (SplitMBB != MBB) {
821 }
822 }
823 }
824
825 optimizeEndCf();
826
828
834 }
835 }
836
837 RecomputeRegs.clear();
838 LoweredEndCf.clear();
839 LoweredIf.clear();
840 KillBlocks.clear();
841
843}
844
845bool SILowerControlFlowLegacy::runOnMachineFunction(MachineFunction &MF) {
846 const GCNSubtarget *ST = &MF.getSubtarget();
847
848 auto *LISWrapper = getAnalysisIfAvailable();
849 LiveIntervals *LIS = LISWrapper ? &LISWrapper->getLIS() : nullptr;
850
851 auto *LVWrapper = getAnalysisIfAvailable();
852 LiveVariables *LV = LVWrapper ? &LVWrapper->getLV() : nullptr;
853 auto *MDTWrapper = getAnalysisIfAvailable();
854 MachineDominatorTree *MDT = MDTWrapper ? &MDTWrapper->getDomTree() : nullptr;
855 auto *PDTWrapper =
856 getAnalysisIfAvailable();
857 MachinePostDominatorTree *PDT =
858 PDTWrapper ? &PDTWrapper->getPostDomTree() : nullptr;
859 return SILowerControlFlow(ST, LIS, LV, MDT, PDT).run(MF);
860}
861
862PreservedAnalyses
872
873 bool Changed = SILowerControlFlow(ST, LIS, LV, MDT, PDT).run(MF);
876
883 return PA;
884}
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder & UseMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
Provides AMDGPU specific target descriptions.
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
AMD GCN specific subclass of TargetSubtarget.
const AbstractManglingParser< Derived, Alloc >::OperatorInfo AbstractManglingParser< Derived, Alloc >::Ops[]
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > & Cond
static cl::opt< bool > RemoveRedundantEndcf("amdgpu-remove-redundant-endcf", cl::init(true), cl::ReallyHidden)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool IsDead
Definition SILowerControlFlow.cpp:174
static bool isSimpleIf(const MachineInstr &MI, const MachineRegisterInfo *MRI)
Definition SILowerControlFlow.cpp:202
This file defines the SmallSet class.
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
const unsigned XorTermOpc
const unsigned MovTermOpc
const unsigned OrSaveExecOpc
const unsigned AndN2TermOpc
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
AnalysisUsage & addUsedIfAvailable()
Add the specified Pass class to the set of analyses used by this pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
Implements a dense probed hash-table based set.
void applyUpdates(ArrayRef< UpdateType > Updates)
Inform the dominator tree about a sequence of CFG edge insertions and deletions and perform a batch u...
CallingConv::ID getCallingConv() const
getCallingConv()/setCallingConv(CC) - These method get and set the calling convention of this functio...
void removeAllRegUnitsForPhysReg(MCRegister Reg)
Remove associated live ranges for the register units associated with Reg.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
LLVM_ABI void handleMove(MachineInstr &MI, bool UpdateFlags=false)
Call this method to notify LiveIntervals that instruction MI has been moved within a basic block.
void RemoveMachineInstrFromMaps(MachineInstr &MI)
void removeInterval(Register Reg)
Interval removal.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
SlotIndex ReplaceMachineInstrInMaps(MachineInstr &MI, MachineInstr &NewMI)
LLVM_ABI void replaceKillInstruction(Register Reg, MachineInstr &OldMI, MachineInstr &NewMI)
replaceKillInstruction - Update register kill info by replacing a kill instruction with a new one.
LLVM_ABI void recomputeForSingleDefVirtReg(Register Reg)
Recompute liveness from scratch for a virtual register Reg that is known to have a single def that do...
LLVM_ABI VarInfo & getVarInfo(Register Reg)
getVarInfo - Return the VarInfo structure for the specified VIRTUAL register.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
succ_iterator succ_begin()
unsigned succ_size() const
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
pred_iterator pred_begin()
LLVM_ABI void ReplaceUsesOfBlockWith(MachineBasicBlock *Old, MachineBasicBlock *New)
Given a machine basic block that branched to 'Old', change the code and CFG so that it branches to 'N...
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
LLVM_ABI MachineBasicBlock * splitAt(MachineInstr &SplitInst, bool UpdateLiveIns=true, LiveIntervals *LIS=nullptr)
Split a basic block into 2 pieces at SplitPoint.
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
iterator_range< iterator > terminators()
LLVM_ABI DebugLoc findBranchDebugLoc()
Find and return the merged DebugLoc of the branch instructions of the block.
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
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.
BasicBlockListType::iterator iterator
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
MachineOperand class - Representation of each machine instruction operand.
void setIsDead(bool Val=true)
Register getReg() const
getReg - Returns the register number.
MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
static bool isVALU(const MachineInstr &MI)
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition SILowerControlFlow.cpp:863
A vector that has set insertion semantics.
size_type count(const_arg_type key) const
Count the number of elements of a given key in the SetVector.
void clear()
Completely clear the SetVector.
bool insert(const value_type &X)
Insert a new element into the SetVector.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void append(ItTy in_start, ItTy in_end)
Add the specified range to the end of the SmallVector.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
const TargetRegisterInfo & getRegisterInfo() const
CodeGenOptLevel getOptLevel() const
Returns the optimization level: None, Less, Default, or Aggressive.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
self_iterator getIterator()
@ Kill
The last use of a register.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
NodeAddr< DefNode * > Def
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
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
DominatorTreeBase< T, false > DomTreeBase
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
char & SILowerControlFlowLegacyID
Definition SILowerControlFlow.cpp:181
@ Or
Bitwise or logical OR of integers.
@ Xor
Bitwise or logical XOR of integers.
@ And
Bitwise or logical AND of integers.
FunctionAddr VTableAddr Next
DWARFExpression::Operation Op
std::vector< MachineInstr * > Kills
Kills - List of MachineInstruction's which are the last use of this virtual register (kill it) in the...