LLVM: lib/Target/AMDGPU/SILowerI1Copies.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
28
29#define DEBUG_TYPE "si-i1-copies"
30
31using namespace llvm;
32
36
37namespace {
38
40public:
43
44private:
46
47public:
48 void markAsLaneMask(Register DstReg) const override;
49 void getCandidatesForLowering(
51 void collectIncomingValuesFromPhi(
60 void constrainAsLaneMask(Incoming &In) override;
61
62 bool lowerCopiesFromI1();
63 bool lowerCopiesToI1();
64 bool cleanConstrainRegs(bool Changed);
66 return Reg.isVirtual() && MRI->getRegClass(Reg) == &AMDGPU::VReg_1RegClass;
67 }
68};
69
70Vreg1LoweringHelper::Vreg1LoweringHelper(MachineFunction *MF,
74
75bool Vreg1LoweringHelper::cleanConstrainRegs(bool Changed) {
79 ConstrainRegs.clear();
80
82}
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106class PhiIncomingAnalysis {
107 MachinePostDominatorTree &PDT;
108 const SIInstrInfo *TII;
109
110
111
112 MapVector<MachineBasicBlock *, bool> ReachableMap;
113 SmallVector<MachineBasicBlock *, 4> Stack;
114 SmallVector<MachineBasicBlock *, 4> Predecessors;
115
116public:
117 PhiIncomingAnalysis(MachinePostDominatorTree &PDT, const SIInstrInfo *TII)
119
120
121
122 bool isSource(MachineBasicBlock &MBB) const {
123 return ReachableMap.find(&MBB)->second;
124 }
125
127
128 void analyze(MachineBasicBlock &DefBlock, ArrayRef Incomings) {
130 ReachableMap.clear();
131 Predecessors.clear();
132
133
134
135 ReachableMap.try_emplace(&DefBlock, false);
136
137 for (auto Incoming : Incomings) {
138 MachineBasicBlock *MBB = Incoming.Block;
139 if (MBB == &DefBlock) {
140 ReachableMap[&DefBlock] = true;
141 continue;
142 }
143
145
146
147
150 }
151
152 while (.empty()) {
153 MachineBasicBlock *MBB = Stack.pop_back_val();
156 }
157
158 for (auto &[MBB, Reachable] : ReachableMap) {
159 bool HaveReachablePred = false;
161 if (ReachableMap.count(Pred)) {
162 HaveReachablePred = true;
163 } else {
164 Stack.push_back(Pred);
165 }
166 }
167 if (!HaveReachablePred)
168 Reachable = true;
169 if (HaveReachablePred) {
170 for (MachineBasicBlock *UnreachablePred : Stack) {
172 Predecessors.push_back(UnreachablePred);
173 }
174 }
176 }
177 }
178};
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212class LoopFinder {
213 MachineDominatorTree &DT;
214 MachinePostDominatorTree &PDT;
215
216
217
218
219 DenseMap<MachineBasicBlock *, unsigned> Visited;
220
221
222
223 SmallVector<MachineBasicBlock *, 4> CommonDominators;
224
225
226 MachineBasicBlock *VisitedPostDom = nullptr;
227
228
229
230
231 unsigned FoundLoopLevel = ~0u;
232
233 MachineBasicBlock *DefBlock = nullptr;
234 SmallVector<MachineBasicBlock *, 4> Stack;
235 SmallVector<MachineBasicBlock *, 4> NextLevel;
236
237public:
238 LoopFinder(MachineDominatorTree &DT, MachinePostDominatorTree &PDT)
239 : DT(DT), PDT(PDT) {}
240
243 CommonDominators.clear();
245 NextLevel.clear();
246 VisitedPostDom = nullptr;
247 FoundLoopLevel = ~0u;
248
249 DefBlock = &MBB;
250 }
251
252
253
254
255
256 unsigned findLoop(MachineBasicBlock *PostDom) {
258
259 if (!VisitedPostDom)
260 advanceLevel();
261
262 unsigned Level = 0;
263 while (PDNode->getBlock() != PostDom) {
264 if (PDNode->getBlock() == VisitedPostDom)
265 advanceLevel();
266 PDNode = PDNode->getIDom();
268 if (FoundLoopLevel == Level)
270 }
271
272 return 0;
273 }
274
275
276
277
278 void addLoopEntries(unsigned LoopLevel, MachineSSAUpdater &SSAUpdater,
279 MachineRegisterInfo &MRI,
280 MachineRegisterInfo::VRegAttrs LaneMaskRegAttrs,
282 assert(LoopLevel < CommonDominators.size());
283
284 MachineBasicBlock *Dom = CommonDominators[LoopLevel];
285 for (auto &Incoming : Incomings)
287
288 if (!inLoopLevel(*Dom, LoopLevel, Incomings)) {
291 } else {
292
293
294 for (MachineBasicBlock *Pred : Dom->predecessors()) {
295 if (!inLoopLevel(*Pred, LoopLevel, Incomings))
298 }
299 }
300 }
301
302private:
303 bool inLoopLevel(MachineBasicBlock &MBB, unsigned LoopLevel,
305 auto DomIt = Visited.find(&MBB);
306 if (DomIt != Visited.end() && DomIt->second <= LoopLevel)
307 return true;
308
309 for (auto &Incoming : Incomings)
310 if (Incoming.Block == &MBB)
311 return true;
312
313 return false;
314 }
315
316 void advanceLevel() {
317 MachineBasicBlock *VisitedDom;
318
319 if (!VisitedPostDom) {
320 VisitedPostDom = DefBlock;
321 VisitedDom = DefBlock;
322 Stack.push_back(DefBlock);
323 } else {
324 VisitedPostDom = PDT.getNode(VisitedPostDom)->getIDom()->getBlock();
325 VisitedDom = CommonDominators.back();
326
327 for (unsigned i = 0; i < NextLevel.size();) {
328 if (PDT.dominates(VisitedPostDom, NextLevel[i])) {
329 Stack.push_back(NextLevel[i]);
330
331 NextLevel[i] = NextLevel.back();
333 } else {
334 i++;
335 }
336 }
337 }
338
339 unsigned Level = CommonDominators.size();
340 while (.empty()) {
341 MachineBasicBlock *MBB = Stack.pop_back_val();
344
347
348 for (MachineBasicBlock *Succ : MBB->successors()) {
349 if (Succ == DefBlock) {
350 if (MBB == VisitedPostDom)
351 FoundLoopLevel = std::min(FoundLoopLevel, Level + 1);
352 else
353 FoundLoopLevel = std::min(FoundLoopLevel, Level);
354 continue;
355 }
356
357 if (Visited.try_emplace(Succ, ~0u).second) {
358 if (MBB == VisitedPostDom)
360 else
361 Stack.push_back(Succ);
362 }
363 }
364 }
365
366 CommonDominators.push_back(VisitedDom);
367 }
368};
369
370}
371
375 return MRI->createVirtualRegister(LaneMaskRegAttrs);
376}
377
385 BuildMI(*MBB, MBB->getFirstTerminator(), {}, TII->get(AMDGPU::IMPLICIT_DEF),
386 UndefReg);
387 return UndefReg;
388}
389
390#ifndef NDEBUG
395 return Size == 1 || Size == 32;
396}
397#endif
398
399bool Vreg1LoweringHelper::lowerCopiesFromI1() {
401 SmallVector<MachineInstr *, 4> DeadCopies;
402
403 for (MachineBasicBlock &MBB : *MF) {
404 for (MachineInstr &MI : MBB) {
405 if (MI.getOpcode() != AMDGPU::COPY)
406 continue;
407
408 Register DstReg = MI.getOperand(0).getReg();
409 Register SrcReg = MI.getOperand(1).getReg();
410 if (!isVreg1(SrcReg))
411 continue;
412
413 if (isLaneMaskReg(DstReg) || isVreg1(DstReg))
414 continue;
415
417
418
421
423 assert(.getOperand(0).getSubReg());
424
425 ConstrainRegs.insert(SrcReg);
426 BuildMI(MBB, MI, DL, TII->get(AMDGPU::V_CNDMASK_B32_e64), DstReg)
433 }
434
435 for (MachineInstr *MI : DeadCopies)
436 MI->eraseFromParent();
437 DeadCopies.clear();
438 }
440}
441
447
451
453 ExecReg = AMDGPU::EXEC_LO;
454 MovOp = AMDGPU::S_MOV_B32;
455 AndOp = AMDGPU::S_AND_B32;
456 OrOp = AMDGPU::S_OR_B32;
457 XorOp = AMDGPU::S_XOR_B32;
458 AndN2Op = AMDGPU::S_ANDN2_B32;
459 OrN2Op = AMDGPU::S_ORN2_B32;
460 } else {
462 MovOp = AMDGPU::S_MOV_B64;
463 AndOp = AMDGPU::S_AND_B64;
464 OrOp = AMDGPU::S_OR_B64;
465 XorOp = AMDGPU::S_XOR_B64;
466 AndN2Op = AMDGPU::S_ANDN2_B64;
467 OrN2Op = AMDGPU::S_ORN2_B64;
468 }
469}
470
474 PhiIncomingAnalysis PIA(*PDT, TII);
477
479 if (Vreg1Phis.empty())
480 return false;
481
482 DT->updateDFSNumbers();
486 if (&MBB != PrevMBB) {
487 LF.initialize(MBB);
488 PrevMBB = &MBB;
489 }
490
492
493 Register DstReg = MI->getOperand(0).getReg();
496
498
499
500
501
502
504 return DT->getNode(LHS.Block)->getDFSNumIn() <
505 DT->getNode(RHS.Block)->getDFSNumIn();
506 });
507
508#ifndef NDEBUG
510#endif
511
512
513
514 std::vector<MachineBasicBlock *> DomBlocks = {&MBB};
516 DomBlocks.push_back(Use.getParent());
517
519 PDT->findNearestCommonDominator(DomBlocks);
520
521
522
523
524
525 unsigned FoundLoopLevel = LF.findLoop(PostDomBound);
526
528
529 if (FoundLoopLevel) {
531 Incomings);
532
533 for (auto &Incoming : Incomings) {
536 }
537
538 for (auto &Incoming : Incomings) {
543 }
544 } else {
545
546
547 PIA.analyze(MBB, Incomings);
548
552
553 for (auto &Incoming : Incomings) {
555 if (PIA.isSource(IMBB)) {
558 } else {
561 }
562 }
563
564 for (auto &Incoming : Incomings) {
566 continue;
567
572 }
573 }
574
576 if (NewReg != DstReg) {
578 MI->eraseFromParent();
579 }
580
581 Incomings.clear();
582 }
583 return true;
584}
585
586bool Vreg1LoweringHelper::lowerCopiesToI1() {
589 LoopFinder LF(*DT, *PDT);
591
593 LF.initialize(MBB);
594
596 if (MI.getOpcode() != AMDGPU::IMPLICIT_DEF &&
597 MI.getOpcode() != AMDGPU::COPY)
598 continue;
599
600 Register DstReg = MI.getOperand(0).getReg();
601 if (!isVreg1(DstReg))
602 continue;
603
605
606 if (MRI->use_empty(DstReg)) {
608 continue;
609 }
610
612
613 markAsLaneMask(DstReg);
614 initializeLaneMaskRegisterAttributes(DstReg);
615
616 if (MI.getOpcode() == AMDGPU::IMPLICIT_DEF)
617 continue;
618
620 Register SrcReg = MI.getOperand(1).getReg();
621 assert(.getOperand(1).getSubReg());
622
623 if (!SrcReg.isVirtual() || (!isLaneMaskReg(SrcReg) && !isVreg1(SrcReg))) {
624 assert(TII->getRegisterInfo().getRegSizeInBits(SrcReg, *MRI) == 32);
629 MI.getOperand(1).setReg(TmpReg);
630 SrcReg = TmpReg;
631 } else {
632
633 MI.getOperand(1).setIsKill(false);
634 }
635
636
637
638 std::vector<MachineBasicBlock *> DomBlocks = {&MBB};
640 DomBlocks.push_back(Use.getParent());
641
644 unsigned FoundLoopLevel = LF.findLoop(PostDomBound);
645 if (FoundLoopLevel) {
648 LF.addLoopEntries(FoundLoopLevel, SSAUpdater, *MRI, LaneMaskRegAttrs);
649
650 buildMergeLaneMasks(MBB, MI, DL, DstReg,
653 }
654 }
655
657 MI->eraseFromParent();
658 DeadCopies.clear();
659 }
661}
662
665 for (;;) {
666 MI = MRI->getUniqueVRegDef(Reg);
667 if (MI->getOpcode() == AMDGPU::IMPLICIT_DEF)
668 return true;
669
670 if (MI->getOpcode() != AMDGPU::COPY)
671 break;
672
673 Reg = MI->getOperand(1).getReg();
674 if (!Reg.isVirtual())
675 return false;
677 return false;
678 }
679
680 if (MI->getOpcode() != MovOp)
681 return false;
682
683 if (->getOperand(1).isImm())
684 return false;
685
686 int64_t Imm = MI->getOperand(1).getImm();
687 if (Imm == 0) {
688 Val = false;
689 return true;
690 }
691 if (Imm == -1) {
692 Val = true;
693 return true;
694 }
695
696 return false;
697}
698
700 Def = false;
701 Use = false;
702
704 if (MO.isReg() && MO.getReg() == AMDGPU::SCC) {
705 if (MO.isUse())
706 Use = true;
707 else
708 Def = true;
709 }
710 }
711}
712
713
714
717 auto InsertionPt = MBB.getFirstTerminator();
718 bool TerminatorsUseSCC = false;
719 for (auto I = InsertionPt, E = MBB.end(); I != E; ++I) {
720 bool DefsSCC;
722 if (TerminatorsUseSCC || DefsSCC)
723 break;
724 }
725
726 if (!TerminatorsUseSCC)
727 return InsertionPt;
728
729 while (InsertionPt != MBB.begin()) {
730 InsertionPt--;
731
732 bool DefSCC, UseSCC;
734 if (DefSCC)
735 return InsertionPt;
736 }
737
738
739 llvm_unreachable("SCC used by terminator but no def in block");
740}
741
742
743void Vreg1LoweringHelper::markAsLaneMask(Register DstReg) const {
744 MRI->setRegClass(DstReg, ST->getBoolRC());
745}
746
747void Vreg1LoweringHelper::getCandidatesForLowering(
751 if (isVreg1(MI.getOperand(0).getReg()))
753 }
754 }
755}
756
757void Vreg1LoweringHelper::collectIncomingValuesFromPhi(
759 for (unsigned i = 1; i < MI->getNumOperands(); i += 2) {
760 assert(i + 1 < MI->getNumOperands());
761 Register IncomingReg = MI->getOperand(i).getReg();
763 MachineInstr *IncomingDef = MRI->getUniqueVRegDef(IncomingReg);
764
765 if (IncomingDef->getOpcode() == AMDGPU::COPY) {
767 assert(isLaneMaskReg(IncomingReg) || isVreg1(IncomingReg));
769 } else if (IncomingDef->getOpcode() == AMDGPU::IMPLICIT_DEF) {
770 continue;
771 } else {
772 assert(IncomingDef->isPHI() || PhiRegisters.count(IncomingReg));
773 }
774
776 }
777}
778
779void Vreg1LoweringHelper::replaceDstReg(Register NewReg, Register OldReg,
781 MRI->replaceRegWith(NewReg, OldReg);
782}
783
789 bool PrevVal = false;
790 bool PrevConstant = isConstantLaneMask(PrevReg, PrevVal);
791 bool CurVal = false;
792 bool CurConstant = isConstantLaneMask(CurReg, CurVal);
793
794 if (PrevConstant && CurConstant) {
795 if (PrevVal == CurVal) {
797 } else if (CurVal) {
799 } else {
803 }
804 return;
805 }
806
809 if (!PrevConstant) {
810 if (CurConstant && CurVal) {
811 PrevMaskedReg = PrevReg;
812 } else {
817 }
818 }
819 if (!CurConstant) {
820
821 if (PrevConstant && PrevVal) {
822 CurMaskedReg = CurReg;
823 } else {
828 }
829 }
830
831 if (PrevConstant && !PrevVal) {
833 .addReg(CurMaskedReg);
834 } else if (CurConstant && !CurVal) {
836 .addReg(PrevMaskedReg);
837 } else if (PrevConstant && PrevVal) {
839 .addReg(CurMaskedReg)
841 } else {
843 .addReg(PrevMaskedReg)
844 .addReg(CurMaskedReg ? CurMaskedReg : ExecReg);
845 }
846}
847
848void Vreg1LoweringHelper::constrainAsLaneMask(Incoming &In) {}
849
850
851
852
853
854
855
856
857
858
861
863 return false;
864
865 Vreg1LoweringHelper Helper(&MF, &MDT, &MPDT);
867 Changed |= Helper.lowerCopiesFromI1();
868 Changed |= Helper.lowerPhis();
869 Changed |= Helper.lowerCopiesToI1();
870 return Helper.cleanConstrainRegs(Changed);
871}
872
882
883
886 return PA;
887}
888
890public:
892
896
898
900
907};
908
916
918 false, false)
923
925
927
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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 void instrDefsUsesSCC(const MachineInstr &MI, bool &Def, bool &Use)
Definition SILowerI1Copies.cpp:699
static Register insertUndefLaneMask(MachineBasicBlock *MBB, MachineRegisterInfo *MRI, MachineRegisterInfo::VRegAttrs LaneMaskRegAttrs)
Definition SILowerI1Copies.cpp:379
static bool runFixI1Copies(MachineFunction &MF, MachineDominatorTree &MDT, MachinePostDominatorTree &MPDT)
Lower all instructions that def or use vreg_1 registers.
Definition SILowerI1Copies.cpp:859
static bool isVRegCompatibleReg(const SIRegisterInfo &TRI, const MachineRegisterInfo &MRI, Register Reg)
Definition SILowerI1Copies.cpp:391
Interface definition of the PhiLoweringHelper class that implements lane mask merging algorithm for d...
static void initialize(TargetLibraryInfoImpl &TLI, const Triple &T, const llvm::StringTable &StandardNames, VectorLibrary VecLib)
Initialize the set of available library functions based on the specified target triple.
static char ID
Definition SILowerI1Copies.cpp:891
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Definition SILowerI1Copies.cpp:901
SILowerI1CopiesLegacy()
Definition SILowerI1Copies.cpp:893
StringRef getPassName() const override
getPassName - Return a nice clean name for a pass.
Definition SILowerI1Copies.cpp:899
bool runOnMachineFunction(MachineFunction &MF) override
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
Definition SILowerI1Copies.cpp:909
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()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Represents analyses that only rely on functions' control flow.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Implements a dense probed hash-table based set.
DomTreeNodeBase * getIDom() const
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
Find nearest common dominator basic block for basic block A and B.
bool dominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
dominates - Returns true iff A dominates B.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
FunctionPass class - This class is used to implement most global optimizations.
const HexagonRegisterInfo & getRegisterInfo() const
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineFunctionPass(char &ID)
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.
const MachineFunctionProperties & getProperties() const
Get the function properties.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
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 MachineOperand & getOperand(unsigned i) const
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
Register getReg() const
getReg - Returns the register number.
MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...
LLVM_ABI MachineBasicBlock * findNearestCommonDominator(ArrayRef< MachineBasicBlock * > Blocks) const
Returns the nearest common dominator of the given blocks.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
MachineSSAUpdater - This class updates SSA form for a set of virtual registers defined in multiple bl...
void AddAvailableValue(MachineBasicBlock *BB, Register V)
AddAvailableValue - Indicate that a rewritten value is available at the end of the specified block wi...
iterator find(const KeyT &Key)
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&...Args)
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
AnalysisType & getAnalysis() const
getAnalysis() - This function is used by subclasses to get to the analysis information ...
bool lowerPhis()
Definition SILowerI1Copies.cpp:471
PhiLoweringHelper(MachineFunction *MF, MachineDominatorTree *DT, MachinePostDominatorTree *PDT)
Definition SILowerI1Copies.cpp:442
bool isLaneMaskReg(Register Reg) const
MachineRegisterInfo * MRI
MachineDominatorTree * DT
DenseSet< Register > PhiRegisters
virtual void getCandidatesForLowering(SmallVectorImpl< MachineInstr * > &Vreg1Phis) const =0
virtual void constrainAsLaneMask(Incoming &In)=0
virtual void collectIncomingValuesFromPhi(const MachineInstr *MI, SmallVectorImpl< Incoming > &Incomings) const =0
virtual void markAsLaneMask(Register DstReg) const =0
MachinePostDominatorTree * PDT
MachineRegisterInfo::VRegAttrs LaneMaskRegAttrs
MachineBasicBlock::iterator getSaluInsertionAtEnd(MachineBasicBlock &MBB) const
Return a point at the end of the given MBB to insert SALU instructions for lane mask calculation.
Definition SILowerI1Copies.cpp:716
void initializeLaneMaskRegisterAttributes(Register LaneMask)
bool isConstantLaneMask(Register Reg, bool &Val) const
Definition SILowerI1Copies.cpp:663
virtual void buildMergeLaneMasks(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DstReg, Register PrevReg, Register CurReg)=0
virtual void replaceDstReg(Register NewReg, Register OldReg, MachineBasicBlock *MBB)=0
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.
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Wrapper class representing virtual and physical registers.
constexpr bool isValid() const
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition SILowerI1Copies.cpp:874
Helper class for SSA formation on a set of values defined in multiple blocks.
void Initialize(Type *Ty, StringRef Name)
Reset this object to get ready for a new set of SSA updates with type 'Ty'.
Value * GetValueInMiddleOfBlock(BasicBlock *BB)
Construct SSA form, materializing a value that is live in the middle of the specified block.
void AddAvailableValue(BasicBlock *BB, Value *V)
Indicate that a rewritten value is available in the specified block with the specified value.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
reference emplace_back(ArgTypes &&... Args)
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.
A Use represents the edge between a Value definition and its users.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
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.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Register createLaneMaskReg(MachineRegisterInfo *MRI, MachineRegisterInfo::VRegAttrs LaneMaskRegAttrs)
Definition SILowerI1Copies.cpp:373
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
void initializeSILowerI1CopiesLegacyPass(PassRegistry &)
ArrayRef(const T &OneElt) -> ArrayRef< T >
FunctionPass * createSILowerI1CopiesLegacyPass()
Definition SILowerI1Copies.cpp:928
char & SILowerI1CopiesLegacyID
Definition SILowerI1Copies.cpp:926
auto predecessors(const MachineBasicBlock *BB)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Incoming for lane maks phi as machine instruction, incoming register Reg and incoming block Block are...
MachineBasicBlock * Block
All attributes(register class or bank and low-level type) a virtual register can have.