LLVM: lib/CodeGen/MachineCopyPropagation.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
75#include
76#include
77
78using namespace llvm;
79
80#define DEBUG_TYPE "machine-cp"
81
82STATISTIC(NumDeletes, "Number of dead copies deleted");
83STATISTIC(NumCopyForwards, "Number of copy uses forwarded");
84STATISTIC(NumCopyBackwardPropagated, "Number of copy defs backward propagated");
85STATISTIC(SpillageChainsLength, "Length of spillage chains");
86STATISTIC(NumSpillageChains, "Number of spillage chains");
88 "Controls which register COPYs are forwarded");
89
94
95namespace {
96
97static std::optional isCopyInstr(const MachineInstr &MI,
99 bool UseCopyInstr) {
100 if (UseCopyInstr)
101 return TII.isCopyInstr(MI);
102
103 if (MI.isCopy())
104 return std::optional(
106
107 return std::nullopt;
108}
109
110class CopyTracker {
111 struct CopyInfo {
112 MachineInstr *MI = nullptr;
113 MachineInstr *LastSeenUseInCopy = nullptr;
114 SmallPtrSet<MachineInstr *, 4> SrcUsers;
116 bool Avail = false;
117 };
118
119 DenseMap<MCRegUnit, CopyInfo> Copies;
120
121
122
123
124 DenseMap<const uint32_t *, BitVector> RegMaskToPreservedRegUnits;
125
126public:
127
128 BitVector &getPreservedRegUnits(const MachineOperand &RegMaskOp,
129 const TargetRegisterInfo &TRI) {
130 const uint32_t *RegMask = RegMaskOp.getRegMask();
131 auto [It, Inserted] = RegMaskToPreservedRegUnits.try_emplace(RegMask);
132 if (!Inserted) {
133 return It->second;
134 } else {
135 BitVector &PreservedRegUnits = It->second;
136
137 PreservedRegUnits.resize(TRI.getNumRegUnits());
138 for (unsigned SafeReg = 0, E = TRI.getNumRegs(); SafeReg < E; ++SafeReg)
140 for (MCRegUnit SafeUnit : TRI.regunits(SafeReg))
141 PreservedRegUnits.set(static_cast<unsigned>(SafeUnit));
142
143 return PreservedRegUnits;
144 }
145 }
146
147
148
150 const TargetRegisterInfo &TRI) {
151 for (MCRegister Reg : Regs) {
152
153 for (MCRegUnit Unit : TRI.regunits(Reg)) {
154 auto CI = Copies.find(Unit);
155 if (CI != Copies.end())
156 CI->second.Avail = false;
157 }
158 }
159 }
160
161
162 void invalidateRegister(MCRegister Reg, const TargetRegisterInfo &TRI,
163 const TargetInstrInfo &TII, bool UseCopyInstr) {
164
165
166
167
168 SmallSet<MCRegUnit, 8> RegUnitsToInvalidate;
169 auto InvalidateCopy = [&](MachineInstr *MI) {
170 std::optional CopyOperands =
171 isCopyInstr(*MI, TII, UseCopyInstr);
172 assert(CopyOperands && "Expect copy");
173
174 auto Dest = TRI.regunits(CopyOperands->Destination->getReg().asMCReg());
175 auto Src = TRI.regunits(CopyOperands->Source->getReg().asMCReg());
178 };
179
180 for (MCRegUnit Unit : TRI.regunits(Reg)) {
181 auto I = Copies.find(Unit);
182 if (I != Copies.end()) {
183 if (MachineInstr *MI = I->second.MI)
184 InvalidateCopy(MI);
185 if (MachineInstr *MI = I->second.LastSeenUseInCopy)
186 InvalidateCopy(MI);
187 }
188 }
189 for (MCRegUnit Unit : RegUnitsToInvalidate)
190 Copies.erase(Unit);
191 }
192
193
194 void clobberRegUnit(MCRegUnit Unit, const TargetRegisterInfo &TRI,
195 const TargetInstrInfo &TII, bool UseCopyInstr) {
196 auto I = Copies.find(Unit);
197 if (I != Copies.end()) {
198
199
200 markRegsUnavailable(I->second.DefRegs, TRI);
201
202
203 if (MachineInstr *MI = I->second.MI) {
204 std::optional CopyOperands =
205 isCopyInstr(*MI, TII, UseCopyInstr);
206
207 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
208 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
209
210 markRegsUnavailable(Def, TRI);
211
212
213
214
215
216
217
218
219
220
221
222
223
224 for (MCRegUnit SrcUnit : TRI.regunits(Src)) {
225 auto SrcCopy = Copies.find(SrcUnit);
226 if (SrcCopy != Copies.end() && SrcCopy->second.LastSeenUseInCopy) {
227
228
229 for (auto itr = SrcCopy->second.DefRegs.begin();
230 itr != SrcCopy->second.DefRegs.end(); itr++) {
231 if (*itr == Def) {
232 SrcCopy->second.DefRegs.erase(itr);
233
234
235
236
237
238 if (SrcCopy->second.DefRegs.empty() && !SrcCopy->second.MI) {
239 Copies.erase(SrcCopy);
240 }
241 break;
242 }
243 }
244 }
245 }
246 }
247
248 Copies.erase(I);
249 }
250 }
251
252
253 void clobberRegister(MCRegister Reg, const TargetRegisterInfo &TRI,
254 const TargetInstrInfo &TII, bool UseCopyInstr) {
255 for (MCRegUnit Unit : TRI.regunits(Reg)) {
256 clobberRegUnit(Unit, TRI, TII, UseCopyInstr);
257 }
258 }
259
260
261
262
263 bool trackSrcUsers(MCRegister Reg, MachineInstr &MI,
264 const TargetRegisterInfo &TRI, const TargetInstrInfo &TII,
265 bool UseCopyInstr) {
266 MCRegUnit RU = *TRI.regunits(Reg).begin();
267 MachineInstr *AvailCopy = findCopyDefViaUnit(RU, TRI);
268 if (!AvailCopy)
269 return false;
270
271 std::optional CopyOperands =
272 isCopyInstr(*AvailCopy, TII, UseCopyInstr);
273 Register Src = CopyOperands->Source->getReg();
274
275
276 if (Src != Reg)
277 return false;
278
279 auto I = Copies.find(RU);
280 if (I == Copies.end())
281 return false;
282
283 I->second.SrcUsers.insert(&MI);
284 return true;
285 }
286
287
288 SmallPtrSet<MachineInstr *, 4> getSrcUsers(MCRegister Reg,
289 const TargetRegisterInfo &TRI) {
290 MCRegUnit RU = *TRI.regunits(Reg).begin();
291 auto I = Copies.find(RU);
292 if (I == Copies.end())
293 return {};
294 return I->second.SrcUsers;
295 }
296
297
298 void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI,
299 const TargetInstrInfo &TII, bool UseCopyInstr) {
300 std::optional CopyOperands =
301 isCopyInstr(*MI, TII, UseCopyInstr);
302 assert(CopyOperands && "Tracking non-copy?");
303
304 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
305 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
306
307
308 for (MCRegUnit Unit : TRI.regunits(Def))
309 Copies[Unit] = {MI, nullptr, {}, {}, true};
310
311
312
313 for (MCRegUnit Unit : TRI.regunits(Src)) {
316 Copy.DefRegs.push_back(Def);
317 Copy.LastSeenUseInCopy = MI;
318 }
319 }
320
321 bool hasAnyCopies() {
322 return !Copies.empty();
323 }
324
325 MachineInstr *findCopyForUnit(MCRegUnit RegUnit,
326 const TargetRegisterInfo &TRI,
327 bool MustBeAvailable = false) {
328 auto CI = Copies.find(RegUnit);
329 if (CI == Copies.end())
330 return nullptr;
331 if (MustBeAvailable && !CI->second.Avail)
332 return nullptr;
333 return CI->second.MI;
334 }
335
336 MachineInstr *findCopyDefViaUnit(MCRegUnit RegUnit,
337 const TargetRegisterInfo &TRI) {
338 auto CI = Copies.find(RegUnit);
339 if (CI == Copies.end())
340 return nullptr;
341 if (CI->second.DefRegs.size() != 1)
342 return nullptr;
343 MCRegUnit RU = *TRI.regunits(CI->second.DefRegs[0]).begin();
344 return findCopyForUnit(RU, TRI, true);
345 }
346
347 MachineInstr *findAvailBackwardCopy(MachineInstr &I, MCRegister Reg,
348 const TargetRegisterInfo &TRI,
349 const TargetInstrInfo &TII,
350 bool UseCopyInstr) {
351 MCRegUnit RU = *TRI.regunits(Reg).begin();
352 MachineInstr *AvailCopy = findCopyDefViaUnit(RU, TRI);
353
354 if (!AvailCopy)
355 return nullptr;
356
357 std::optional CopyOperands =
358 isCopyInstr(*AvailCopy, TII, UseCopyInstr);
359 Register AvailSrc = CopyOperands->Source->getReg();
360 Register AvailDef = CopyOperands->Destination->getReg();
361 if (.isSubRegisterEq(AvailSrc, Reg))
362 return nullptr;
363
364 for (const MachineInstr &MI :
366 for (const MachineOperand &MO : MI.operands())
367 if (MO.isRegMask())
368
369 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
370 return nullptr;
371
372 return AvailCopy;
373 }
374
375 MachineInstr *findAvailCopy(MachineInstr &DestCopy, MCRegister Reg,
376 const TargetRegisterInfo &TRI,
377 const TargetInstrInfo &TII, bool UseCopyInstr) {
378
379
380 MCRegUnit RU = *TRI.regunits(Reg).begin();
381 MachineInstr *AvailCopy =
382 findCopyForUnit(RU, TRI, true);
383
384 if (!AvailCopy)
385 return nullptr;
386
387 std::optional CopyOperands =
388 isCopyInstr(*AvailCopy, TII, UseCopyInstr);
389 Register AvailSrc = CopyOperands->Source->getReg();
390 Register AvailDef = CopyOperands->Destination->getReg();
391 if (.isSubRegisterEq(AvailDef, Reg))
392 return nullptr;
393
394
395
396 for (const MachineInstr &MI :
398 for (const MachineOperand &MO : MI.operands())
399 if (MO.isRegMask())
400 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
401 return nullptr;
402
403 return AvailCopy;
404 }
405
406
407 MachineInstr *findLastSeenDefInCopy(const MachineInstr &Current,
408 MCRegister Reg,
409 const TargetRegisterInfo &TRI,
410 const TargetInstrInfo &TII,
411 bool UseCopyInstr) {
412 MCRegUnit RU = *TRI.regunits(Reg).begin();
413 auto CI = Copies.find(RU);
414 if (CI == Copies.end() || !CI->second.Avail)
415 return nullptr;
416
417 MachineInstr *DefCopy = CI->second.MI;
418 std::optional CopyOperands =
419 isCopyInstr(*DefCopy, TII, UseCopyInstr);
420 Register Def = CopyOperands->Destination->getReg();
421 if (.isSubRegisterEq(Def, Reg))
422 return nullptr;
423
424 for (const MachineInstr &MI :
425 make_range(static_cast<const MachineInstr *>(DefCopy)->getIterator(),
427 for (const MachineOperand &MO : MI.operands())
428 if (MO.isRegMask())
429 if (MO.clobbersPhysReg(Def)) {
432 return nullptr;
433 }
434
435 return DefCopy;
436 }
437
438
439 MachineInstr *findLastSeenUseInCopy(MCRegister Reg,
440 const TargetRegisterInfo &TRI) {
441 MCRegUnit RU = *TRI.regunits(Reg).begin();
442 auto CI = Copies.find(RU);
443 if (CI == Copies.end())
444 return nullptr;
445 return CI->second.LastSeenUseInCopy;
446 }
447
448 void clear() {
449 Copies.clear();
450 }
451};
452
453class MachineCopyPropagation {
454 const TargetRegisterInfo *TRI = nullptr;
455 const TargetInstrInfo *TII = nullptr;
456 const MachineRegisterInfo *MRI = nullptr;
457
458
459 bool UseCopyInstr;
460
461public:
462 MachineCopyPropagation(bool CopyInstr = false)
464
465 bool run(MachineFunction &MF);
466
467private:
468 typedef enum { DebugUse = false, RegularUse = true } DebugType;
469
470 void ReadRegister(MCRegister Reg, MachineInstr &Reader, DebugType DT);
471 void readSuccessorLiveIns(const MachineBasicBlock &MBB);
472 void ForwardCopyPropagateBlock(MachineBasicBlock &MBB);
473 void BackwardCopyPropagateBlock(MachineBasicBlock &MBB);
474 void EliminateSpillageCopies(MachineBasicBlock &MBB);
475 bool eraseIfRedundant(MachineInstr &Copy, MCRegister Src, MCRegister Def);
476 void forwardUses(MachineInstr &MI);
477 void propagateDefs(MachineInstr &MI);
478 bool isForwardableRegClassCopy(const MachineInstr &Copy,
479 const MachineInstr &UseI, unsigned UseIdx);
480 bool isBackwardPropagatableRegClassCopy(const MachineInstr &Copy,
481 const MachineInstr &UseI,
482 unsigned UseIdx);
483 bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use);
484 bool hasOverlappingMultipleDef(const MachineInstr &MI,
485 const MachineOperand &MODef, Register Def);
486 bool canUpdateSrcUsers(const MachineInstr &Copy,
487 const MachineOperand &CopySrc);
488
489
490 SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
491
492
493 DenseMap<MachineInstr *, SmallPtrSet<MachineInstr *, 2>> CopyDbgUsers;
494
495 CopyTracker Tracker;
496
497 bool Changed = false;
498};
499
501 bool UseCopyInstr;
502
503public:
504 static char ID;
505
506 MachineCopyPropagationLegacy(bool UseCopyInstr = false)
507 : MachineFunctionPass(ID), UseCopyInstr(UseCopyInstr) {}
508
509 void getAnalysisUsage(AnalysisUsage &AU) const override {
512 }
513
514 bool runOnMachineFunction(MachineFunction &MF) override;
515
516 MachineFunctionProperties getRequiredProperties() const override {
517 return MachineFunctionProperties().setNoVRegs();
518 }
519};
520
521}
522
523char MachineCopyPropagationLegacy::ID = 0;
524
526
528 "Machine Copy Propagation Pass", false, false)
529
531 DebugType DT) {
532
533
534
535 for (MCRegUnit Unit : TRI->regunits(Reg)) {
536 if (MachineInstr *Copy = Tracker.findCopyForUnit(Unit, *TRI)) {
537 if (DT == RegularUse) {
538 LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; Copy->dump());
539 MaybeDeadCopies.remove(Copy);
540 } else {
541 CopyDbgUsers[Copy].insert(&Reader);
542 }
543 }
544 }
545}
546
547void MachineCopyPropagation::readSuccessorLiveIns(
549 if (MaybeDeadCopies.empty())
550 return;
551
552
553 for (const MachineBasicBlock *Succ : MBB.successors()) {
554 for (const auto &LI : Succ->liveins()) {
555 for (MCRegUnitMaskIterator U(LI.PhysReg, TRI); U.isValid(); ++U) {
557 if ((Mask & LI.LaneMask).any()) {
558 if (MachineInstr *Copy = Tracker.findCopyForUnit(Unit, *TRI))
559 MaybeDeadCopies.remove(Copy);
560 }
561 }
562 }
563 }
564}
565
566
567
568
569
570
571
575
576 std::optional CopyOperands =
577 isCopyInstr(PreviousCopy, *TII, UseCopyInstr);
578 MCRegister PreviousSrc = CopyOperands->Source->getReg().asMCReg();
579 MCRegister PreviousDef = CopyOperands->Destination->getReg().asMCReg();
580 if (Src == PreviousSrc && Def == PreviousDef)
581 return true;
582 if (->isSubRegister(PreviousSrc, Src))
583 return false;
584 unsigned SubIdx = TRI->getSubRegIndex(PreviousSrc, Src);
585 return SubIdx == TRI->getSubRegIndex(PreviousDef, Def);
586}
587
588
589
590
591bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy,
592 MCRegister Src, MCRegister Def) {
593
594
595 if (MRI->isReserved(Src) || MRI->isReserved(Def))
596 return false;
597
598
599 MachineInstr *PrevCopy =
600 Tracker.findAvailCopy(Copy, Def, *TRI, *TII, UseCopyInstr);
601 if (!PrevCopy)
602 return false;
603
604 auto PrevCopyOperands = isCopyInstr(*PrevCopy, *TII, UseCopyInstr);
605
606 if (PrevCopyOperands->Destination->isDead())
607 return false;
608 if ((*PrevCopy, Src, Def, TRI, TII, UseCopyInstr))
609 return false;
610
612
613
614
615 std::optional CopyOperands =
616 isCopyInstr(Copy, *TII, UseCopyInstr);
617 assert(CopyOperands);
618
619 Register CopyDef = CopyOperands->Destination->getReg();
620 assert(CopyDef == Src || CopyDef == Def);
621 for (MachineInstr &MI :
623 MI.clearRegisterKills(CopyDef, TRI);
624
625
626 if (!CopyOperands->Source->isUndef()) {
627 PrevCopy->getOperand(PrevCopyOperands->Source->getOperandNo())
629 }
630
631 Copy.eraseFromParent();
633 ++NumDeletes;
634 return true;
635}
636
637bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy(
638 const MachineInstr &Copy, const MachineInstr &UseI, unsigned UseIdx) {
639 std::optional CopyOperands =
640 isCopyInstr(Copy, *TII, UseCopyInstr);
641 Register Def = CopyOperands->Destination->getReg();
642
643 if (const TargetRegisterClass *URC =
645 return URC->contains(Def);
646
647
648
649 return false;
650}
651
652
653
654
655bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy,
656 const MachineInstr &UseI,
657 unsigned UseIdx) {
658 std::optional CopyOperands =
659 isCopyInstr(Copy, *TII, UseCopyInstr);
660 Register CopySrcReg = CopyOperands->Source->getReg();
661
662
663
664 if (const TargetRegisterClass *URC =
666 return URC->contains(CopySrcReg);
667
668 auto UseICopyOperands = isCopyInstr(UseI, *TII, UseCopyInstr);
669 if (!UseICopyOperands)
670 return false;
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692 Register UseDstReg = UseICopyOperands->Destination->getReg();
693 bool Found = false;
694 bool IsCrossClass = false;
695 for (const TargetRegisterClass *RC : TRI->regclasses()) {
696 if (RC->contains(CopySrcReg) && RC->contains(UseDstReg)) {
697 Found = true;
698 if (TRI->getCrossCopyRegClass(RC) != RC) {
699 IsCrossClass = true;
700 break;
701 }
702 }
703 }
704 if (!Found)
705 return false;
706 if (!IsCrossClass)
707 return true;
708
709
710 Register CopyDstReg = CopyOperands->Destination->getReg();
711 for (const TargetRegisterClass *RC : TRI->regclasses()) {
712 if (RC->contains(CopySrcReg) && RC->contains(CopyDstReg) &&
713 TRI->getCrossCopyRegClass(RC) != RC)
714 return true;
715 }
716 return false;
717}
718
719
720
721
722
723
724
725
726
727bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI,
728 const MachineOperand &Use) {
729 for (const MachineOperand &MIUse : MI.uses())
730 if (&MIUse != &Use && MIUse.isReg() && MIUse.isImplicit() &&
731 MIUse.isUse() && TRI->regsOverlap(Use.getReg(), MIUse.getReg()))
732 return true;
733
734 return false;
735}
736
737
738
739
740
741bool MachineCopyPropagation::hasOverlappingMultipleDef(
742 const MachineInstr &MI, const MachineOperand &MODef, Register Def) {
743 for (const MachineOperand &MIDef : MI.all_defs()) {
744 if ((&MIDef != &MODef) && MIDef.isReg() &&
745 TRI->regsOverlap(Def, MIDef.getReg()))
746 return true;
747 }
748
749 return false;
750}
751
752
753
754bool MachineCopyPropagation::canUpdateSrcUsers(const MachineInstr &Copy,
755 const MachineOperand &CopySrc) {
756 assert(CopySrc.isReg() && "Expected a register operand");
757 for (auto *SrcUser : Tracker.getSrcUsers(CopySrc.getReg(), *TRI)) {
758 if (hasImplicitOverlap(*SrcUser, CopySrc))
759 return false;
760
761 for (MachineOperand &MO : SrcUser->uses()) {
762 if (!MO.isReg() || !MO.isUse() || MO.getReg() != CopySrc.getReg())
763 continue;
764 if (MO.isTied() || !MO.isRenamable() ||
765 !isBackwardPropagatableRegClassCopy(Copy, *SrcUser,
766 MO.getOperandNo()))
767 return false;
768 }
769 }
770 return true;
771}
772
773
774
775void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
776 if (!Tracker.hasAnyCopies())
777 return;
778
779
780
781
782 for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx < OpEnd;
784 MachineOperand &MOUse = MI.getOperand(OpIdx);
785
786
787
788
789
792 continue;
793
795 continue;
796
797
798
799
801 continue;
802
804 *TRI, *TII, UseCopyInstr);
805 if (!Copy)
806 continue;
807
808 std::optional CopyOperands =
809 isCopyInstr(*Copy, *TII, UseCopyInstr);
810 Register CopyDstReg = CopyOperands->Destination->getReg();
811 const MachineOperand &CopySrc = *CopyOperands->Source;
813
814 Register ForwardedReg = CopySrcReg;
815
816
817 if (MOUse.getReg() != CopyDstReg) {
818 unsigned SubRegIdx = TRI->getSubRegIndex(CopyDstReg, MOUse.getReg());
820 "MI source is not a sub-register of Copy destination");
821 ForwardedReg = TRI->getSubReg(CopySrcReg, SubRegIdx);
822 if (!ForwardedReg) {
823 LLVM_DEBUG(dbgs() << "MCP: Copy source does not have sub-register "
824 << TRI->getSubRegIndexName(SubRegIdx) << '\n');
825 continue;
826 }
827 }
828
829
830 if (MRI->isReserved(CopySrcReg) && ->isConstantPhysReg(CopySrcReg))
831 continue;
832
833 if (!isForwardableRegClassCopy(*Copy, MI, OpIdx))
834 continue;
835
836 if (hasImplicitOverlap(MI, MOUse))
837 continue;
838
839
840
841
842 if (isCopyInstr(MI, *TII, UseCopyInstr) &&
843 MI.modifiesRegister(CopySrcReg, TRI) &&
844 .definesRegister(CopySrcReg, nullptr)) {
845 LLVM_DEBUG(dbgs() << "MCP: Copy source overlap with dest in " << MI);
846 continue;
847 }
848
850 LLVM_DEBUG(dbgs() << "MCP: Skipping forwarding due to debug counter:\n "
851 << MI);
852 continue;
853 }
854
856 << "\n with " << printReg(ForwardedReg, TRI)
857 << "\n in " << MI << " from " << *Copy);
858
859 MOUse.setReg(ForwardedReg);
860
864
865 LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
866
867
868 for (MachineInstr &KMI :
869 make_range(Copy->getIterator(), std::next(MI.getIterator())))
870 KMI.clearRegisterKills(CopySrcReg, TRI);
871
872 ++NumCopyForwards;
874 }
875}
876
877void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
879 << "\n");
880
882
883 std::optional CopyOperands =
884 isCopyInstr(MI, *TII, UseCopyInstr);
885 if (CopyOperands) {
886 Register RegSrc = CopyOperands->Source->getReg();
887 Register RegDef = CopyOperands->Destination->getReg();
888 if (->regsOverlap(RegDef, RegSrc)) {
890 "MachineCopyPropagation should be run after register allocation!");
891
893 MCRegister Src = RegSrc.asMCReg();
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910 if (eraseIfRedundant(MI, Def, Src) || eraseIfRedundant(MI, Src, Def))
911 continue;
912 }
913 }
914
915
916 for (const MachineOperand &MO : MI.operands())
917 if (MO.isReg() && MO.isEarlyClobber()) {
918 MCRegister Reg = MO.getReg().asMCReg();
919
920
921
922 if (MO.isTied())
923 ReadRegister(Reg, MI, RegularUse);
924 Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
925 }
926
927 forwardUses(MI);
928
929
930
933 LLVM_DEBUG(dbgs() << "MCP: After simplifyInstruction: " << MI);
934 }
935
936 CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr);
937 if (CopyOperands) {
938 Register RegSrc = CopyOperands->Source->getReg();
939 Register RegDef = CopyOperands->Destination->getReg();
940
941 if (->regsOverlap(RegDef, RegSrc)) {
942
944 if (->isReserved(Def))
945 MaybeDeadCopies.insert(&MI);
946 }
947 }
948
950 const MachineOperand *RegMask = nullptr;
951 for (const MachineOperand &MO : MI.operands()) {
952 if (MO.isRegMask())
953 RegMask = &MO;
954 if (!MO.isReg())
955 continue;
957 if ()
958 continue;
959
961 "MachineCopyPropagation should be run after register allocation!");
962
963 if (MO.isDef() && !MO.isEarlyClobber()) {
964
965 if (->isConstantPhysReg(Reg)) {
967 continue;
968 }
969 } else if (MO.readsReg())
970 ReadRegister(Reg.asMCReg(), MI, MO.isDebug() ? DebugUse : RegularUse);
971 }
972
973
974
975
976 if (RegMask) {
977 BitVector &PreservedRegUnits =
978 Tracker.getPreservedRegUnits(*RegMask, *TRI);
979
980
981 for (SmallSetVector<MachineInstr *, 8>::iterator DI =
982 MaybeDeadCopies.begin();
983 DI != MaybeDeadCopies.end();) {
984 MachineInstr *MaybeDead = *DI;
985 std::optional CopyOperands =
986 isCopyInstr(*MaybeDead, *TII, UseCopyInstr);
987 MCRegister Reg = CopyOperands->Destination->getReg().asMCReg();
989
991 ++DI;
992 continue;
993 }
994
995
996
997 bool MIRefedinCopyInfo = false;
998 for (MCRegUnit RegUnit : TRI->regunits(Reg)) {
999 if (!PreservedRegUnits.test(static_cast<unsigned>(RegUnit)))
1000 Tracker.clobberRegUnit(RegUnit, *TRI, *TII, UseCopyInstr);
1001 else {
1002 if (MaybeDead == Tracker.findCopyForUnit(RegUnit, *TRI)) {
1003 MIRefedinCopyInfo = true;
1004 }
1005 }
1006 }
1007
1008
1009
1010 DI = MaybeDeadCopies.erase(DI);
1011
1012
1013 if (MIRefedinCopyInfo)
1014 continue;
1015
1016 LLVM_DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: "
1017 << *MaybeDead);
1018
1021 ++NumDeletes;
1022 }
1023 }
1024
1025
1026 for (MCRegister Reg : Defs)
1027 Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
1028
1029 if (CopyOperands) {
1030 Register RegSrc = CopyOperands->Source->getReg();
1031 Register RegDef = CopyOperands->Destination->getReg();
1032 if (->regsOverlap(RegDef, RegSrc)) {
1033 Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr);
1034 }
1035 }
1036 }
1037
1038 bool TracksLiveness = MRI->tracksLiveness();
1039
1040
1041
1042 if (TracksLiveness)
1043 readSuccessorLiveIns(MBB);
1044
1045
1046
1047
1049 for (MachineInstr *MaybeDead : MaybeDeadCopies) {
1050 LLVM_DEBUG(dbgs() << "MCP: Removing copy due to no live-out succ: ";
1051 MaybeDead->dump());
1052
1053 std::optional CopyOperands =
1054 isCopyInstr(*MaybeDead, *TII, UseCopyInstr);
1055 assert(CopyOperands);
1056
1057 Register SrcReg = CopyOperands->Source->getReg();
1058 Register DestReg = CopyOperands->Destination->getReg();
1059 assert(->isReserved(DestReg));
1060
1061
1062 const auto &DbgUsers = CopyDbgUsers[MaybeDead];
1064 DbgUsers.end());
1066 MaybeDeadDbgUsers);
1067
1070 ++NumDeletes;
1071 }
1072 }
1073
1074 MaybeDeadCopies.clear();
1075 CopyDbgUsers.clear();
1076 Tracker.clear();
1077}
1078
1083
1084 if (!Def || !Src)
1085 return false;
1086
1087 if (MRI.isReserved(Def) || MRI.isReserved(Src))
1088 return false;
1089
1091}
1092
1093void MachineCopyPropagation::propagateDefs(MachineInstr &MI) {
1094 if (!Tracker.hasAnyCopies())
1095 return;
1096
1097 for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx != OpEnd;
1099 MachineOperand &MODef = MI.getOperand(OpIdx);
1100
1101 if (!MODef.isReg() || MODef.isUse())
1102 continue;
1103
1104
1106 continue;
1107
1108 if (!MODef.getReg())
1109 continue;
1110
1111
1113 continue;
1114
1115 MachineInstr *Copy = Tracker.findAvailBackwardCopy(
1117 if (!Copy)
1118 continue;
1119
1120 std::optional CopyOperands =
1121 isCopyInstr(*Copy, *TII, UseCopyInstr);
1122 Register Def = CopyOperands->Destination->getReg();
1123 Register Src = CopyOperands->Source->getReg();
1124
1125 if (MODef.getReg() != Src)
1126 continue;
1127
1128 if (!isBackwardPropagatableRegClassCopy(*Copy, MI, OpIdx))
1129 continue;
1130
1131 if (hasImplicitOverlap(MI, MODef))
1132 continue;
1133
1134 if (hasOverlappingMultipleDef(MI, MODef, Def))
1135 continue;
1136
1137 if (!canUpdateSrcUsers(*Copy, *CopyOperands->Source))
1138 continue;
1139
1141 << "\n with " << printReg(Def, TRI) << "\n in "
1142 << MI << " from " << *Copy);
1143
1145 MODef.setIsRenamable(CopyOperands->Destination->isRenamable());
1146
1147 for (auto *SrcUser : Tracker.getSrcUsers(Src, *TRI)) {
1148 for (MachineOperand &MO : SrcUser->uses()) {
1149 if (!MO.isReg() || !MO.isUse() || MO.getReg() != Src)
1150 continue;
1151 MO.setReg(Def);
1152 MO.setIsRenamable(CopyOperands->Destination->isRenamable());
1153 }
1154 }
1155
1156 LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
1157 MaybeDeadCopies.insert(Copy);
1159 ++NumCopyBackwardPropagated;
1160 }
1161}
1162
1163void MachineCopyPropagation::BackwardCopyPropagateBlock(
1164 MachineBasicBlock &MBB) {
1166 << "\n");
1167
1169
1170 std::optional CopyOperands =
1171 isCopyInstr(MI, *TII, UseCopyInstr);
1172 if (CopyOperands && MI.getNumImplicitOperands() == 0) {
1173 Register DefReg = CopyOperands->Destination->getReg();
1174 Register SrcReg = CopyOperands->Source->getReg();
1175
1176 if (->regsOverlap(DefReg, SrcReg)) {
1177
1178
1180 Tracker.invalidateRegister(SrcReg.asMCReg(), *TRI, *TII,
1181 UseCopyInstr);
1182 Tracker.invalidateRegister(DefReg.asMCReg(), *TRI, *TII,
1183 UseCopyInstr);
1184 Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr);
1185 continue;
1186 }
1187 }
1188 }
1189
1190
1191 for (const MachineOperand &MO : MI.operands())
1192 if (MO.isReg() && MO.isEarlyClobber()) {
1193 MCRegister Reg = MO.getReg().asMCReg();
1194 if ()
1195 continue;
1196 Tracker.invalidateRegister(Reg, *TRI, *TII, UseCopyInstr);
1197 }
1198
1199 propagateDefs(MI);
1200 for (const MachineOperand &MO : MI.operands()) {
1201 if (!MO.isReg())
1202 continue;
1203
1204 if (!MO.getReg())
1205 continue;
1206
1207 if (MO.isDef())
1208 Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII,
1209 UseCopyInstr);
1210
1211 if (MO.readsReg()) {
1212 if (MO.isDebug()) {
1213
1214
1215
1216 for (MCRegUnit Unit : TRI->regunits(MO.getReg().asMCReg())) {
1217 if (auto *Copy = Tracker.findCopyDefViaUnit(Unit, *TRI)) {
1218 CopyDbgUsers[Copy].insert(&MI);
1219 }
1220 }
1221 } else if (!Tracker.trackSrcUsers(MO.getReg().asMCReg(), MI, *TRI, *TII,
1222 UseCopyInstr)) {
1223
1224 Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII,
1225 UseCopyInstr);
1226 }
1227 }
1228 }
1229 }
1230
1231 for (auto *Copy : MaybeDeadCopies) {
1232 std::optional CopyOperands =
1233 isCopyInstr(*Copy, *TII, UseCopyInstr);
1234 Register Src = CopyOperands->Source->getReg();
1235 Register Def = CopyOperands->Destination->getReg();
1236 const auto &DbgUsers = CopyDbgUsers[Copy];
1238 DbgUsers.end());
1239
1240 MRI->updateDbgUsersToReg(Src.asMCReg(), Def.asMCReg(), MaybeDeadDbgUsers);
1241 Copy->eraseFromParent();
1242 ++NumDeletes;
1243 }
1244
1245 MaybeDeadCopies.clear();
1246 CopyDbgUsers.clear();
1247 Tracker.clear();
1248}
1249
1254 auto &SC = SpillChain[Leader];
1255 auto &RC = ReloadChain[Leader];
1256 for (auto I = SC.rbegin(), E = SC.rend(); I != E; ++I)
1257 (*I)->dump();
1259 MI->dump();
1260}
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300void MachineCopyPropagation::EliminateSpillageCopies(MachineBasicBlock &MBB) {
1301
1302
1303 DenseMap<MachineInstr *, MachineInstr *> ChainLeader;
1304
1305
1306
1307
1308 DenseMap<MachineInstr *, SmallVector<MachineInstr *>> SpillChain, ReloadChain;
1309
1310
1311 DenseSet<const MachineInstr *> CopySourceInvalid;
1312
1313 auto TryFoldSpillageCopies =
1314 [&, this](const SmallVectorImpl<MachineInstr *> &SC,
1315 const SmallVectorImpl<MachineInstr *> &RC) {
1316 assert(SC.size() == RC.size() && "Spill-reload should be paired");
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327 if (SC.size() <= 2)
1328 return;
1329
1330
1331 for (const MachineInstr *Spill : drop_begin(SC))
1332 if (CopySourceInvalid.count(Spill))
1333 return;
1334
1335 for (const MachineInstr *Reload : drop_end(RC))
1336 if (CopySourceInvalid.count(Reload))
1337 return;
1338
1340 for (const TargetRegisterClass *RC : TRI->regclasses()) {
1341 if (RC->contains(Def) && RC->contains(Src))
1342 return true;
1343 }
1344 return false;
1345 };
1346
1347 auto UpdateReg = [](MachineInstr *MI, const MachineOperand *Old,
1348 const MachineOperand *New) {
1349 for (MachineOperand &MO : MI->operands()) {
1350 if (&MO == Old)
1351 MO.setReg(New->getReg());
1352 }
1353 };
1354
1355 std::optional InnerMostSpillCopy =
1356 isCopyInstr(*SC[0], *TII, UseCopyInstr);
1357 std::optional OuterMostSpillCopy =
1358 isCopyInstr(*SC.back(), *TII, UseCopyInstr);
1359 std::optional InnerMostReloadCopy =
1360 isCopyInstr(*RC[0], *TII, UseCopyInstr);
1361 std::optional OuterMostReloadCopy =
1362 isCopyInstr(*RC.back(), *TII, UseCopyInstr);
1363 if (!CheckCopyConstraint(OuterMostSpillCopy->Source->getReg(),
1364 InnerMostSpillCopy->Source->getReg()) ||
1365 !CheckCopyConstraint(InnerMostReloadCopy->Destination->getReg(),
1366 OuterMostReloadCopy->Destination->getReg()))
1367 return;
1368
1369 SpillageChainsLength += SC.size() + RC.size();
1370 NumSpillageChains += 1;
1371 UpdateReg(SC[0], InnerMostSpillCopy->Destination,
1372 OuterMostSpillCopy->Source);
1373 UpdateReg(RC[0], InnerMostReloadCopy->Source,
1374 OuterMostReloadCopy->Destination);
1375
1376 for (size_t I = 1; I < SC.size() - 1; ++I) {
1377 SC[I]->eraseFromParent();
1378 RC[I]->eraseFromParent();
1379 NumDeletes += 2;
1380 }
1381 };
1382
1383 auto IsFoldableCopy = [this](const MachineInstr &MaybeCopy) {
1384 if (MaybeCopy.getNumImplicitOperands() > 0)
1385 return false;
1386 std::optional CopyOperands =
1387 isCopyInstr(MaybeCopy, *TII, UseCopyInstr);
1388 if (!CopyOperands)
1389 return false;
1390 Register Src = CopyOperands->Source->getReg();
1391 Register Def = CopyOperands->Destination->getReg();
1392 return Src && Def && ->regsOverlap(Src, Def) &&
1393 CopyOperands->Source->isRenamable() &&
1394 CopyOperands->Destination->isRenamable();
1395 };
1396
1397 auto IsSpillReloadPair = [&, this](const MachineInstr &Spill,
1398 const MachineInstr &Reload) {
1399 if (!IsFoldableCopy(Spill) || !IsFoldableCopy(Reload))
1400 return false;
1401 std::optional SpillCopy =
1402 isCopyInstr(Spill, *TII, UseCopyInstr);
1403 std::optional ReloadCopy =
1404 isCopyInstr(Reload, *TII, UseCopyInstr);
1405 if (!SpillCopy || !ReloadCopy)
1406 return false;
1407 return SpillCopy->Source->getReg() == ReloadCopy->Destination->getReg() &&
1408 SpillCopy->Destination->getReg() == ReloadCopy->Source->getReg();
1409 };
1410
1411 auto IsChainedCopy = [&, this](const MachineInstr &Prev,
1412 const MachineInstr &Current) {
1413 if (!IsFoldableCopy(Prev) || !IsFoldableCopy(Current))
1414 return false;
1415 std::optional PrevCopy =
1416 isCopyInstr(Prev, *TII, UseCopyInstr);
1417 std::optional CurrentCopy =
1418 isCopyInstr(Current, *TII, UseCopyInstr);
1419 if (!PrevCopy || !CurrentCopy)
1420 return false;
1421 return PrevCopy->Source->getReg() == CurrentCopy->Destination->getReg();
1422 };
1423
1425 std::optional CopyOperands =
1426 isCopyInstr(MI, *TII, UseCopyInstr);
1427
1428
1429 SmallSet<Register, 8> RegsToClobber;
1430 if (!CopyOperands) {
1431 for (const MachineOperand &MO : MI.operands()) {
1432 if (!MO.isReg())
1433 continue;
1435 if ()
1436 continue;
1437 MachineInstr *LastUseCopy =
1438 Tracker.findLastSeenUseInCopy(Reg.asMCReg(), *TRI);
1439 if (LastUseCopy) {
1444 CopySourceInvalid.insert(LastUseCopy);
1445 }
1446
1447
1448
1449
1450
1451
1453 UseCopyInstr))
1454
1456 }
1458 Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
1460 << "\n");
1461 }
1462 continue;
1463 }
1464
1465 Register Src = CopyOperands->Source->getReg();
1466 Register Def = CopyOperands->Destination->getReg();
1467
1468 LLVM_DEBUG(dbgs() << "MCP: Searching paired spill for reload: ");
1470 MachineInstr *MaybeSpill =
1471 Tracker.findLastSeenDefInCopy(MI, Src.asMCReg(), *TRI, *TII, UseCopyInstr);
1472 bool MaybeSpillIsChained = ChainLeader.count(MaybeSpill);
1473 if (!MaybeSpillIsChained && MaybeSpill &&
1474 IsSpillReloadPair(*MaybeSpill, MI)) {
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1509 MachineInstr *MaybePrevReload =
1510 Tracker.findLastSeenUseInCopy(Def.asMCReg(), *TRI);
1511 auto Leader = ChainLeader.find(MaybePrevReload);
1512 MachineInstr *L = nullptr;
1513 if (Leader == ChainLeader.end() ||
1514 (MaybePrevReload && !IsChainedCopy(*MaybePrevReload, MI))) {
1517 "SpillChain should not have contained newly found chain");
1518 } else {
1519 assert(MaybePrevReload &&
1520 "Found a valid leader through nullptr should not happend");
1521 L = Leader->second;
1523 "Existing chain's length should be larger than zero");
1524 }
1526 "Newly found paired spill-reload should not belong to any chain "
1527 "at this point");
1528 ChainLeader.insert({MaybeSpill, L});
1530 SpillChain[L].push_back(MaybeSpill);
1531 ReloadChain[L].push_back(&MI);
1532 LLVM_DEBUG(dbgs() << "MCP: Chain " << L << " now is:\n");
1534 } else if (MaybeSpill && !MaybeSpillIsChained) {
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548 LLVM_DEBUG(dbgs() << "MCP: Not paired spill-reload:\n");
1551 Tracker.clobberRegister(Src.asMCReg(), *TRI, *TII, UseCopyInstr);
1553 << "\n");
1554 }
1555 Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr);
1556 }
1557
1558 for (auto I = SpillChain.begin(), E = SpillChain.end(); I != E; ++I) {
1559 auto &SC = I->second;
1561 "Reload chain of the same leader should exist");
1562 auto &RC = ReloadChain[I->first];
1563 TryFoldSpillageCopies(SC, RC);
1564 }
1565
1566 MaybeDeadCopies.clear();
1567 CopyDbgUsers.clear();
1568 Tracker.clear();
1569}
1570
1571bool MachineCopyPropagationLegacy::runOnMachineFunction(MachineFunction &MF) {
1573 return false;
1574
1575 return MachineCopyPropagation(UseCopyInstr).run(MF);
1576}
1577
1578PreservedAnalyses
1582 if (!MachineCopyPropagation(UseCopyInstr).run(MF))
1586 return PA;
1587}
1588
1590 bool isSpillageCopyElimEnabled = false;
1593 isSpillageCopyElimEnabled =
1595 break;
1597 isSpillageCopyElimEnabled = true;
1598 break;
1600 isSpillageCopyElimEnabled = false;
1601 break;
1602 }
1603
1605
1609
1611 if (isSpillageCopyElimEnabled)
1612 EliminateSpillageCopies(MBB);
1613 BackwardCopyPropagateBlock(MBB);
1614 ForwardCopyPropagateBlock(MBB);
1615 }
1616
1618}
1619
1620MachineFunctionPass *
1622 return new MachineCopyPropagationLegacy(UseCopyInstr);
1623}
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
const TargetInstrInfo & TII
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
This file defines the DenseMap class.
static cl::opt< cl::boolOrDefault > EnableSpillageCopyElimination("enable-spill-copy-elim", cl::Hidden)
static bool isBackwardPropagatableCopy(const DestSourcePair &CopyOperands, const MachineRegisterInfo &MRI)
Definition MachineCopyPropagation.cpp:1079
static void printSpillReloadChain(DenseMap< MachineInstr *, SmallVector< MachineInstr * > > &SpillChain, DenseMap< MachineInstr *, SmallVector< MachineInstr * > > &ReloadChain, MachineInstr *Leader)
Definition MachineCopyPropagation.cpp:1250
static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src, MCRegister Def, const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, bool UseCopyInstr)
Return true if PreviousCopy did copy register Src to register Def.
Definition MachineCopyPropagation.cpp:572
static cl::opt< bool > MCPUseCopyInstr("mcp-use-is-copy-instr", cl::init(false), cl::Hidden)
Register const TargetRegisterInfo * TRI
Promote Memory to Register
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
This file implements a set that has insertion order iteration characteristics.
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)
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
bool test(unsigned Idx) const
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
Represents analyses that only rely on functions' control flow.
static bool shouldExecute(CounterInfo &Counter)
iterator find(const_arg_type_t< KeyT > Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Wrapper class representing physical registers. Should be passed by value.
An RAII based helper class to modify MachineFunctionProperties when running pass.
iterator_range< succ_iterator > successors()
LLVM_ABI StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
Definition MachineCopyPropagation.cpp:1579
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.
Representation of each machine instruction.
LLVM_ABI void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
LLVM_ABI void dump() const
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI const TargetRegisterClass * getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
Compute the static register class constraint for operand OpIdx.
LLVM_ABI void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
LLVM_ABI void setReg(Register Reg)
Change the register this operand corresponds to.
LLVM_ABI bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
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.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
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.
void insert_range(Range &&R)
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.
TargetInstrInfo - Interface to description of machine instruction set.
virtual bool simplifyInstruction(MachineInstr &MI) const
If possible, converts the instruction to a simplified/canonical form.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual bool enableSpillageCopyElimination() const
Enable spillage copy elimination in MachineCopyPropagation pass.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
reverse_self_iterator getReverseIterator()
self_iterator getIterator()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
NodeAddr< DefNode * > Def
NodeAddr< UseNode * > Use
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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...
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
auto reverse(ContainerTy &&C)
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...
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
ArrayRef(const T &OneElt) -> ArrayRef< T >
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
LLVM_ABI MachineFunctionPass * createMachineCopyPropagationPass(bool UseCopyInstr)
Definition MachineCopyPropagation.cpp:1621
LLVM_ABI 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.
LLVM_ABI char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
Definition MachineCopyPropagation.cpp:525
const MachineOperand * Source
const MachineOperand * Destination