LLVM: lib/CodeGen/PeepholeOptimizer.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
95#include
96#include
97#include
98
99using namespace llvm;
102
103#define DEBUG_TYPE "peephole-opt"
104
105
107 cl::desc("Aggressive extension optimization"));
108
111 cl::desc("Disable the peephole optimizer"));
112
113
114
115
118 cl::desc("Disable advanced copy optimization"));
119
121 "disable-non-allocatable-phys-copy-opt", cl::Hidden, cl::init(false),
122 cl::desc("Disable non-allocatable physical register copy optimization"));
123
124
125
128 cl::desc("Limit the length of PHI chains to lookup"));
129
130
131
134 cl::desc("Maximum length of recurrence chain when evaluating the benefit "
135 "of commuting operands"));
136
137STATISTIC(NumReuse, "Number of extension results reused");
138STATISTIC(NumCmps, "Number of compares eliminated");
139STATISTIC(NumImmFold, "Number of move immediate folded");
140STATISTIC(NumLoadFold, "Number of loads folded");
141STATISTIC(NumSelects, "Number of selects optimized");
142STATISTIC(NumUncoalescableCopies, "Number of uncoalescable copies optimized");
143STATISTIC(NumRewrittenCopies, "Number of copies rewritten");
144STATISTIC(NumNAPhysCopies, "Number of non-allocatable physical copies removed");
145
146namespace {
147
148class ValueTrackerResult;
149class RecurrenceInstr;
150
151
152class Rewriter {
153protected:
155 int CurrentSrcIdx = 0;
156public:
158 virtual ~Rewriter() = default;
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185 virtual bool getNextRewritableSource(RegSubRegPair &Src,
187
188
189
190 virtual bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) = 0;
191};
192
193
194class CopyRewriter : public Rewriter {
195public:
196 CopyRewriter(MachineInstr &MI) : Rewriter(MI) {
197 assert(MI.isCopy() && "Expected copy instruction");
198 }
199 ~CopyRewriter() override = default;
200
203 if (++CurrentSrcIdx > 1)
204 return false;
205
206
207 const MachineOperand &MOSrc = CopyLike.getOperand(CurrentSrcIdx);
209
210 const MachineOperand &MODef = CopyLike.getOperand(0);
212 return true;
213 }
214
215 bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
216 MachineOperand &MOSrc = CopyLike.getOperand(CurrentSrcIdx);
217 MOSrc.setReg(NewReg);
219 return true;
220 }
221};
222
223
224
225class UncoalescableRewriter : public Rewriter {
226 int NumDefs;
227
228public:
229 UncoalescableRewriter(MachineInstr &MI) : Rewriter(MI) {
230 NumDefs = MI.getDesc().getNumDefs();
231 }
232
233
234
235
236
239
240 if (CurrentSrcIdx == NumDefs)
241 return false;
242
243 while (CopyLike.getOperand(CurrentSrcIdx).isDead()) {
244 ++CurrentSrcIdx;
245 if (CurrentSrcIdx == NumDefs)
246 return false;
247 }
248
249
251 const MachineOperand &MODef = CopyLike.getOperand(CurrentSrcIdx);
253
254 CurrentSrcIdx++;
255 return true;
256 }
257
258 bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
259 return false;
260 }
261};
262
263
264class InsertSubregRewriter : public Rewriter {
265public:
266 InsertSubregRewriter(MachineInstr &MI) : Rewriter(MI) {
267 assert(MI.isInsertSubreg() && "Invalid instruction");
268 }
269
270
271
272
273
274
275
276
277
278
279
280
283
284 if (CurrentSrcIdx == 2)
285 return false;
286
287 CurrentSrcIdx = 2;
288 const MachineOperand &MOInsertedReg = CopyLike.getOperand(2);
290 const MachineOperand &MODef = CopyLike.getOperand(0);
291
292
293
295
296 return false;
298 (unsigned)CopyLike.getOperand(3).getImm());
299 return true;
300 }
301
302 bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
303 if (CurrentSrcIdx != 2)
304 return false;
305
306 MachineOperand &MO = CopyLike.getOperand(CurrentSrcIdx);
309 return true;
310 }
311};
312
313
314class ExtractSubregRewriter : public Rewriter {
315 const TargetInstrInfo &TII;
316
317public:
318 ExtractSubregRewriter(MachineInstr &MI, const TargetInstrInfo &TII)
320 assert(MI.isExtractSubreg() && "Invalid instruction");
321 }
322
323
324
325
326
327
330
331 if (CurrentSrcIdx == 1)
332 return false;
333
334 CurrentSrcIdx = 1;
335 const MachineOperand &MOExtractedReg = CopyLike.getOperand(1);
336
338 return false;
339
340 Src =
342
343
344 const MachineOperand &MODef = CopyLike.getOperand(0);
346 return true;
347 }
348
349 bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
350
351 if (CurrentSrcIdx != 1)
352 return false;
353
354 CopyLike.getOperand(CurrentSrcIdx).setReg(NewReg);
355
356
357
358 if (!NewSubReg) {
359
360
361
362 CurrentSrcIdx = -1;
363
364
365 CopyLike.removeOperand(2);
366
367 CopyLike.setDesc(TII.get(TargetOpcode::COPY));
368 return true;
369 }
370 CopyLike.getOperand(CurrentSrcIdx + 1).setImm(NewSubReg);
371 return true;
372 }
373};
374
375
376class RegSequenceRewriter : public Rewriter {
377public:
378 RegSequenceRewriter(MachineInstr &MI) : Rewriter(MI) {
379 assert(MI.isRegSequence() && "Invalid instruction");
380 CurrentSrcIdx = -1;
381 }
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
401
402 CurrentSrcIdx += 2;
403 if (static_cast<unsigned>(CurrentSrcIdx) >= CopyLike.getNumOperands())
404 return false;
405
406 const MachineOperand &MOInsertedReg = CopyLike.getOperand(CurrentSrcIdx);
407 Src.Reg = MOInsertedReg.getReg();
408 Src.SubReg = MOInsertedReg.getSubReg();
409
410
411
412 Dst.SubReg = CopyLike.getOperand(CurrentSrcIdx + 1).getImm();
413
414 const MachineOperand &MODef = CopyLike.getOperand(0);
415 Dst.Reg = MODef.getReg();
416 assert(MODef.getSubReg() == 0 && "cannot have subregister def in SSA");
417 return true;
418 }
419
420 bool RewriteCurrentSource(Register NewReg, unsigned NewSubReg) override {
421 MachineOperand &MO = CopyLike.getOperand(CurrentSrcIdx);
424 return true;
425 }
426};
427
429 const TargetInstrInfo *TII = nullptr;
430 const TargetRegisterInfo *TRI = nullptr;
431 MachineRegisterInfo *MRI = nullptr;
432 MachineDominatorTree *DT = nullptr;
433 MachineLoopInfo *MLI = nullptr;
434
435public:
436 PeepholeOptimizer(MachineDominatorTree *DT, MachineLoopInfo *MLI)
437 : DT(DT), MLI(MLI) {}
438
439 bool run(MachineFunction &MF);
440
441 using RewriteMapTy = SmallDenseMap<RegSubRegPair, ValueTrackerResult>;
442
443
444 using RecurrenceCycle = SmallVector<RecurrenceInstr, 4>;
445
446private:
447 bool optimizeCmpInstr(MachineInstr &MI);
448 bool optimizeExtInstr(MachineInstr &MI, MachineBasicBlock &MBB,
449 SmallPtrSetImpl<MachineInstr *> &LocalMIs);
450 bool optimizeSelect(MachineInstr &MI,
451 SmallPtrSetImpl<MachineInstr *> &LocalMIs);
452 bool optimizeCondBranch(MachineInstr &MI);
453
454 bool optimizeCoalescableCopyImpl(Rewriter &&CpyRewriter);
455 bool optimizeCoalescableCopy(MachineInstr &MI);
456 bool optimizeUncoalescableCopy(MachineInstr &MI,
457 SmallPtrSetImpl<MachineInstr *> &LocalMIs);
458 bool optimizeRecurrence(MachineInstr &PHI);
459 bool findNextSource(const TargetRegisterClass *DefRC, unsigned DefSubReg,
460 RegSubRegPair RegSubReg, RewriteMapTy &RewriteMap);
461 bool isMoveImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
462 DenseMap<Register, MachineInstr *> &ImmDefMIs);
463 bool foldImmediate(MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
464 DenseMap<Register, MachineInstr *> &ImmDefMIs,
466
467
468
469
470
472 const SmallSet<Register, 2> &TargetReg,
473 RecurrenceCycle &RC);
474
475
476
477
478
479
480 bool foldRedundantCopy(MachineInstr &MI);
481
482
484
485
486
487
488
489
490 bool
491 foldRedundantNAPhysCopy(MachineInstr &MI,
492 DenseMap<Register, MachineInstr *> &NAPhysToVirtMIs);
493
494 bool isLoadFoldable(MachineInstr &MI,
495 SmallSet<Register, 16> &FoldAsLoadDefCandidates);
496
497
498
499 static bool isCoalescableCopy(const MachineInstr &MI) {
500
501
502 return MI.isCopy() ||
504 MI.isExtractSubreg()));
505 }
506
507
508
509 static bool isUncoalescableCopy(const MachineInstr &MI) {
511 MI.isInsertSubregLike() ||
512 MI.isExtractSubregLike()));
513 }
514
515 MachineInstr &rewriteSource(MachineInstr &CopyLike, RegSubRegPair Def,
516 RewriteMapTy &RewriteMap);
517
518
519
520 DenseMap<RegSubRegPair, MachineInstr *> CopySrcMIs;
521
522
523 void MF_HandleInsertion(MachineInstr &MI) override {}
524
525 bool getCopySrc(MachineInstr &MI, RegSubRegPair &SrcPair) {
526 if (.isCopy())
527 return false;
528
529 Register SrcReg = MI.getOperand(1).getReg();
530 unsigned SrcSubReg = MI.getOperand(1).getSubReg();
531 if (!SrcReg.isVirtual() && !MRI->isConstantPhysReg(SrcReg))
532 return false;
533
535 return true;
536 }
537
538
539
540 void deleteChangedCopy(MachineInstr &MI) {
542 if (!getCopySrc(MI, SrcPair))
543 return;
544
545 auto It = CopySrcMIs.find(SrcPair);
546 if (It != CopySrcMIs.end() && It->second == &MI)
547 CopySrcMIs.erase(It);
548 }
549
550 void MF_HandleRemoval(MachineInstr &MI) override { deleteChangedCopy(MI); }
551
552 void MF_HandleChangeDesc(MachineInstr &MI, const MCInstrDesc &TID) override {
553 deleteChangedCopy(MI);
554 }
555};
556
558public:
559 static char ID;
560
561 PeepholeOptimizerLegacy() : MachineFunctionPass(ID) {
563 }
564
565 bool runOnMachineFunction(MachineFunction &MF) override;
566
567 void getAnalysisUsage(AnalysisUsage &AU) const override {
570 AU.addRequired();
571 AU.addPreserved();
573 AU.addRequired();
574 AU.addPreserved();
575 }
576 }
577
578 MachineFunctionProperties getRequiredProperties() const override {
579 return MachineFunctionProperties().setIsSSA();
580 }
581};
582
583
584
585
586
587
588
589class RecurrenceInstr {
590public:
591 using IndexPair = std::pair<unsigned, unsigned>;
592
593 RecurrenceInstr(MachineInstr *MI) : MI(MI) {}
594 RecurrenceInstr(MachineInstr *MI, unsigned Idx1, unsigned Idx2)
595 : MI(MI), CommutePair(std::make_pair(Idx1, Idx2)) {}
596
597 MachineInstr *getMI() const { return MI; }
598 std::optional getCommutePair() const { return CommutePair; }
599
600private:
601 MachineInstr *MI;
602 std::optional CommutePair;
603};
604
605
606
607
608class ValueTrackerResult {
609private:
610
612
613
614 const MachineInstr *Inst = nullptr;
615
616public:
617 ValueTrackerResult() = default;
618
620
621 bool isValid() const { return getNumSources() > 0; }
622
623 void setInst(const MachineInstr *I) { Inst = I; }
624 const MachineInstr *getInst() const { return Inst; }
625
626 void clear() {
627 RegSrcs.clear();
628 Inst = nullptr;
629 }
630
631 void addSource(Register SrcReg, unsigned SrcSubReg) {
632 RegSrcs.push_back(RegSubRegPair(SrcReg, SrcSubReg));
633 }
634
635 void setSource(int Idx, Register SrcReg, unsigned SrcSubReg) {
636 assert(Idx < getNumSources() && "Reg pair source out of index");
638 }
639
640 int getNumSources() const { return RegSrcs.size(); }
641
642 RegSubRegPair getSrc(int Idx) const { return RegSrcs[Idx]; }
643
644 Register getSrcReg(int Idx) const {
645 assert(Idx < getNumSources() && "Reg source out of index");
646 return RegSrcs[Idx].Reg;
647 }
648
649 unsigned getSrcSubReg(int Idx) const {
650 assert(Idx < getNumSources() && "SubReg source out of index");
651 return RegSrcs[Idx].SubReg;
652 }
653
655 if (Other.getInst() != getInst())
656 return false;
657
658 if (Other.getNumSources() != getNumSources())
659 return false;
660
661 for (int i = 0, e = Other.getNumSources(); i != e; ++i)
662 if (Other.getSrcReg(i) != getSrcReg(i) ||
663 Other.getSrcSubReg(i) != getSrcSubReg(i))
664 return false;
665 return true;
666 }
667};
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685class ValueTracker {
686private:
687
688 const MachineInstr *Def = nullptr;
689
690
691 unsigned DefIdx = 0;
692
693
694 unsigned DefSubReg;
695
696
698
699
700 const MachineRegisterInfo &MRI;
701
702
703 const TargetInstrInfo *TII;
704
705
706 ValueTrackerResult getNextSourceImpl();
707
708
709 ValueTrackerResult getNextSourceFromCopy();
710
711
712 ValueTrackerResult getNextSourceFromBitcast();
713
714
715 ValueTrackerResult getNextSourceFromRegSequence();
716
717
718 ValueTrackerResult getNextSourceFromInsertSubreg();
719
720
721 ValueTrackerResult getNextSourceFromExtractSubreg();
722
723
724 ValueTrackerResult getNextSourceFromSubregToReg();
725
726
727 ValueTrackerResult getNextSourceFromPHI();
728
729public:
730
731
732
733
734
735
736
737
738
739 ValueTracker(Register Reg, unsigned DefSubReg, const MachineRegisterInfo &MRI,
740 const TargetInstrInfo *TII = nullptr)
741 : DefSubReg(DefSubReg), Reg(Reg), MRI(MRI), TII(TII) {
742 if (!Reg.isPhysical()) {
743 Def = MRI.getVRegDef(Reg);
744 DefIdx = MRI.def_begin(Reg).getOperandNo();
745 }
746 }
747
748
749
750
751
752
753 ValueTrackerResult getNextSource();
754};
755
756}
757
758char PeepholeOptimizerLegacy::ID = 0;
759
761
763 "Peephole Optimizations", false, false)
768
769
770
771
772
773
774
775
776
777bool PeepholeOptimizer::optimizeExtInstr(
781 unsigned SubIdx;
782 if (->isCoalescableExtInstr(MI, SrcReg, DstReg, SubIdx))
783 return false;
784
786 return false;
787
788 if (MRI->hasOneNonDBGUse(SrcReg))
789
790 return false;
791
792
793
795 DstRC = TRI->getSubClassWithSubReg(DstRC, SubIdx);
796 if (!DstRC)
797 return false;
798
799
800
801
802
803
804 bool UseSrcSubIdx =
805 TRI->getSubClassWithSubReg(MRI->getRegClass(SrcReg), SubIdx) != nullptr;
806
807
808
811 ReachedBBs.insert(UI.getParent());
812
813
815
816
818
819 bool ExtendLife = true;
821 MachineInstr *UseMI = UseMO.getParent();
822 if (UseMI == &MI)
823 continue;
824
825 if (UseMI->isPHI()) {
826 ExtendLife = false;
827 continue;
828 }
829
830
831 if (UseSrcSubIdx && UseMO.getSubReg() != SubIdx)
832 continue;
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851 if (UseMI->getOpcode() == TargetOpcode::SUBREG_TO_REG)
852 continue;
853
856
857 if (!LocalMIs.count(UseMI))
858 Uses.push_back(&UseMO);
859 } else if (ReachedBBs.count(UseMBB)) {
860
861
862 Uses.push_back(&UseMO);
864
865
866 ExtendedUses.push_back(&UseMO);
867 } else {
868
869
870 ExtendLife = false;
871 break;
872 }
873 }
874
875 if (ExtendLife && !ExtendedUses.empty())
876
877 Uses.append(ExtendedUses.begin(), ExtendedUses.end());
878
879
882 SmallPtrSet<MachineBasicBlock *, 4> PHIBBs;
883
884
885
886
887 for (MachineInstr &UI : MRI->use_nodbg_instructions(DstReg))
888 if (UI.isPHI())
889 PHIBBs.insert(UI.getParent());
890
891 const TargetRegisterClass *RC = MRI->getRegClass(SrcReg);
892 for (MachineOperand *UseMO : Uses) {
893 MachineInstr *UseMI = UseMO->getParent();
894 MachineBasicBlock *UseMBB = UseMI->getParent();
895 if (PHIBBs.count(UseMBB))
896 continue;
897
898
899 if (!Changed) {
900 MRI->clearKillFlags(DstReg);
901 MRI->constrainRegClass(DstReg, DstRC);
902 }
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918 if (UseSrcSubIdx)
919 RC = MRI->getRegClass(UseMI->getOperand(0).getReg());
920
921 Register NewVR = MRI->createVirtualRegister(RC);
922 BuildMI(*UseMBB, UseMI, UseMI->getDebugLoc(),
923 TII->get(TargetOpcode::COPY), NewVR)
924 .addReg(DstReg, 0, SubIdx);
925 if (UseSrcSubIdx)
926 UseMO->setSubReg(0);
927
928 UseMO->setReg(NewVR);
929 ++NumReuse;
930 Changed = true;
931 }
932 }
933
935}
936
937
938
939
940
941bool PeepholeOptimizer::optimizeCmpInstr(MachineInstr &MI) {
942
943
945 int64_t CmpMask, CmpValue;
948 return false;
949
950
951 LLVM_DEBUG(dbgs() << "Attempting to optimize compare: " << MI);
953 LLVM_DEBUG(dbgs() << " -> Successfully optimized compare!\n");
954 ++NumCmps;
955 return true;
956 }
957
958 return false;
959}
960
961
962bool PeepholeOptimizer::optimizeSelect(
963 MachineInstr &MI, SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
964 unsigned TrueOp = 0;
965 unsigned FalseOp = 0;
966 bool Optimizable = false;
969 return false;
970 if (!Optimizable)
971 return false;
973 return false;
975 MI.eraseFromParent();
976 ++NumSelects;
977 return true;
978}
979
980
981bool PeepholeOptimizer::optimizeCondBranch(MachineInstr &MI) {
983}
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998bool PeepholeOptimizer::findNextSource(const TargetRegisterClass *DefRC,
999 unsigned DefSubReg,
1001 RewriteMapTy &RewriteMap) {
1002
1003
1004
1005
1009
1010 unsigned PHICount = 0;
1011 do {
1013
1015 return false;
1016
1017 ValueTracker ValTracker(CurSrcPair.Reg, CurSrcPair.SubReg, *MRI, TII);
1018
1019
1020
1021 while (true) {
1022 ValueTrackerResult Res = ValTracker.getNextSource();
1023
1024 if (!Res.isValid())
1025 return false;
1026
1027
1028 auto [InsertPt, WasInserted] = RewriteMap.try_emplace(CurSrcPair, Res);
1029
1030 if (!WasInserted) {
1031 const ValueTrackerResult &CurSrcRes = InsertPt->second;
1032
1033 assert(CurSrcRes == Res && "ValueTrackerResult found must match");
1034
1035
1036 if (CurSrcRes.getNumSources() > 1) {
1038 << "findNextSource: found PHI cycle, aborting...\n");
1039 return false;
1040 }
1041 break;
1042 }
1043
1044
1045
1046 unsigned NumSrcs = Res.getNumSources();
1047 if (NumSrcs > 1) {
1048 PHICount++;
1050 LLVM_DEBUG(dbgs() << "findNextSource: PHI limit reached\n");
1051 return false;
1052 }
1053
1054 for (unsigned i = 0; i < NumSrcs; ++i)
1055 SrcToLook.push_back(Res.getSrc(i));
1056 break;
1057 }
1058
1059 CurSrcPair = Res.getSrc(0);
1060
1061
1062
1063
1065 return false;
1066
1067
1068 const TargetRegisterClass *SrcRC = MRI->getRegClass(CurSrcPair.Reg);
1069 if (->shouldRewriteCopySrc(DefRC, DefSubReg, SrcRC,
1071 continue;
1072
1073
1074
1075 if (PHICount > 0 && CurSrcPair.SubReg != 0)
1076 continue;
1077
1078
1079 break;
1080 }
1081 } while (!SrcToLook.empty());
1082
1083
1084 return CurSrcPair.Reg != Reg;
1085}
1086
1087
1088
1089
1090
1091
1096 assert(!SrcRegs.empty() && "No sources to create a PHI instruction?");
1097
1099
1100
1101 assert(SrcRegs[0].SubReg == 0 && "should not have subreg operand");
1102 Register NewVR = MRI.createVirtualRegister(NewRC);
1105 TII.get(TargetOpcode::PHI), NewVR);
1106
1107 unsigned MBBOpIdx = 2;
1109 MIB.addReg(RegPair.Reg, 0, RegPair.SubReg);
1111
1112
1113
1114 MRI.clearKillFlags(RegPair.Reg);
1115 MBBOpIdx += 2;
1116 }
1117
1118 return *MIB;
1119}
1120
1121
1122
1123
1124
1125
1126
1130 const PeepholeOptimizer::RewriteMapTy &RewriteMap,
1131 bool HandleMultipleSources = true) {
1133 while (true) {
1134 ValueTrackerResult Res = RewriteMap.lookup(LookupSrc);
1135
1136 if (!Res.isValid())
1137 return LookupSrc;
1138
1139
1140 unsigned NumSrcs = Res.getNumSources();
1141 if (NumSrcs == 1) {
1142 LookupSrc.Reg = Res.getSrcReg(0);
1143 LookupSrc.SubReg = Res.getSrcSubReg(0);
1144 continue;
1145 }
1146
1147
1148 if (!HandleMultipleSources)
1149 break;
1150
1151
1152
1154 for (unsigned i = 0; i < NumSrcs; ++i) {
1155 RegSubRegPair PHISrc(Res.getSrcReg(i), Res.getSrcSubReg(i));
1158 }
1159
1160
1168 }
1169
1171}
1172
1173bool PeepholeOptimizer::optimizeCoalescableCopyImpl(Rewriter &&CpyRewriter) {
1175
1176
1179 while (CpyRewriter.getNextRewritableSource(TrackPair, Dst)) {
1180 if (Dst.Reg.isPhysical()) {
1181
1182
1183
1184
1185 continue;
1186 }
1187
1188 const TargetRegisterClass *DefRC = MRI->getRegClass(Dst.Reg);
1189
1190
1191 RewriteMapTy RewriteMap;
1192
1193
1194 if (!findNextSource(DefRC, Dst.SubReg, TrackPair, RewriteMap))
1195 continue;
1196
1197
1198
1200 false);
1202 "should not rewrite source to original value");
1203 if (!NewSrc.Reg)
1204 continue;
1205
1206 if (NewSrc.SubReg) {
1207
1208
1209
1210 const TargetRegisterClass *RC = MRI->getRegClass(NewSrc.Reg);
1211 const TargetRegisterClass *WithSubRC =
1212 TRI->getSubClassWithSubReg(RC, NewSrc.SubReg);
1213 if (->constrainRegClass(NewSrc.Reg, WithSubRC))
1214 continue;
1216 }
1217
1218
1219 if (CpyRewriter.RewriteCurrentSource(NewSrc.Reg, NewSrc.SubReg)) {
1220
1221 MRI->clearKillFlags(NewSrc.Reg);
1223 }
1224 }
1225
1226
1227
1228
1229
1230
1231 NumRewrittenCopies += Changed;
1233}
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246bool PeepholeOptimizer::optimizeCoalescableCopy(MachineInstr &MI) {
1247 assert(isCoalescableCopy(MI) && "Invalid argument");
1248 assert(MI.getDesc().getNumDefs() == 1 &&
1249 "Coalescer can understand multiple defs?!");
1250 const MachineOperand &MODef = MI.getOperand(0);
1251
1253 return false;
1254
1255 switch (MI.getOpcode()) {
1256 case TargetOpcode::COPY:
1257 return optimizeCoalescableCopyImpl(CopyRewriter(MI));
1258 case TargetOpcode::INSERT_SUBREG:
1259 return optimizeCoalescableCopyImpl(InsertSubregRewriter(MI));
1260 case TargetOpcode::EXTRACT_SUBREG:
1261 return optimizeCoalescableCopyImpl(ExtractSubregRewriter(MI, *TII));
1262 case TargetOpcode::REG_SEQUENCE:
1263 return optimizeCoalescableCopyImpl(RegSequenceRewriter(MI));
1264 default:
1265
1266 if (MI.isBitcast() || MI.isRegSequenceLike() || MI.isInsertSubregLike() ||
1267 MI.isExtractSubregLike())
1268 return optimizeCoalescableCopyImpl(UncoalescableRewriter(MI));
1269 return false;
1270 }
1271}
1272
1273
1274
1275
1276
1277
1278MachineInstr &PeepholeOptimizer::rewriteSource(MachineInstr &CopyLike,
1280 RewriteMapTy &RewriteMap) {
1281 assert(.Reg.isPhysical() && "We do not rewrite physical registers");
1282
1283
1285
1286
1287 const TargetRegisterClass *DefRC = MRI->getRegClass(Def.Reg);
1288 Register NewVReg = MRI->createVirtualRegister(DefRC);
1289
1290 if (NewSrc.SubReg) {
1291 const TargetRegisterClass *NewSrcRC = MRI->getRegClass(NewSrc.Reg);
1292 const TargetRegisterClass *WithSubRC =
1293 TRI->getSubClassWithSubReg(NewSrcRC, NewSrc.SubReg);
1294
1295
1296
1297
1298 if (->constrainRegClass(NewSrc.Reg, WithSubRC))
1299 llvm_unreachable("replacement register cannot support subregister");
1300 }
1301
1302 MachineInstr *NewCopy =
1304 TII->get(TargetOpcode::COPY), NewVReg)
1306
1307 if (Def.SubReg) {
1310 }
1311
1315 MRI->replaceRegWith(Def.Reg, NewVReg);
1316 MRI->clearKillFlags(NewVReg);
1317
1318
1319
1320 MRI->clearKillFlags(NewSrc.Reg);
1321
1322 return *NewCopy;
1323}
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336bool PeepholeOptimizer::optimizeUncoalescableCopy(
1337 MachineInstr &MI, SmallPtrSetImpl<MachineInstr *> &LocalMIs) {
1338 assert(isUncoalescableCopy(MI) && "Invalid argument");
1339 UncoalescableRewriter CpyRewriter(MI);
1340
1341
1342
1343
1344 RewriteMapTy RewriteMap;
1348 while (CpyRewriter.getNextRewritableSource(Src, Def)) {
1349
1350
1351 if (Def.Reg.isPhysical())
1352 return false;
1353
1354
1355
1356
1357 const TargetRegisterClass *DefRC = MRI->getRegClass(Def.Reg);
1358
1359
1360
1361 if (!findNextSource(DefRC, Def.SubReg, Def, RewriteMap))
1362 return false;
1363
1365 }
1366
1367
1369
1370 MachineInstr &NewCopy = rewriteSource(MI, Def, RewriteMap);
1371 LocalMIs.insert(&NewCopy);
1372 }
1373
1374
1375 LLVM_DEBUG(dbgs() << "Deleting uncoalescable copy: " << MI);
1376 MI.eraseFromParent();
1377 ++NumUncoalescableCopies;
1378 return true;
1379}
1380
1381
1382
1383
1384bool PeepholeOptimizer::isLoadFoldable(
1385 MachineInstr &MI, SmallSet<Register, 16> &FoldAsLoadDefCandidates) {
1386 if (.canFoldAsLoad() ||
.mayLoad())
1387 return false;
1388 const MCInstrDesc &MCID = MI.getDesc();
1390 return false;
1391
1393
1394
1395
1396 if (Reg.isVirtual() && .getOperand(0).getSubReg() &&
1397 MRI->hasOneNonDBGUser(Reg)) {
1398 FoldAsLoadDefCandidates.insert(Reg);
1399 return true;
1400 }
1401 return false;
1402}
1403
1404bool PeepholeOptimizer::isMoveImmediate(
1405 MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
1406 DenseMap<Register, MachineInstr *> &ImmDefMIs) {
1407 const MCInstrDesc &MCID = MI.getDesc();
1408 if (MCID.getNumDefs() != 1 || .getOperand(0).isReg())
1409 return false;
1412 return false;
1413
1414 int64_t ImmVal;
1416 return false;
1417
1418 ImmDefMIs.insert(std::make_pair(Reg, &MI));
1420 return true;
1421}
1422
1423
1424
1425
1426bool PeepholeOptimizer::foldImmediate(
1427 MachineInstr &MI, SmallSet<Register, 4> &ImmDefRegs,
1428 DenseMap<Register, MachineInstr *> &ImmDefMIs, bool &Deleted) {
1430 for (unsigned i = 0, e = MI.getDesc().getNumOperands(); i != e; ++i) {
1431 MachineOperand &MO = MI.getOperand(i);
1433 continue;
1436 continue;
1437 if (ImmDefRegs.count(Reg) == 0)
1438 continue;
1439 DenseMap<Register, MachineInstr *>::iterator II = ImmDefMIs.find(Reg);
1440 assert(II != ImmDefMIs.end() && "couldn't find immediate definition");
1442 ++NumImmFold;
1443
1444
1445
1446 if (MRI->getVRegDef(Reg) &&
1448 Register DstReg = MI.getOperand(0).getReg();
1450 MRI->getRegClass(DstReg) == MRI->getRegClass(Reg)) {
1451 MRI->replaceRegWith(DstReg, Reg);
1452 MI.eraseFromParent();
1454 }
1455 }
1456 return true;
1457 }
1458 }
1459 return false;
1460}
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476bool PeepholeOptimizer::foldRedundantCopy(MachineInstr &MI) {
1477 assert(MI.isCopy() && "expected a COPY machine instruction");
1478
1480 if (!getCopySrc(MI, SrcPair))
1481 return false;
1482
1483 Register DstReg = MI.getOperand(0).getReg();
1485 return false;
1486
1487 if (CopySrcMIs.insert(std::make_pair(SrcPair, &MI)).second) {
1488
1489 return false;
1490 }
1491
1492 MachineInstr *PrevCopy = CopySrcMIs.find(SrcPair)->second;
1493
1495 "Unexpected mismatching subreg!");
1496
1498
1499
1500
1501
1502
1503 if (MRI->getRegClass(DstReg) != MRI->getRegClass(PrevDstReg))
1504 return false;
1505
1506 MRI->replaceRegWith(DstReg, PrevDstReg);
1507
1508
1509 MRI->clearKillFlags(PrevDstReg);
1510 return true;
1511}
1512
1513bool PeepholeOptimizer::isNAPhysCopy(Register Reg) {
1515}
1516
1517bool PeepholeOptimizer::foldRedundantNAPhysCopy(
1518 MachineInstr &MI, DenseMap<Register, MachineInstr *> &NAPhysToVirtMIs) {
1519 assert(MI.isCopy() && "expected a COPY machine instruction");
1520
1522 return false;
1523
1524 Register DstReg = MI.getOperand(0).getReg();
1525 Register SrcReg = MI.getOperand(1).getReg();
1526 if (isNAPhysCopy(SrcReg) && DstReg.isVirtual()) {
1527
1528
1529
1530 NAPhysToVirtMIs.insert({SrcReg, &MI});
1531 return false;
1532 }
1533
1534 if (!(SrcReg.isVirtual() && isNAPhysCopy(DstReg)))
1535 return false;
1536
1537
1538 auto PrevCopy = NAPhysToVirtMIs.find(DstReg);
1539 if (PrevCopy == NAPhysToVirtMIs.end()) {
1540
1541
1542 LLVM_DEBUG(dbgs() << "NAPhysCopy: intervening clobber forbids erasing "
1543 << MI);
1544 return false;
1545 }
1546
1548 if (PrevDstReg == SrcReg) {
1549
1550
1552 ++NumNAPhysCopies;
1553 return true;
1554 }
1555
1556
1557
1558
1559
1560 LLVM_DEBUG(dbgs() << "NAPhysCopy: missed opportunity " << MI);
1561 NAPhysToVirtMIs.erase(PrevCopy);
1562 return false;
1563}
1564
1565
1569
1570bool PeepholeOptimizer::findTargetRecurrence(
1571 Register Reg, const SmallSet<Register, 2> &TargetRegs,
1572 RecurrenceCycle &RC) {
1573
1575 return true;
1576
1577
1578
1579
1580
1581
1582 if (->hasOneNonDBGUse(Reg))
1583 return false;
1584
1585
1587 return false;
1588
1589 MachineInstr &MI = *(MRI->use_instr_nodbg_begin(Reg));
1590 unsigned Idx = MI.findRegisterUseOperandIdx(Reg, nullptr);
1591
1592
1593
1594 if (MI.getDesc().getNumDefs() != 1)
1595 return false;
1596
1597 MachineOperand &DefOp = MI.getOperand(0);
1599 return false;
1600
1601
1602
1603
1604 unsigned TiedUseIdx;
1605 if (.isRegTiedToUseOperand(0, &TiedUseIdx))
1606 return false;
1607
1608 if (Idx == TiedUseIdx) {
1609 RC.push_back(RecurrenceInstr(&MI));
1610 return findTargetRecurrence(DefOp.getReg(), TargetRegs, RC);
1611 } else {
1612
1615 RC.push_back(RecurrenceInstr(&MI, Idx, CommIdx));
1616 return findTargetRecurrence(DefOp.getReg(), TargetRegs, RC);
1617 }
1618 }
1619
1620 return false;
1621}
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641bool PeepholeOptimizer::optimizeRecurrence(MachineInstr &PHI) {
1642 SmallSet<Register, 2> TargetRegs;
1643 for (unsigned Idx = 1; Idx < PHI.getNumOperands(); Idx += 2) {
1644 MachineOperand &MO = PHI.getOperand(Idx);
1647 }
1648
1650 RecurrenceCycle RC;
1651 if (findTargetRecurrence(PHI.getOperand(0).getReg(), TargetRegs, RC)) {
1652
1653
1655 for (auto &RI : RC) {
1657 auto CP = RI.getCommutePair();
1658 if (CP) {
1661 (*CP).second);
1662 LLVM_DEBUG(dbgs() << "\t\tCommuted: " << *(RI.getMI()));
1663 }
1664 }
1665 }
1666
1668}
1669
1670PreservedAnalyses
1674 auto *DT =
1677 PeepholeOptimizer Impl(DT, MLI);
1678 bool Changed = Impl.run(MF);
1681
1686 return PA;
1687}
1688
1689bool PeepholeOptimizerLegacy::runOnMachineFunction(MachineFunction &MF) {
1691 return false;
1693 ? &getAnalysis().getDomTree()
1694 : nullptr;
1695 auto *MLI = &getAnalysis().getLI();
1696 PeepholeOptimizer Impl(DT, MLI);
1697 return Impl.run(MF);
1698}
1699
1701
1702 LLVM_DEBUG(dbgs() << "********** PEEPHOLE OPTIMIZER **********\n");
1704
1706 return false;
1707
1712
1714
1716 bool SeenMoveImm = false;
1717
1718
1719
1720
1721
1722
1723
1728
1729
1730
1731
1732
1733
1735
1736 CopySrcMIs.clear();
1737
1739
1741 MII != MIE;) {
1743
1744 ++MII;
1746
1747
1748
1749 if (MI->isDebugInstr())
1750 continue;
1751
1752 if (MI->isPosition())
1753 continue;
1754
1755 if (IsLoopHeader && MI->isPHI()) {
1756 if (optimizeRecurrence(*MI)) {
1758 continue;
1759 }
1760 }
1761
1762 if (->isCopy()) {
1763 for (const MachineOperand &MO : MI->operands()) {
1764
1765 if (MO.isReg()) {
1767 if (MO.isDef() && isNAPhysCopy(Reg)) {
1768 const auto &Def = NAPhysToVirtMIs.find(Reg);
1769 if (Def != NAPhysToVirtMIs.end()) {
1770
1771
1773 << "NAPhysCopy: invalidating because of " << *MI);
1774 NAPhysToVirtMIs.erase(Def);
1775 }
1776 }
1778 const uint32_t *RegMask = MO.getRegMask();
1779 for (auto &RegMI : NAPhysToVirtMIs) {
1783 << "NAPhysCopy: invalidating because of " << *MI);
1784 NAPhysToVirtMIs.erase(Def);
1785 }
1786 }
1787 }
1788 }
1789 }
1790
1791 if (MI->isImplicitDef() || MI->isKill())
1792 continue;
1793
1794 if (MI->isInlineAsm() || MI->hasUnmodeledSideEffects()) {
1795
1796
1797
1798
1799 LLVM_DEBUG(dbgs() << "NAPhysCopy: blowing away all info due to "
1800 << *MI);
1801 NAPhysToVirtMIs.clear();
1802 }
1803
1804 if ((isUncoalescableCopy(*MI) &&
1805 optimizeUncoalescableCopy(*MI, LocalMIs)) ||
1806 (MI->isCompare() && optimizeCmpInstr(*MI)) ||
1807 (MI->isSelect() && optimizeSelect(*MI, LocalMIs))) {
1808
1811 continue;
1812 }
1813
1814 if (MI->isConditionalBranch() && optimizeCondBranch(*MI)) {
1816 continue;
1817 }
1818
1819 if (isCoalescableCopy(*MI) && optimizeCoalescableCopy(*MI)) {
1820
1822 continue;
1823 }
1824
1825 if (MI->isCopy() && (foldRedundantCopy(*MI) ||
1826 foldRedundantNAPhysCopy(*MI, NAPhysToVirtMIs))) {
1828 LLVM_DEBUG(dbgs() << "Deleting redundant copy: " << *MI << "\n");
1829 MI->eraseFromParent();
1831 continue;
1832 }
1833
1834 if (isMoveImmediate(*MI, ImmDefRegs, ImmDefMIs)) {
1835 SeenMoveImm = true;
1836 } else {
1837 Changed |= optimizeExtInstr(*MI, MBB, LocalMIs);
1838
1839
1840
1841 MII = MI;
1842 ++MII;
1843 if (SeenMoveImm) {
1845 Changed |= foldImmediate(*MI, ImmDefRegs, ImmDefMIs, Deleted);
1848 continue;
1849 }
1850 }
1851 }
1852
1853
1854
1855
1856 if (!isLoadFoldable(*MI, FoldAsLoadDefCandidates) &&
1857 !FoldAsLoadDefCandidates.empty()) {
1858
1859
1860
1861
1862
1863
1864 const MCInstrDesc &MIDesc = MI->getDesc();
1865 for (unsigned i = MIDesc.getNumDefs(); i != MI->getNumOperands(); ++i) {
1866 const MachineOperand &MOp = MI->getOperand(i);
1867 if (!MOp.isReg())
1868 continue;
1870 if (FoldAsLoadDefCandidates.count(FoldAsLoadDefReg)) {
1871
1872
1873
1874
1875 Register FoldedReg = FoldAsLoadDefReg;
1876 MachineInstr *DefMI = nullptr;
1877 if (MachineInstr *FoldMI =
1879
1880
1885 LocalMIs.insert(FoldMI);
1886
1887 if (MI->shouldUpdateAdditionalCallInfo())
1888 MI->getMF()->moveAdditionalCallInfo(MI, FoldMI);
1889 MI->eraseFromParent();
1891 MRI->markUsesInDebugValueAsUndef(FoldedReg);
1892 FoldAsLoadDefCandidates.erase(FoldedReg);
1893 ++NumLoadFold;
1894
1895
1897 MI = FoldMI;
1898 }
1899 }
1900 }
1901 }
1902
1903
1904
1905
1906 if (MI->isLoadFoldBarrier()) {
1907 LLVM_DEBUG(dbgs() << "Encountered load fold barrier on " << *MI);
1908 FoldAsLoadDefCandidates.clear();
1909 }
1910 }
1911 }
1912
1913 MF.resetDelegate(this);
1915}
1916
1917ValueTrackerResult ValueTracker::getNextSourceFromCopy() {
1918 assert(Def->isCopy() && "Invalid definition");
1919
1920
1921
1922
1923 assert(Def->getNumOperands() - Def->getNumImplicitOperands() == 2 &&
1924 "Invalid number of operands");
1925 assert(->hasImplicitDef() && "Only implicit uses are allowed");
1926 assert(->getOperand(DefIdx).getSubReg() && "no subregister defs in SSA");
1927
1928
1929 const MachineOperand &Src = Def->getOperand(1);
1930 if (Src.isUndef())
1931 return ValueTrackerResult();
1932
1933 Register SrcReg = Src.getReg();
1934 unsigned SubReg = Src.getSubReg();
1935 if (DefSubReg) {
1936 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
1938
1940
1941 const TargetRegisterClass *RegRC = MRI.getRegClass(SrcReg);
1942 const TargetRegisterClass *SrcWithSubRC =
1943 TRI->getSubClassWithSubReg(RegRC, SubReg);
1944 if (RegRC != SrcWithSubRC)
1945 return ValueTrackerResult();
1946 } else {
1947 if (->getSubReg(SrcReg, SubReg))
1948 return ValueTrackerResult();
1949 }
1950 }
1951
1952 return ValueTrackerResult(SrcReg, SubReg);
1953}
1954
1955ValueTrackerResult ValueTracker::getNextSourceFromBitcast() {
1956 assert(Def->isBitcast() && "Invalid definition");
1957
1958
1959 if (Def->mayRaiseFPException() || Def->hasUnmodeledSideEffects())
1960 return ValueTrackerResult();
1961
1962
1963 if (Def->getDesc().getNumDefs() != 1)
1964 return ValueTrackerResult();
1965
1966 assert(->getOperand(DefIdx).getSubReg() && "no subregister defs in SSA");
1967
1968 unsigned SrcIdx = Def->getNumOperands();
1969 for (unsigned OpIdx = DefIdx + 1, EndOpIdx = SrcIdx; OpIdx != EndOpIdx;
1971 const MachineOperand &MO = Def->getOperand(OpIdx);
1973 continue;
1974
1976 continue;
1977 assert(!MO.isDef() && "We should have skipped all the definitions by now");
1978 if (SrcIdx != EndOpIdx)
1979
1980 return ValueTrackerResult();
1982 }
1983
1984
1985
1986 if (SrcIdx >= Def->getNumOperands())
1987 return ValueTrackerResult();
1988
1989 const MachineOperand &DefOp = Def->getOperand(DefIdx);
1990
1991
1992
1993 for (const MachineInstr &UseMI : MRI.use_nodbg_instructions(DefOp.getReg())) {
1994 if (UseMI.isSubregToReg())
1995 return ValueTrackerResult();
1996 }
1997
1998 const MachineOperand &Src = Def->getOperand(SrcIdx);
1999 if (Src.isUndef())
2000 return ValueTrackerResult();
2001 return ValueTrackerResult(Src.getReg(), Src.getSubReg());
2002}
2003
2004ValueTrackerResult ValueTracker::getNextSourceFromRegSequence() {
2005 assert((Def->isRegSequence() || Def->isRegSequenceLike()) &&
2006 "Invalid definition");
2007
2008 assert(->getOperand(DefIdx).getSubReg() && "illegal subregister def");
2009
2012 return ValueTrackerResult();
2013
2014
2015
2016
2017
2018
2020 if (RegSeqInput.SubIdx == DefSubReg)
2021 return ValueTrackerResult(RegSeqInput.Reg, RegSeqInput.SubReg);
2022 }
2023
2024 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
2025
2026
2027
2029 LaneBitmask DefMask = TRI->getSubRegIndexLaneMask(DefSubReg);
2030 LaneBitmask ThisOpRegMask = TRI->getSubRegIndexLaneMask(RegSeqInput.SubIdx);
2031
2032
2033
2034
2035
2036 if ((DefMask & ThisOpRegMask) != DefMask)
2037 continue;
2038
2039 unsigned ReverseDefCompose =
2040 TRI->reverseComposeSubRegIndices(RegSeqInput.SubIdx, DefSubReg);
2041 if (!ReverseDefCompose)
2042 continue;
2043
2044 unsigned ComposedDefInSrcReg1 =
2045 TRI->composeSubRegIndices(RegSeqInput.SubReg, ReverseDefCompose);
2046
2047
2048
2049
2050
2051 const TargetRegisterClass *SrcRC = MRI.getRegClass(RegSeqInput.Reg);
2052 const TargetRegisterClass *SrcWithSubRC =
2053 TRI->getSubClassWithSubReg(SrcRC, ComposedDefInSrcReg1);
2054 if (SrcRC != SrcWithSubRC)
2055 return ValueTrackerResult();
2056
2057 return ValueTrackerResult(RegSeqInput.Reg, ComposedDefInSrcReg1);
2058 }
2059
2060
2061
2062
2063 return ValueTrackerResult();
2064}
2065
2066ValueTrackerResult ValueTracker::getNextSourceFromInsertSubreg() {
2067 assert((Def->isInsertSubreg() || Def->isInsertSubregLike()) &&
2068 "Invalid definition");
2069 assert(->getOperand(DefIdx).getSubReg() && "no subreg defs in SSA");
2070
2074 return ValueTrackerResult();
2075
2076
2077
2078
2079
2080
2081
2082
2083 if (InsertedReg.SubIdx == DefSubReg) {
2084 return ValueTrackerResult(InsertedReg.Reg, InsertedReg.SubReg);
2085 }
2086
2087
2088
2089 const MachineOperand &MODef = Def->getOperand(DefIdx);
2090
2091
2092
2095 return ValueTrackerResult();
2096
2097
2098
2099 const TargetRegisterInfo *TRI = MRI.getTargetRegisterInfo();
2100 if ((TRI->getSubRegIndexLaneMask(DefSubReg) &
2101 TRI->getSubRegIndexLaneMask(InsertedReg.SubIdx))
2102 .any())
2103 return ValueTrackerResult();
2104
2105
2106 return ValueTrackerResult(BaseReg.Reg, DefSubReg);
2107}
2108
2109ValueTrackerResult ValueTracker::getNextSourceFromExtractSubreg() {
2110 assert((Def->isExtractSubreg() || Def->isExtractSubregLike()) &&
2111 "Invalid definition");
2112
2113
2114
2115
2116
2117 if (DefSubReg)
2118 return ValueTrackerResult();
2119
2122 return ValueTrackerResult();
2123
2124
2125
2126 if (ExtractSubregInputReg.SubReg)
2127 return ValueTrackerResult();
2128
2129 return ValueTrackerResult(ExtractSubregInputReg.Reg,
2130 ExtractSubregInputReg.SubIdx);
2131}
2132
2133ValueTrackerResult ValueTracker::getNextSourceFromSubregToReg() {
2134 assert(Def->isSubregToReg() && "Invalid definition");
2135
2136
2137
2138
2139
2140
2141
2142 if (DefSubReg != Def->getOperand(3).getImm())
2143 return ValueTrackerResult();
2144
2145
2146 if (Def->getOperand(2).getSubReg())
2147 return ValueTrackerResult();
2148
2149 return ValueTrackerResult(Def->getOperand(2).getReg(),
2150 Def->getOperand(3).getImm());
2151}
2152
2153
2154ValueTrackerResult ValueTracker::getNextSourceFromPHI() {
2155 assert(Def->isPHI() && "Invalid definition");
2156 ValueTrackerResult Res;
2157
2158
2159 for (unsigned i = 1, e = Def->getNumOperands(); i < e; i += 2) {
2160 const MachineOperand &MO = Def->getOperand(i);
2161 assert(MO.isReg() && "Invalid PHI instruction");
2162
2163
2165 return ValueTrackerResult();
2167 }
2168
2169 return Res;
2170}
2171
2172ValueTrackerResult ValueTracker::getNextSourceImpl() {
2173 assert(Def && "This method needs a valid definition");
2174
2175 assert(((Def->getOperand(DefIdx).isDef() &&
2176 (DefIdx < Def->getDesc().getNumDefs() ||
2177 Def->getDesc().isVariadic())) ||
2178 Def->getOperand(DefIdx).isImplicit()) &&
2179 "Invalid DefIdx");
2180 if (Def->isCopy())
2181 return getNextSourceFromCopy();
2182 if (Def->isBitcast())
2183 return getNextSourceFromBitcast();
2184
2185
2187 return ValueTrackerResult();
2188 if (Def->isRegSequence() || Def->isRegSequenceLike())
2189 return getNextSourceFromRegSequence();
2190 if (Def->isInsertSubreg() || Def->isInsertSubregLike())
2191 return getNextSourceFromInsertSubreg();
2192 if (Def->isExtractSubreg() || Def->isExtractSubregLike())
2193 return getNextSourceFromExtractSubreg();
2194 if (Def->isSubregToReg())
2195 return getNextSourceFromSubregToReg();
2196 if (Def->isPHI())
2197 return getNextSourceFromPHI();
2198 return ValueTrackerResult();
2199}
2200
2201ValueTrackerResult ValueTracker::getNextSource() {
2202
2203
2204 if (!Def)
2205 return ValueTrackerResult();
2206
2207 ValueTrackerResult Res = getNextSourceImpl();
2208 if (Res.isValid()) {
2209
2210
2211
2212 bool OneRegSrc = Res.getNumSources() == 1;
2213 if (OneRegSrc)
2214 Reg = Res.getSrcReg(0);
2215
2216
2217 Res.setInst(Def);
2218
2219
2220
2223 if (DI != MRI.def_end()) {
2226 DefSubReg = Res.getSrcSubReg(0);
2227 } else {
2228 Def = nullptr;
2229 }
2230 return Res;
2231 }
2232 }
2233
2234
2235
2236 Def = nullptr;
2237 return Res;
2238}
unsigned const MachineRegisterInfo * MRI
for(const MachineOperand &MO :llvm::drop_begin(OldMI.operands(), Desc.getNumOperands()))
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
This file defines the DenseMap class.
A common definition of LaneBitmask for use in TableGen and CodeGen.
TargetInstrInfo::RegSubRegPair RegSubRegPair
Register const TargetRegisterInfo * TRI
Promote Memory to Register
MachineInstr unsigned OpIdx
uint64_t IntrinsicInst * II
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static cl::opt< unsigned > RewritePHILimit("rewrite-phi-limit", cl::Hidden, cl::init(10), cl::desc("Limit the length of PHI chains to lookup"))
static cl::opt< bool > DisablePeephole("disable-peephole", cl::Hidden, cl::init(false), cl::desc("Disable the peephole optimizer"))
static cl::opt< unsigned > MaxRecurrenceChain("recurrence-chain-limit", cl::Hidden, cl::init(3), cl::desc("Maximum length of recurrence chain when evaluating the benefit " "of commuting operands"))
static cl::opt< bool > DisableNAPhysCopyOpt("disable-non-allocatable-phys-copy-opt", cl::Hidden, cl::init(false), cl::desc("Disable non-allocatable physical register copy optimization"))
static bool isVirtualRegisterOperand(MachineOperand &MO)
\bried Returns true if MO is a virtual register operand.
Definition PeepholeOptimizer.cpp:1566
static MachineInstr & insertPHI(MachineRegisterInfo &MRI, const TargetInstrInfo &TII, const SmallVectorImpl< RegSubRegPair > &SrcRegs, MachineInstr &OrigPHI)
Insert a PHI instruction with incoming edges SrcRegs that are guaranteed to have the same register cl...
Definition PeepholeOptimizer.cpp:1092
static cl::opt< bool > Aggressive("aggressive-ext-opt", cl::Hidden, cl::desc("Aggressive extension optimization"))
static cl::opt< bool > DisableAdvCopyOpt("disable-adv-copy-opt", cl::Hidden, cl::init(false), cl::desc("Disable advanced copy optimization"))
Specifiy whether or not the value tracking looks through complex instructions.
TargetInstrInfo::RegSubRegPairAndIdx RegSubRegPairAndIdx
Definition PeepholeOptimizer.cpp:101
static RegSubRegPair getNewSource(MachineRegisterInfo *MRI, const TargetInstrInfo *TII, RegSubRegPair Def, const PeepholeOptimizer::RewriteMapTy &RewriteMap, bool HandleMultipleSources=true)
Given a Def.Reg and Def.SubReg pair, use RewriteMap to find the new source to use for rewrite.
Definition PeepholeOptimizer.cpp:1128
const SmallVectorImpl< MachineOperand > & Cond
Remove Loads Into Fake Uses
static bool isValid(const char C)
Returns true if C is a valid mangled character: <0-9a-zA-Z_>.
This file defines the SmallPtrSet class.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Virtual Register Rewriter
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
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.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool isLoopHeader(const BlockT *BB) const
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
An RAII based helper class to modify MachineFunctionProperties when running pass.
MachineInstrBundleIterator< MachineInstr > iterator
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
bool dominates(const MachineInstr *A, const MachineInstr *B) const
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.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
void setDelegate(Delegate *delegate)
Set the delegate.
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.
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
Analysis pass that exposes the MachineLoopInfo for a machine function.
MachineOperand class - Representation of each machine instruction operand.
void setSubReg(unsigned subReg)
unsigned getSubReg() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
MachineBasicBlock * getMBB() const
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
const uint32_t * getRegMask() const
getRegMask - Returns a bit mask of registers preserved by this RegMask operand.
unsigned getOperandNo() const
getOperandNo - Return the operand # of this MachineOperand in its MachineInstr.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
defusechain_iterator< false, true, false, true, false > def_iterator
def_iterator/def_begin/def_end - Walk all defs of the specified register.
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition PeepholeOptimizer.cpp:1671
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.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
bool erase(PtrType Ptr)
Remove pointer from the set.
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...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
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 push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
TargetInstrInfo - Interface to description of machine instruction set.
virtual MachineInstr * optimizeSelect(MachineInstr &MI, SmallPtrSetImpl< MachineInstr * > &NewMIs, bool PreferFalse=false) const
Given a select instruction that was understood by analyzeSelect and returned Optimizable = true,...
virtual bool findCommutedOpIndices(const MachineInstr &MI, unsigned &SrcOpIdx1, unsigned &SrcOpIdx2) const
Returns true iff the routine could find two commutable operands in the given machine instruction.
virtual MachineInstr * optimizeLoadInstr(MachineInstr &MI, const MachineRegisterInfo *MRI, Register &FoldAsLoadDefReg, MachineInstr *&DefMI) const
Try to remove the load by folding it to a register operand at the use.
virtual bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t Mask, int64_t Value, const MachineRegisterInfo *MRI) const
See if the comparison instruction can be converted into something more efficient.
virtual bool getConstValDefinedInReg(const MachineInstr &MI, const Register Reg, int64_t &ImmVal) const
Returns true if MI is an instruction that defines Reg to have a constant value and the value is recor...
virtual bool optimizeCondBranch(MachineInstr &MI) const
MachineInstr * commuteInstruction(MachineInstr &MI, bool NewMI=false, unsigned OpIdx1=CommuteAnyOperandIndex, unsigned OpIdx2=CommuteAnyOperandIndex) const
This method commutes the operands of the given machine instruction MI.
virtual bool foldImmediate(MachineInstr &UseMI, MachineInstr &DefMI, Register Reg, MachineRegisterInfo *MRI) const
'Reg' is known to be defined by a move immediate instruction, try to fold the immediate into the use ...
bool getInsertSubregInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPair &BaseReg, RegSubRegPairAndIdx &InsertedReg) const
Build the equivalent inputs of a INSERT_SUBREG for the given MI and DefIdx.
virtual bool analyzeSelect(const MachineInstr &MI, SmallVectorImpl< MachineOperand > &Cond, unsigned &TrueOp, unsigned &FalseOp, bool &Optimizable) const
Analyze the given select instruction, returning true if it cannot be understood.
bool getRegSequenceInputs(const MachineInstr &MI, unsigned DefIdx, SmallVectorImpl< RegSubRegPairAndIdx > &InputRegs) const
Build the equivalent inputs of a REG_SEQUENCE for the given MI and DefIdx.
static const unsigned CommuteAnyOperandIndex
bool getExtractSubregInputs(const MachineInstr &MI, unsigned DefIdx, RegSubRegPairAndIdx &InputReg) const
Build the equivalent inputs of a EXTRACT_SUBREG for the given MI and DefIdx.
virtual bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &Mask, int64_t &Value) const
For a comparison instruction, return the source registers in SrcReg and SrcReg2 if having two registe...
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MCInstrDesc const & getDesc(MCInstrInfo const &MCII, MCInst const &MCI)
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
NodeAddr< DefNode * > Def
BaseReg
Stack frame base register. Bit 0 of FREInfo.Info.
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
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
LLVM_ABI char & PeepholeOptimizerLegacyID
PeepholeOptimizer - This pass performs peephole optimizations - like extension and comparison elimina...
Definition PeepholeOptimizer.cpp:760
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
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...
LLVM_ABI void initializePeepholeOptimizerLegacyPass(PassRegistry &)
A pair composed of a pair of a register and a sub-register index, and another sub-register index.
A pair composed of a register and a sub-register index.