LLVM: lib/Target/AArch64/AArch64MIPeepholeOpt.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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
77
78using namespace llvm;
79
80#define DEBUG_TYPE "aarch64-mi-peephole-opt"
81
82namespace {
83
85 static char ID;
86
88
93
94 using OpcodePair = std::pair<unsigned, unsigned>;
95 template
96 using SplitAndOpcFunc =
97 std::function<std::optional(T, unsigned, T &, T &)>;
98 using BuildMIFunc =
99 std::function<void(MachineInstr &, OpcodePair, unsigned, unsigned,
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 template
118 SplitAndOpcFunc SplitAndOpc, BuildMIFunc BuildInstr);
119
122
123 template
124 bool visitADDSUB(unsigned PosOpc, unsigned NegOpc, MachineInstr &MI);
125 template
126 bool visitADDSSUBS(OpcodePair PosOpcs, OpcodePair NegOpcs, MachineInstr &MI);
127
128
129 enum class SplitStrategy {
130 Intersect,
131 Disjoint,
132 };
133 template
135 SplitStrategy Strategy, unsigned OtherOpc = 0);
145
146 StringRef getPassName() const override {
147 return "AArch64 MI Peephole Optimization pass";
148 }
149
150 void getAnalysisUsage(AnalysisUsage &AU) const override {
154 }
155};
156
157char AArch64MIPeepholeOpt::ID = 0;
158
159}
160
162 "AArch64 MI Peephole Optimization", false, false)
163
164template <typename T>
166 T UImm = static_cast<T>(Imm);
167 assert(UImm && (UImm != ~static_cast<T>(0)) && "Invalid immediate!");
168
169
170
171
172
173
176
177
178
181
182
184
185
186
188 return false;
189
192 return true;
193}
194
195template
198 assert(Imm && (Imm != ~static_cast<T>(0)) && "Invalid immediate!");
199
200
201
202
203
205 unsigned LowestGapBitUnset =
207
208
209 assert(LowestGapBitUnset < sizeof(T) * CHAR_BIT && "Undefined behaviour!");
210 T NewImm1 = (static_cast<T>(1) << LowestGapBitUnset) -
212
214
215
217 return false;
218
221 return true;
222}
223
224template
225bool AArch64MIPeepholeOpt::trySplitLogicalImm(unsigned Opc, MachineInstr &MI,
226 SplitStrategy Strategy,
227 unsigned OtherOpc) {
228
229
230
231
232
233
234
235
236
237
238 return splitTwoPartImm(
240 [Opc, Strategy, OtherOpc](T Imm, unsigned RegSize, T &Imm0,
241 T &Imm1) -> std::optional {
242
243
245 return std::nullopt;
246
247
250 if (Insn.size() == 1)
251 return std::nullopt;
252
253 bool SplitSucc = false;
254 switch (Strategy) {
255 case SplitStrategy::Intersect:
256 SplitSucc = splitBitmaskImm(Imm, RegSize, Imm0, Imm1);
257 break;
258 case SplitStrategy::Disjoint:
260 break;
261 }
262 if (SplitSucc)
263 return std::make_pair(Opc, !OtherOpc ? Opc : OtherOpc);
264 return std::nullopt;
265 },
266 [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,
270 MachineBasicBlock *MBB = MI.getParent();
277 });
278}
279
280bool AArch64MIPeepholeOpt::visitORR(MachineInstr &MI) {
281
282
283
284
285 if (MI.getOperand(3).getImm() != 0)
286 return false;
287
288 if (MI.getOperand(1).getReg() != AArch64::WZR)
289 return false;
290
291 MachineInstr *SrcMI = MRI->getUniqueVRegDef(MI.getOperand(2).getReg());
292 if (!SrcMI)
293 return false;
294
295
296
297
298
299
300
301
302
303
304
305 if (SrcMI->getOpcode() == TargetOpcode::COPY &&
307 const TargetRegisterClass *RC =
309
310
311
312 if (RC != &AArch64::FPR32RegClass &&
313 ((RC != &AArch64::FPR64RegClass && RC != &AArch64::FPR128RegClass &&
314 RC != &AArch64::ZPRRegClass) ||
316 return false;
319 CpySrc = MRI->createVirtualRegister(&AArch64::FPR32RegClass);
321 TII->get(TargetOpcode::COPY), CpySrc)
323 } else {
325 }
330 }
331 else if (SrcMI->getOpcode() <= TargetOpcode::GENERIC_OP_END)
332 return false;
333
334 Register DefReg = MI.getOperand(0).getReg();
335 Register SrcReg = MI.getOperand(2).getReg();
336 MRI->replaceRegWith(DefReg, SrcReg);
337 MRI->clearKillFlags(SrcReg);
339 MI.eraseFromParent();
340
341 return true;
342}
343
344bool AArch64MIPeepholeOpt::visitCSEL(MachineInstr &MI) {
345
346 if (MI.getOperand(1).getReg() != MI.getOperand(2).getReg())
347 return false;
348
349 auto ZeroReg =
350 MI.getOpcode() == AArch64::CSELXr ? AArch64::XZR : AArch64::WZR;
351 auto OrOpcode =
352 MI.getOpcode() == AArch64::CSELXr ? AArch64::ORRXrs : AArch64::ORRWrs;
353
357 .addReg(MI.getOperand(1).getReg())
359
360 MI.eraseFromParent();
361 return true;
362}
363
364bool AArch64MIPeepholeOpt::visitINSERT(MachineInstr &MI) {
365
366
367
368
369
370
371
372 if (.isRegTiedToDefOperand(1))
373 return false;
374
375 Register DstReg = MI.getOperand(0).getReg();
376 const TargetRegisterClass *RC = MRI->getRegClass(DstReg);
377 MachineInstr *SrcMI = MRI->getUniqueVRegDef(MI.getOperand(2).getReg());
378 if (!SrcMI)
379 return false;
380
381
382
383
384
385
386
387
388
389
390
391 if ((SrcMI->getOpcode() <= TargetOpcode::GENERIC_OP_END) ||
392 !AArch64::GPR64allRegClass.hasSubClassEq(RC))
393 return false;
394
395
396 MachineInstr *SubregMI =
398 TII->get(TargetOpcode::SUBREG_TO_REG), DstReg)
402 LLVM_DEBUG(dbgs() << MI << " replace by:\n: " << *SubregMI << "\n");
403 (void)SubregMI;
404 MI.eraseFromParent();
405
406 return true;
407}
408
409template
411
412
413 if ((Imm & 0xfff000) == 0 || (Imm & 0xfff) == 0 ||
414 (Imm & ~static_cast<T>(0xffffff)) != 0)
415 return false;
416
417
420 if (Insn.size() == 1)
421 return false;
422
423
424 Imm0 = (Imm >> 12) & 0xfff;
425 Imm1 = Imm & 0xfff;
426 return true;
427}
428
429template
430bool AArch64MIPeepholeOpt::visitADDSUB(
431 unsigned PosOpc, unsigned NegOpc, MachineInstr &MI) {
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448 if (MI.getOperand(1).getReg() == AArch64::XZR ||
449 MI.getOperand(1).getReg() == AArch64::WZR)
450 return false;
451
452 return splitTwoPartImm(
454 [PosOpc, NegOpc](T Imm, unsigned RegSize, T &Imm0,
455 T &Imm1) -> std::optional {
457 return std::make_pair(PosOpc, PosOpc);
459 return std::make_pair(NegOpc, NegOpc);
460 return std::nullopt;
461 },
462 [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,
466 MachineBasicBlock *MBB = MI.getParent();
475 });
476}
477
478template
479bool AArch64MIPeepholeOpt::visitADDSSUBS(
480 OpcodePair PosOpcs, OpcodePair NegOpcs, MachineInstr &MI) {
481
482
483
484 if (MI.getOperand(1).getReg() == AArch64::XZR ||
485 MI.getOperand(1).getReg() == AArch64::WZR)
486 return false;
487
488 return splitTwoPartImm(
490 [PosOpcs, NegOpcs, &MI, &TRI = TRI,
492 T &Imm1) -> std::optional {
493 OpcodePair OP;
495 OP = PosOpcs;
497 OP = NegOpcs;
498 else
499 return std::nullopt;
500
501
502 MachineInstr &SrcMI = *MRI->getUniqueVRegDef(MI.getOperand(1).getReg());
504 if (!NZCVUsed || NZCVUsed->C || NZCVUsed->V)
505 return std::nullopt;
506 return OP;
507 },
508 [&TII = TII](MachineInstr &MI, OpcodePair Opcode, unsigned Imm0,
512 MachineBasicBlock *MBB = MI.getParent();
521 });
522}
523
524
525
526bool AArch64MIPeepholeOpt::checkMovImmInstr(MachineInstr &MI,
527 MachineInstr *&MovMI,
528 MachineInstr *&SubregToRegMI) {
529
530 MachineBasicBlock *MBB = MI.getParent();
532 if (L && ->isLoopInvariant(MI))
533 return false;
534
535
536 MovMI = MRI->getUniqueVRegDef(MI.getOperand(2).getReg());
537 if (!MovMI)
538 return false;
539
540
541 SubregToRegMI = nullptr;
542 if (MovMI->getOpcode() == TargetOpcode::SUBREG_TO_REG) {
543 SubregToRegMI = MovMI;
545 if (!MovMI)
546 return false;
547 }
548
549 if (MovMI->getOpcode() != AArch64::MOVi32imm &&
550 MovMI->getOpcode() != AArch64::MOVi64imm)
551 return false;
552
553
554
556 return false;
557 if (SubregToRegMI && ->hasOneUse(SubregToRegMI->getOperand(0).getReg()))
558 return false;
559
560
561 return true;
562}
563
564template
565bool AArch64MIPeepholeOpt::splitTwoPartImm(
566 MachineInstr &MI,
567 SplitAndOpcFunc SplitAndOpc, BuildMIFunc BuildInstr) {
568 unsigned RegSize = sizeof(T) * 8;
570 "Invalid RegSize for legal immediate peephole optimization");
571
572
573 MachineInstr *MovMI, *SubregToRegMI;
574 if (!checkMovImmInstr(MI, MovMI, SubregToRegMI))
575 return false;
576
577
579
580
581
582
583 if (SubregToRegMI)
584 Imm &= 0xFFFFFFFF;
585 OpcodePair Opcode;
586 if (auto R = SplitAndOpc(Imm, RegSize, Imm0, Imm1))
587 Opcode = *R;
588 else
589 return false;
590
591
592
593
594
595
596
597 const TargetRegisterClass *FirstInstrDstRC =
599 const TargetRegisterClass *FirstInstrOperandRC =
601 const TargetRegisterClass *SecondInstrDstRC =
602 (Opcode.first == Opcode.second)
603 ? FirstInstrDstRC
605 const TargetRegisterClass *SecondInstrOperandRC =
606 (Opcode.first == Opcode.second)
607 ? FirstInstrOperandRC
609
610
611 Register DstReg = MI.getOperand(0).getReg();
612 Register SrcReg = MI.getOperand(1).getReg();
613 Register NewTmpReg = MRI->createVirtualRegister(FirstInstrDstRC);
614
615
617 ? MRI->createVirtualRegister(SecondInstrDstRC)
618 : DstReg;
619
620
621 MRI->constrainRegClass(SrcReg, FirstInstrOperandRC);
622 MRI->constrainRegClass(NewTmpReg, SecondInstrOperandRC);
623 if (DstReg != NewDstReg)
624 MRI->constrainRegClass(NewDstReg, MRI->getRegClass(DstReg));
625
626
627 BuildInstr(MI, Opcode, Imm0, Imm1, SrcReg, NewTmpReg, NewDstReg);
628
629
630
631 if (DstReg != NewDstReg) {
632 MRI->replaceRegWith(DstReg, NewDstReg);
633 MI.getOperand(0).setReg(DstReg);
634 }
635
636
637 MI.eraseFromParent();
638 if (SubregToRegMI)
641
642 return true;
643}
644
645bool AArch64MIPeepholeOpt::visitINSviGPR(MachineInstr &MI, unsigned Opc) {
646
647
648
649
650
651
652
653
654
655
656
657 MachineInstr *SrcMI = MRI->getUniqueVRegDef(MI.getOperand(3).getReg());
658
659
660
661 while (true) {
662 if (!SrcMI || SrcMI->getOpcode() != TargetOpcode::COPY)
663 return false;
664
666 return false;
667
669 &AArch64::FPR128RegClass) {
670 break;
671 }
673 }
674
675 Register DstReg = MI.getOperand(0).getReg();
677 MachineInstr *INSvilaneMI =
683
684 LLVM_DEBUG(dbgs() << MI << " replace by:\n: " << *INSvilaneMI << "\n");
685 (void)INSvilaneMI;
686 MI.eraseFromParent();
687 return true;
688}
689
690
691
694 if (->getOperand(0).isReg() ||
->getOperand(0).isDef())
695 return false;
697 if (RC != &AArch64::FPR64RegClass)
698 return false;
699 return MI->getOpcode() > TargetOpcode::GENERIC_OP_END;
700}
701
702bool AArch64MIPeepholeOpt::visitINSvi64lane(MachineInstr &MI) {
703
704
705
706
707
708
709
710 MachineInstr *Low64MI = MRI->getUniqueVRegDef(MI.getOperand(1).getReg());
711 if (Low64MI->getOpcode() != AArch64::INSERT_SUBREG)
712 return false;
715 return false;
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730 MachineInstr *High64MI = MRI->getUniqueVRegDef(MI.getOperand(3).getReg());
731 if (!High64MI || High64MI->getOpcode() != AArch64::INSERT_SUBREG)
732 return false;
734 if (High64MI && High64MI->getOpcode() == TargetOpcode::COPY)
736 if (!High64MI || (High64MI->getOpcode() != AArch64::MOVID &&
737 High64MI->getOpcode() != AArch64::MOVIv2d_ns))
738 return false;
740 return false;
741
742
743 Register OldDef = MI.getOperand(0).getReg();
744 Register NewDef = MI.getOperand(1).getReg();
745 MRI->constrainRegClass(NewDef, MRI->getRegClass(OldDef));
746 MRI->replaceRegWith(OldDef, NewDef);
747 MI.eraseFromParent();
748
749 return true;
750}
751
752bool AArch64MIPeepholeOpt::visitFMOVDr(MachineInstr &MI) {
753
754 MachineInstr *Low64MI = MRI->getUniqueVRegDef(MI.getOperand(1).getReg());
756 return false;
757
758
759 Register OldDef = MI.getOperand(0).getReg();
760 Register NewDef = MI.getOperand(1).getReg();
762 MRI->clearKillFlags(OldDef);
763 MRI->clearKillFlags(NewDef);
764 MRI->constrainRegClass(NewDef, MRI->getRegClass(OldDef));
765 MRI->replaceRegWith(OldDef, NewDef);
766 MI.eraseFromParent();
767
768 return true;
769}
770
771bool AArch64MIPeepholeOpt::visitUBFMXri(MachineInstr &MI) {
772
773
774 int64_t Immr = MI.getOperand(2).getImm();
775 int64_t Imms = MI.getOperand(3).getImm();
776
777 bool IsLSR = Imms == 31 && Immr <= Imms;
778 bool IsLSL = Immr == Imms + 33;
779 if (!IsLSR && !IsLSL)
780 return false;
781
782 if (IsLSL) {
783 Immr -= 32;
784 }
785
786 const TargetRegisterClass *DstRC64 =
788 const TargetRegisterClass *DstRC32 =
789 TRI->getSubRegisterClass(DstRC64, AArch64::sub_32);
790 assert(DstRC32 && "Destination register class of UBFMXri doesn't have a "
791 "sub_32 subregister class");
792
793 const TargetRegisterClass *SrcRC64 =
795 const TargetRegisterClass *SrcRC32 =
796 TRI->getSubRegisterClass(SrcRC64, AArch64::sub_32);
797 assert(SrcRC32 && "Source register class of UBFMXri doesn't have a sub_32 "
798 "subregister class");
799
800 Register DstReg64 = MI.getOperand(0).getReg();
801 Register DstReg32 = MRI->createVirtualRegister(DstRC32);
802 Register SrcReg64 = MI.getOperand(1).getReg();
803 Register SrcReg32 = MRI->createVirtualRegister(SrcRC32);
804
806 SrcReg32)
807 .addReg(SrcReg64, 0, AArch64::sub_32);
808 BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(AArch64::UBFMWri),
809 DstReg32)
814 TII->get(AArch64::SUBREG_TO_REG), DstReg64)
817 .addImm(AArch64::sub_32);
818 MI.eraseFromParent();
819 return true;
820}
821
822
823
824
825bool AArch64MIPeepholeOpt::visitCopy(MachineInstr &MI) {
826 Register InputReg = MI.getOperand(1).getReg();
827 if (MI.getOperand(1).getSubReg() != AArch64::sub_32 ||
828 ->hasOneNonDBGUse(InputReg))
829 return false;
830
831 MachineInstr *SrcMI = MRI->getUniqueVRegDef(InputReg);
832 SmallPtrSet<MachineInstr *, 4> DeadInstrs;
833 DeadInstrs.insert(SrcMI);
834 while (SrcMI && SrcMI->isFullCopy() &&
837 DeadInstrs.insert(SrcMI);
838 }
839
840 if (!SrcMI)
841 return false;
842
843
844 auto getSXTWSrcReg = [](MachineInstr *SrcMI) -> Register {
845 if (SrcMI->getOpcode() != AArch64::SBFMXri ||
848 return AArch64::NoRegister;
850 };
851
852 auto getUXTWSrcReg = [&](MachineInstr *SrcMI) -> Register {
853 if (SrcMI->getOpcode() != AArch64::SUBREG_TO_REG ||
856 return AArch64::NoRegister;
857 MachineInstr *Orr = MRI->getUniqueVRegDef(SrcMI->getOperand(2).getReg());
858 if (!Orr || Orr->getOpcode() != AArch64::ORRWrr ||
861 return AArch64::NoRegister;
863 if (!Cpy || Cpy->getOpcode() != AArch64::COPY ||
865 return AArch64::NoRegister;
866 DeadInstrs.insert(Orr);
868 };
869
870 Register SrcReg = getSXTWSrcReg(SrcMI);
871 if (!SrcReg)
872 SrcReg = getUXTWSrcReg(SrcMI);
873 if (!SrcReg)
874 return false;
875
876 MRI->constrainRegClass(SrcReg, MRI->getRegClass(InputReg));
878 MI.getOperand(1).setReg(SrcReg);
880 for (auto *DeadMI : DeadInstrs) {
882 DeadMI->eraseFromParent();
883 }
884 return true;
885}
886
887bool AArch64MIPeepholeOpt::runOnMachineFunction(MachineFunction &MF) {
889 return false;
890
891 TII = static_cast<const AArch64InstrInfo *>(MF.getSubtarget().getInstrInfo());
892 TRI = static_cast<const AArch64RegisterInfo *>(
894 MLI = &getAnalysis().getLI();
896
897 assert(MRI->isSSA() && "Expected to be run on SSA form!");
898
900
901 for (MachineBasicBlock &MBB : MF) {
903 switch (MI.getOpcode()) {
904 default:
905 break;
906 case AArch64::INSERT_SUBREG:
908 break;
909 case AArch64::ANDWrr:
910 Changed |= trySplitLogicalImm<uint32_t>(AArch64::ANDWri, MI,
911 SplitStrategy::Intersect);
912 break;
913 case AArch64::ANDXrr:
914 Changed |= trySplitLogicalImm<uint64_t>(AArch64::ANDXri, MI,
915 SplitStrategy::Intersect);
916 break;
917 case AArch64::ANDSWrr:
918 Changed |= trySplitLogicalImm<uint32_t>(
919 AArch64::ANDWri, MI, SplitStrategy::Intersect, AArch64::ANDSWri);
920 break;
921 case AArch64::ANDSXrr:
922 Changed |= trySplitLogicalImm<uint64_t>(
923 AArch64::ANDXri, MI, SplitStrategy::Intersect, AArch64::ANDSXri);
924 break;
925 case AArch64::EORWrr:
926 Changed |= trySplitLogicalImm<uint32_t>(AArch64::EORWri, MI,
927 SplitStrategy::Disjoint);
928 break;
929 case AArch64::EORXrr:
930 Changed |= trySplitLogicalImm<uint64_t>(AArch64::EORXri, MI,
931 SplitStrategy::Disjoint);
932 break;
933 case AArch64::ORRWrr:
934 Changed |= trySplitLogicalImm<uint32_t>(AArch64::ORRWri, MI,
935 SplitStrategy::Disjoint);
936 break;
937 case AArch64::ORRXrr:
938 Changed |= trySplitLogicalImm<uint64_t>(AArch64::ORRXri, MI,
939 SplitStrategy::Disjoint);
940 break;
941 case AArch64::ORRWrs:
943 break;
944 case AArch64::ADDWrr:
945 Changed |= visitADDSUB<uint32_t>(AArch64::ADDWri, AArch64::SUBWri, MI);
946 break;
947 case AArch64::SUBWrr:
948 Changed |= visitADDSUB<uint32_t>(AArch64::SUBWri, AArch64::ADDWri, MI);
949 break;
950 case AArch64::ADDXrr:
951 Changed |= visitADDSUB<uint64_t>(AArch64::ADDXri, AArch64::SUBXri, MI);
952 break;
953 case AArch64::SUBXrr:
954 Changed |= visitADDSUB<uint64_t>(AArch64::SUBXri, AArch64::ADDXri, MI);
955 break;
956 case AArch64::ADDSWrr:
958 visitADDSSUBS<uint32_t>({AArch64::ADDWri, AArch64::ADDSWri},
959 {AArch64::SUBWri, AArch64::SUBSWri}, MI);
960 break;
961 case AArch64::SUBSWrr:
963 visitADDSSUBS<uint32_t>({AArch64::SUBWri, AArch64::SUBSWri},
964 {AArch64::ADDWri, AArch64::ADDSWri}, MI);
965 break;
966 case AArch64::ADDSXrr:
968 visitADDSSUBS<uint64_t>({AArch64::ADDXri, AArch64::ADDSXri},
969 {AArch64::SUBXri, AArch64::SUBSXri}, MI);
970 break;
971 case AArch64::SUBSXrr:
973 visitADDSSUBS<uint64_t>({AArch64::SUBXri, AArch64::SUBSXri},
974 {AArch64::ADDXri, AArch64::ADDSXri}, MI);
975 break;
976 case AArch64::CSELWr:
977 case AArch64::CSELXr:
979 break;
980 case AArch64::INSvi64gpr:
981 Changed |= visitINSviGPR(MI, AArch64::INSvi64lane);
982 break;
983 case AArch64::INSvi32gpr:
984 Changed |= visitINSviGPR(MI, AArch64::INSvi32lane);
985 break;
986 case AArch64::INSvi16gpr:
987 Changed |= visitINSviGPR(MI, AArch64::INSvi16lane);
988 break;
989 case AArch64::INSvi8gpr:
990 Changed |= visitINSviGPR(MI, AArch64::INSvi8lane);
991 break;
992 case AArch64::INSvi64lane:
994 break;
995 case AArch64::FMOVDr:
997 break;
998 case AArch64::UBFMXri:
1000 break;
1001 case AArch64::COPY:
1003 break;
1004 }
1005 }
1006 }
1007
1009}
1010
1012 return new AArch64MIPeepholeOpt();
1013}
unsigned const MachineRegisterInfo * MRI
static const TargetRegisterClass * getRegClass(const MachineInstr &MI, Register Reg)
static bool splitDisjointBitmaskImm(T Imm, unsigned RegSize, T &Imm1Enc, T &Imm2Enc)
Definition AArch64MIPeepholeOpt.cpp:196
unsigned HighestBitSet
Definition AArch64MIPeepholeOpt.cpp:175
T NewImm1
Definition AArch64MIPeepholeOpt.cpp:179
unsigned T T & Imm2Enc
Definition AArch64MIPeepholeOpt.cpp:165
unsigned T & Imm1Enc
Definition AArch64MIPeepholeOpt.cpp:165
T NewImm2
Definition AArch64MIPeepholeOpt.cpp:183
unsigned RegSize
Definition AArch64MIPeepholeOpt.cpp:165
static bool is64bitDefwithZeroHigh64bit(MachineInstr *MI, MachineRegisterInfo *MRI)
Definition AArch64MIPeepholeOpt.cpp:692
static bool splitAddSubImm(T Imm, unsigned RegSize, T &Imm0, T &Imm1)
Definition AArch64MIPeepholeOpt.cpp:410
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned LowestBitSet
Definition AArch64MIPeepholeOpt.cpp:174
const TargetInstrInfo & TII
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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:
FunctionPass class - This class is used to implement most global optimizations.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
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 & 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 & addUse(Register RegNo, unsigned Flags=0, unsigned SubReg=0) const
Add a virtual register use operand.
Representation of each machine instruction.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
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
unsigned getSubReg() const
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Wrapper class representing virtual and physical registers.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
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.
virtual const TargetRegisterClass * getRegClass(const MCInstrDesc &MCID, unsigned OpNum) const
Given a machine instruction descriptor, returns the register class constraint for OpNum,...
static bool isLogicalImmediate(uint64_t imm, unsigned regSize)
isLogicalImmediate - Return true if the immediate is valid for a logical immediate instruction of the...
static uint64_t encodeLogicalImmediate(uint64_t imm, unsigned regSize)
encodeLogicalImmediate - Return the encoded immediate value for a logical immediate instruction of th...
void expandMOVImm(uint64_t Imm, unsigned BitSize, SmallVectorImpl< ImmInsnModel > &Insn)
Expand a MOVi32imm or MOVi64imm pseudo instruction to one or more real move-immediate instructions to...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Define
Register definition.
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.
FunctionPass * createAArch64MIPeepholeOptPass()
Definition AArch64MIPeepholeOpt.cpp:1011
int countr_one(T Value)
Count the number of ones from the least significant bit to the first zero bit.
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...
unsigned Log2_64(uint64_t Value)
Return the floor log base 2 of the specified value, -1 if the value is zero.
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
MachineInstr * getImm(const MachineOperand &MO, const MachineRegisterInfo *MRI)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
std::optional< UsedNZCV > examineCFlagsUse(MachineInstr &MI, MachineInstr &CmpInstr, const TargetRegisterInfo &TRI, SmallVectorImpl< MachineInstr * > *CCUseInstrs=nullptr)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
unsigned getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.