LLVM: lib/Target/ARM/MVETPAndVPTOptimisationsPass.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
31#include
32
33using namespace llvm;
34
35#define DEBUG_TYPE "arm-mve-vpt-opts"
36
39 cl::desc("Enable merging Loop End and Dec instructions."),
41
44 cl::desc("Enable setting lr as a predicate in tail predication regions."),
46
47namespace {
49public:
50 static char ID;
53
55
57
64 }
65
67 return "ARM MVE TailPred and VPT Optimisation Pass";
68 }
69
70private:
85};
86
87char MVETPAndVPTOptimisations::ID = 0;
88
89}
90
92 "ARM MVE TailPred and VPT Optimisations pass", false,
93 false)
98
101 while (MI && MI->getOpcode() == TargetOpcode::COPY &&
102 MI->getOperand(1).getReg().isVirtual())
103 MI = MRI->getVRegDef(MI->getOperand(1).getReg());
104 return MI;
105}
106
107
108
109
115 if (!Header || !Latch) {
117 return false;
118 }
119
120
121 LoopEnd = nullptr;
123 if (T.getOpcode() == ARM::t2LoopEnd && T.getOperand(1).getMBB() == Header) {
124 LoopEnd = &T;
125 break;
126 }
127 if (T.getOpcode() == ARM::t2LoopEndDec &&
128 T.getOperand(2).getMBB() == Header) {
129 LoopEnd = &T;
130 break;
131 }
132 }
133 if (!LoopEnd) {
135 return false;
136 }
137 LLVM_DEBUG(dbgs() << " found loop end: " << *LoopEnd);
138
139
140
141
142
143
144
145
146
147
148 if (LoopEnd->getOpcode() == ARM::t2LoopEndDec)
149 LoopDec = LoopEnd;
150 else {
151 LoopDec =
153 if (!LoopDec || LoopDec->getOpcode() != ARM::t2LoopDec) {
154 LLVM_DEBUG(dbgs() << " didn't find LoopDec where we expected!\n");
155 return false;
156 }
157 }
158 LLVM_DEBUG(dbgs() << " found loop dec: " << *LoopDec);
159
160 LoopPhi =
162 if (!LoopPhi || LoopPhi->getOpcode() != TargetOpcode::PHI ||
166 LLVM_DEBUG(dbgs() << " didn't find PHI where we expected!\n");
167 return false;
168 }
169 LLVM_DEBUG(dbgs() << " found loop phi: " << *LoopPhi);
170
175 if (!LoopStart || (LoopStart->getOpcode() != ARM::t2DoLoopStart &&
176 LoopStart->getOpcode() != ARM::t2WhileLoopSetup &&
177 LoopStart->getOpcode() != ARM::t2WhileLoopStartLR)) {
178 LLVM_DEBUG(dbgs() << " didn't find Start where we expected!\n");
179 return false;
180 }
181 LLVM_DEBUG(dbgs() << " found loop start: " << *LoopStart);
182
183 return true;
184}
185
188 assert(MI->getOpcode() == ARM::t2WhileLoopSetup &&
189 "Only expected a t2WhileLoopSetup in RevertWhileLoopStart!");
190
191
194 MIB.add(MI->getOperand(0));
195 MIB.add(MI->getOperand(1));
198 MIB.addReg(ARM::NoRegister);
200
201
203 if (I.getOpcode() == ARM::t2WhileLoopStart) {
205 BuildMI(*MBB, &I, I.getDebugLoc(), TII->get(ARM::t2Bcc));
206 MIB.add(MI->getOperand(1));
208 MIB.addReg(ARM::CPSR);
209 I.eraseFromParent();
210 break;
211 }
212 }
213
214 MI->eraseFromParent();
215}
216
217
218
219
220
221
222
223
224
225
226
227bool MVETPAndVPTOptimisations::LowerWhileLoopStart(MachineLoop *ML) {
229 << ML->getHeader()->getName() << "\n");
230
231 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
233 return false;
234
235 if (LoopStart->getOpcode() != ARM::t2WhileLoopSetup)
236 return false;
237
239 auto WLSIt = find_if(MRI->use_nodbg_instructions(LR), [](auto &MI) {
240 return MI.getOpcode() == ARM::t2WhileLoopStart;
241 });
242 if ( || WLSIt == MRI->use_instr_nodbg_end()) {
246 return true;
247 }
248
250 BuildMI(*WLSIt->getParent(), *WLSIt, WLSIt->getDebugLoc(),
251 TII->get(ARM::t2WhileLoopStartLR), LR)
253 .add(WLSIt->getOperand(1));
254 (void)MI;
255 LLVM_DEBUG(dbgs() << "Lowered WhileLoopStart into: " << *MI.getInstr());
256
257 WLSIt->eraseFromParent();
259 return true;
260}
261
262
263
266}
267
268
269
270
271
272MachineInstr *MVETPAndVPTOptimisations::CheckForLRUseInPredecessors(
278
279 while (!Worklist.empty()) {
282 continue;
283
286 continue;
287
288 LLVM_DEBUG(dbgs() << "Found LR use in predecessors, reverting: " << MI);
289
290
293 LoopStart->getDebugLoc(), TII->get(ARM::t2DoLoopStart));
296
297
299
300
302 return MIB;
303 }
304
308 }
309 return LoopStart;
310}
311
312
313
314
315
316
317
318
319bool MVETPAndVPTOptimisations::MergeLoopEnd(MachineLoop *ML) {
321 return false;
322
323 LLVM_DEBUG(dbgs() << "MergeLoopEnd on loop " << ML->getHeader()->getName()
324 << "\n");
325
326 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
328 return false;
329
330
331
332
333 auto *PreHeader = ML->getLoopPreheader();
334 if (LoopStart->getOpcode() == ARM::t2WhileLoopStartLR && PreHeader)
335 LoopStart = CheckForLRUseInPredecessors(PreHeader, LoopStart);
336
340 LLVM_DEBUG(dbgs() << "Found LR use in loop, reverting: " << MI);
341 if (LoopStart->getOpcode() == ARM::t2DoLoopStart)
343 else
347 return true;
348 }
349 }
350 }
351
352
353
354
358
365 while (!Worklist.empty()) {
369 continue;
370 if (MI.getOpcode() != TargetOpcode::COPY ||
371 .getOperand(0).getReg().isVirtual()) {
372 LLVM_DEBUG(dbgs() << "Extra users of register found: " << MI);
373 return false;
374 }
375 Worklist.push_back(MI.getOperand(0).getReg());
377 }
378 }
379 return true;
380 };
381 if (!CheckUsers(PhiReg, {LoopDec}, MRI) ||
382 !CheckUsers(DecReg, {LoopPhi, LoopEnd}, MRI) ||
383 !CheckUsers(StartReg, {LoopPhi}, MRI)) {
384
385 if (LoopStart->getOpcode() == ARM::t2WhileLoopStartLR) {
389 return true;
390 }
391 return false;
392 }
393
394 MRI->constrainRegClass(StartReg, &ARM::GPRlrRegClass);
395 MRI->constrainRegClass(PhiReg, &ARM::GPRlrRegClass);
396 MRI->constrainRegClass(DecReg, &ARM::GPRlrRegClass);
397
401 } else {
404 }
405
409
410
415 }
416
417
420 TII->get(ARM::t2LoopEndDec), DecReg)
423 (void)MI;
424 LLVM_DEBUG(dbgs() << "Merged LoopDec and End into: " << *MI.getInstr());
425
429 MI->eraseFromParent();
430 return true;
431}
432
433
434
435
436
437bool MVETPAndVPTOptimisations::ConvertTailPredLoop(MachineLoop *ML,
440 << ML->getHeader()->getName() << "\n");
441
442
443
444 MachineInstr *LoopEnd, *LoopPhi, *LoopStart, *LoopDec;
446 return false;
447 if (LoopDec != LoopEnd || (LoopStart->getOpcode() != ARM::t2DoLoopStart &&
448 LoopStart->getOpcode() != ARM::t2WhileLoopStartLR))
449 return false;
450
459 }
460
461 if (VCTPs.empty()) {
463 return false;
464 }
465
466
470 if (VCTP->getOpcode() != FirstVCTP->getOpcode() ||
471 VCTP->getOperand(0).getReg() != FirstVCTP->getOperand(0).getReg()) {
473 return false;
474 }
475 }
476
477
478
479
480
481
482
483
484
485
486
489 LLVM_DEBUG(dbgs() << " cannot determine VCTP PHI\n");
490 return false;
491 }
493 if (!Phi || Phi->getOpcode() != TargetOpcode::PHI ||
494 Phi->getNumOperands() != 5 ||
495 (Phi->getOperand(2).getMBB() != ML->getLoopLatch() &&
496 Phi->getOperand(4).getMBB() != ML->getLoopLatch())) {
497 LLVM_DEBUG(dbgs() << " cannot determine VCTP Count\n");
498 return false;
499 }
500 CountReg = Phi->getOperand(2).getMBB() == ML->getLoopLatch()
501 ? Phi->getOperand(3).getReg()
502 : Phi->getOperand(1).getReg();
503
504
505
506
513 LLVM_DEBUG(dbgs() << " InsertPt could not be a terminator!\n");
514 return false;
515 }
516
517 unsigned NewOpc = LoopStart->getOpcode() == ARM::t2DoLoopStart
518 ? ARM::t2DoLoopStartTP
519 : ARM::t2WhileLoopStartTP;
525 if (NewOpc == ARM::t2WhileLoopStartTP)
527 LLVM_DEBUG(dbgs() << "Replacing " << *LoopStart << " with "
528 << *MI.getInstr());
529 MRI->constrainRegClass(CountReg, &ARM::rGPRRegClass);
531
533
534
538 MI->getOperand(Idx + 2).setReg(LR);
539 }
540 }
541
542 return true;
543}
544
545
547
548
549
550
552 switch (Opcode) {
553 default:
554 return true;
555 case ARM::MVE_VCMPf32:
556 case ARM::MVE_VCMPf16:
557 case ARM::MVE_VCMPf32r:
558 case ARM::MVE_VCMPf16r:
559 case ARM::MVE_VCMPi8r:
560 case ARM::MVE_VCMPi16r:
561 case ARM::MVE_VCMPi32r:
562 case ARM::MVE_VCMPu8r:
563 case ARM::MVE_VCMPu16r:
564 case ARM::MVE_VCMPu32r:
565 case ARM::MVE_VCMPs8r:
566 case ARM::MVE_VCMPs16r:
567 case ARM::MVE_VCMPs32r:
568 return false;
569 }
570}
571
572
574 assert(IsVCMP(Instr.getOpcode()) && "Inst must be a VCMP");
576}
577
578
579
582
583
585 return false;
586
589
590
591
595 if (CondOP1.isIdenticalTo(PrevOP1) && CondOP2.isIdenticalTo(PrevOP2))
596 return true;
597
599 return false;
602 CondOP2.isIdenticalTo(PrevOP1);
603}
604
605
607 if (Instr.getNumOperands() == 0)
608 return false;
610 if (!Dst.isReg())
611 return false;
612 Register DstReg = Dst.getReg();
614 return false;
617 return RegClass && (RegClass->getID() == ARM::VCCRRegClassID);
618}
619
620
621
622
623
624
625
626
627
628MachineInstr &MVETPAndVPTOptimisations::ReplaceRegisterUseWithVPNOT(
632
638
639
640 User.setReg(NewResult);
641 User.setIsKill(false);
642
643 LLVM_DEBUG(dbgs() << " Inserting VPNOT (for spill prevention): ";
645
646 return *MIBuilder.getInstr();
647}
648
649
650
651
655 assert(Iter->getOpcode() == ARM::MVE_VPNOT && "Not a VPNOT!");
657 "The VPNOT cannot be predicated");
658
662
663
664
665 bool MustMove = false, HasUser = false;
667 for (; Iter != MBB.end(); ++Iter) {
669 Iter->findRegisterUseOperand(VPNOTOperand, nullptr,
670 true)) {
671
672 VPNOTOperandKiller = MO;
673 }
674
675 if (Iter->findRegisterUseOperandIdx(Reg, nullptr) != -1) {
676 MustMove = true;
677 continue;
678 }
679
680 if (Iter->findRegisterUseOperandIdx(VPNOTResult, nullptr) == -1)
681 continue;
682
683 HasUser = true;
684 if (!MustMove)
685 break;
686
687
689 Iter->dump());
691
692
693 if (VPNOTOperandKiller)
694 VPNOTOperandKiller->setIsKill(false);
695
696 break;
697 }
698 return HasUser;
699}
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714bool MVETPAndVPTOptimisations::ReduceOldVCCRValueUses(MachineBasicBlock &MBB) {
718
719 while (Iter != End) {
720 Register VCCRValue, OppositeVCCRValue;
721
722
723
724 for (; Iter != End; ++Iter) {
725
728 continue;
729 Register Dst = Iter->getOperand(0).getReg();
730
731
732
733 if (VCCRValue && Iter->getOpcode() == ARM::MVE_VPNOT &&
734 Iter->findRegisterUseOperandIdx(VCCRValue, nullptr) != -1) {
735
736
738 continue;
739
740 OppositeVCCRValue = Dst;
741 ++Iter;
742 break;
743 }
744
745
746 VCCRValue = Dst;
747 }
748
749
750 if (Iter == End)
751 break;
752
753 assert(VCCRValue && OppositeVCCRValue &&
754 "VCCRValue and OppositeVCCRValue shouldn't be empty if the loop "
755 "stopped before the end of the block!");
756 assert(VCCRValue != OppositeVCCRValue &&
757 "VCCRValue should not be equal to OppositeVCCRValue!");
758
759
760 Register LastVPNOTResult = OppositeVCCRValue;
761
762
763 for (; Iter != End; ++Iter) {
764 bool IsInteresting = false;
765
767 Iter->findRegisterUseOperand(VCCRValue, nullptr)) {
768 IsInteresting = true;
769
770
771
772
773 if (Iter->getOpcode() == ARM::MVE_VPNOT) {
775
776 MRI->replaceRegWith(Result, LastVPNOTResult);
777 DeadInstructions.push_back(&*Iter);
779
781 << "Replacing all uses of '" << printReg(Result)
782 << "' with '" << printReg(LastVPNOTResult) << "'\n");
783 } else {
785 ReplaceRegisterUseWithVPNOT(MBB, *Iter, *MO, LastVPNOTResult);
787
789 std::swap(VCCRValue, OppositeVCCRValue);
790
792 << "' with '" << printReg(LastVPNOTResult)
793 << "' in instr: " << *Iter);
794 }
795 } else {
796
797
798 if (MachineOperand *MO = Iter->findRegisterUseOperand(
799 OppositeVCCRValue, nullptr)) {
800 IsInteresting = true;
801
802
803 if (LastVPNOTResult != OppositeVCCRValue) {
805 << printReg(OppositeVCCRValue) << "' with '"
806 << printReg(LastVPNOTResult) << " for instr: ";
807 Iter->dump());
808 MO->setReg(LastVPNOTResult);
810 }
811
812 MO->setIsKill(false);
813 }
814
815
816
817 if (Iter->getOpcode() == ARM::MVE_VPNOT &&
819 Register VPNOTOperand = Iter->getOperand(1).getReg();
820 if (VPNOTOperand == LastVPNOTResult ||
821 VPNOTOperand == OppositeVCCRValue) {
822 IsInteresting = true;
823
824 std::swap(VCCRValue, OppositeVCCRValue);
825 LastVPNOTResult = Iter->getOperand(0).getReg();
826 }
827 }
828 }
829
830
832 break;
833 }
834 }
835
836 for (MachineInstr *DeadInstruction : DeadInstructions)
837 DeadInstruction->eraseFromParent();
838
840}
841
842
845
846
847
848
849
850
852
853
854
856
858 if (PrevVCMP) {
861 nullptr, true)) {
862
863
864 PrevVCMPResultKiller = MO;
865 }
866 }
867
868
870 continue;
871
872
874
876 PrevVCMP = nullptr;
877 continue;
878 }
879
881 PrevVCMP = &Instr;
882 continue;
883 }
884
885
886
888
889
893 .addReg(PrevVCMPResultReg);
895 LLVM_DEBUG(dbgs() << "Inserting VPNOT (to replace VCMP): ";
898
899
900
901 if (PrevVCMPResultKiller)
902 PrevVCMPResultKiller->setIsKill(false);
903
904
905
906 DeadInstructions.push_back(&Instr);
907 PrevVCMP = nullptr;
908 PrevVCMPResultKiller = nullptr;
909 }
910
911 for (MachineInstr *DeadInstruction : DeadInstructions)
912 DeadInstruction->eraseFromParent();
913
914 return !DeadInstructions.empty();
915}
916
919
920
921
922
923
924 unsigned LastVPTImm = 0;
927
929
931 if (PIdx == -1)
932 continue;
933 Register VPR = Instr.getOperand(PIdx + 1).getReg();
935 continue;
936
937
939 if (!Copy || Copy->getOpcode() != TargetOpcode::COPY ||
940 ->getOperand(1).getReg().isVirtual() ||
941 MRI->getRegClass(Copy->getOperand(1).getReg()) == &ARM::VCCRRegClass) {
942 LastVPTReg = 0;
943 continue;
944 }
946
947
948 auto getImm = [&](Register GPR) -> unsigned {
950 if (Def && (Def->getOpcode() == ARM::t2MOVi ||
951 Def->getOpcode() == ARM::t2MOVi16))
952 return Def->getOperand(1).getImm();
953 return -1U;
954 };
955 unsigned Imm = getImm(GPR);
956 if (Imm == -1U) {
957 LastVPTReg = 0;
958 continue;
959 }
960
961 unsigned NotImm = ~Imm & 0xffff;
962 if (LastVPTReg != 0 && LastVPTReg != VPR && LastVPTImm == Imm) {
963 MRI->clearKillFlags(LastVPTReg);
964 Instr.getOperand(PIdx + 1).setReg(LastVPTReg);
965 if (MRI->use_empty(VPR)) {
966 DeadInstructions.insert(Copy);
967 if (MRI->hasOneUse(GPR))
968 DeadInstructions.insert(MRI->getVRegDef(GPR));
969 }
970 LLVM_DEBUG(dbgs() << "Reusing predicate: in " << Instr);
971 VPR = LastVPTReg;
972 } else if (LastVPTReg != 0 && LastVPTImm == NotImm) {
973
974
975 Register NewVPR = MRI->createVirtualRegister(&ARM::VCCRRegClass);
977 TII->get(ARM::MVE_VPNOT), NewVPR)
980
981
982 Instr.getOperand(PIdx + 1).setReg(NewVPR);
983 if (MRI->use_empty(VPR)) {
984 DeadInstructions.insert(Copy);
985 if (MRI->hasOneUse(GPR))
986 DeadInstructions.insert(MRI->getVRegDef(GPR));
987 }
988 LLVM_DEBUG(dbgs() << "Adding VPNot: " << *VPNot << " to replace use at "
989 << Instr);
990 VPR = NewVPR;
991 }
992
993 LastVPTImm = Imm;
994 LastVPTReg = VPR;
995 }
996
998 DI->eraseFromParent();
999
1000 return !DeadInstructions.empty();
1001}
1002
1003
1004
1005
1006
1007
1009 bool HasVCTP = false;
1011
1014 HasVCTP = true;
1015 continue;
1016 }
1017
1018 if (!HasVCTP || MI.getOpcode() != ARM::MVE_VPSEL)
1019 continue;
1020
1030
1031 (void)MIBuilder;
1035 }
1036
1037 for (MachineInstr *DeadInstruction : DeadInstructions)
1038 DeadInstruction->eraseFromParent();
1039
1040 return !DeadInstructions.empty();
1041}
1042
1043
1044
1046 bool Changed = false;
1048 if (MI.getOpcode() != ARM::t2DoLoopStart)
1049 continue;
1053 Changed = true;
1054 }
1055 return Changed;
1056}
1057
1058bool MVETPAndVPTOptimisations::runOnMachineFunction(MachineFunction &Fn) {
1060
1061 if (!STI.isThumb2() || !STI.hasLOB())
1062 return false;
1063
1066 MachineLoopInfo *MLI = &getAnalysis().getLI();
1068 &getAnalysis().getDomTree();
1069
1070 LLVM_DEBUG(dbgs() << "********** ARM MVE VPT Optimisations **********\n"
1071 << "********** Function: " << Fn.getName() << '\n');
1072
1075 Modified |= LowerWhileLoopStart(ML);
1077 Modified |= ConvertTailPredLoop(ML, DT);
1078 }
1079
1082 Modified |= ReplaceConstByVPNOTs(MBB, DT);
1084 Modified |= ReduceOldVCCRValueUses(MBB);
1086 }
1087
1088 LLVM_DEBUG(dbgs() << "**************************************\n");
1090}
1091
1092
1094 return new MVETPAndVPTOptimisations();
1095}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
const HexagonInstrInfo * TII
ARM MVE TailPred and VPT Optimisations static false MachineInstr * LookThroughCOPY(MachineInstr *MI, MachineRegisterInfo *MRI)
static void RevertWhileLoopSetup(MachineInstr *MI, const TargetInstrInfo *TII)
static cl::opt< bool > SetLRPredicate("arm-set-lr-predicate", cl::Hidden, cl::desc("Enable setting lr as a predicate in tail predication regions."), cl::init(true))
static bool findLoopComponents(MachineLoop *ML, MachineRegisterInfo *MRI, MachineInstr *&LoopStart, MachineInstr *&LoopPhi, MachineInstr *&LoopDec, MachineInstr *&LoopEnd)
static bool MoveVPNOTBeforeFirstUser(MachineBasicBlock &MBB, MachineBasicBlock::iterator Iter, Register Reg)
static cl::opt< bool > MergeEndDec("arm-enable-merge-loopenddec", cl::Hidden, cl::desc("Enable merging Loop End and Dec instructions."), cl::init(true))
static ARMCC::CondCodes GetCondCode(MachineInstr &Instr)
static bool IsVPNOTEquivalent(MachineInstr &Cond, MachineInstr &Prev)
static bool IsInvalidTPInstruction(MachineInstr &MI)
static bool IsVCMP(unsigned Opcode)
ARM MVE TailPred and VPT Optimisations pass
static bool IsWritingToVCCR(MachineInstr &Instr)
static bool CanHaveSwappedOperands(unsigned Opcode)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
const ARMBaseInstrInfo * getInstrInfo() const override
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
FunctionPass class - This class is used to implement most global optimizations.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
SmallVector< LoopT *, 4 > getLoopsInPreorder() const
Return all of the loops in the function in preorder across the loop nests, with siblings in forward p...
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
iterator_range< iterator > terminators()
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
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
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
const MachineInstrBuilder & addDef(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register definition operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
unsigned getNumOperands() const
Retuns the total number of operands.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
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.
MachineBasicBlock * getMBB() const
void setReg(Register Reg)
Change the register this operand corresponds to.
void setIsKill(bool Val=true)
Register getReg() const
getReg - Returns the register number.
bool isIdenticalTo(const MachineOperand &Other) const
Returns true if this operand is identical to the specified operand except for liveness related flags ...
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
void setRegAllocationHint(Register VReg, unsigned Type, Register PrefReg)
setRegAllocationHint - Specify a register allocation hint for the specified virtual register.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
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.
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.
TargetInstrInfo - Interface to description of machine instruction set.
unsigned getID() const
Return the register class ID number.
Target - Wrapper for Target specific information.
A Use represents the edge between a Value definition and its users.
self_iterator getIterator()
static CondCodes getOppositeCondition(CondCodes CC)
static ARMCC::CondCodes getSwappedCondition(ARMCC::CondCodes CC)
getSwappedCondition - assume the flags are set by MI(a,b), return the condition code if we modify the...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
NodeAddr< InstrNode * > Instr
NodeAddr< PhiNode * > Phi
NodeAddr< DefNode * > Def
This is an optimization pass for GlobalISel generic memory operations.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
int findFirstVPTPredOperandIdx(const MachineInstr &MI)
FunctionPass * createMVETPAndVPTOptimisationsPass()
createMVETPAndVPTOptimisationsPass
ARMVCC::VPTCodes getVPTInstrPredicate(const MachineInstr &MI, Register &PredReg)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isVCTP(const MachineInstr *MI)
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static bool isLoopStart(const MachineInstr &MI)
void RevertWhileLoopStartLR(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool UseCmp=false)
void RevertLoopEnd(MachineInstr *MI, const TargetInstrInfo *TII, unsigned BrOpc=ARM::t2Bcc, bool SkipCmp=false)
void RevertLoopDec(MachineInstr *MI, const TargetInstrInfo *TII, bool SetFlags=false)
auto find_if(R &&Range, UnaryPredicate P)
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly.
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
static unsigned VCMPOpcodeToVPT(unsigned Opcode)
void RevertDoLoopStart(MachineInstr *MI, const TargetInstrInfo *TII)
void addUnpredicatedMveVpredNOp(MachineInstrBuilder &MIB)
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.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.