xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
10b57cec5SDimitry Andric //===- MachineCopyPropagation.cpp - Machine Copy Propagation Pass ---------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This is an extremely simple MachineInstr-level copy propagation pass.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric // This pass forwards the source of COPYs to the users of their destinations
120b57cec5SDimitry Andric // when doing so is legal.  For example:
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //   %reg1 = COPY %reg0
150b57cec5SDimitry Andric //   ...
160b57cec5SDimitry Andric //   ... = OP %reg1
170b57cec5SDimitry Andric //
180b57cec5SDimitry Andric // If
190b57cec5SDimitry Andric //   - %reg0 has not been clobbered by the time of the use of %reg1
200b57cec5SDimitry Andric //   - the register class constraints are satisfied
210b57cec5SDimitry Andric //   - the COPY def is the only value that reaches OP
220b57cec5SDimitry Andric // then this pass replaces the above with:
230b57cec5SDimitry Andric //
240b57cec5SDimitry Andric //   %reg1 = COPY %reg0
250b57cec5SDimitry Andric //   ...
260b57cec5SDimitry Andric //   ... = OP %reg0
270b57cec5SDimitry Andric //
280b57cec5SDimitry Andric // This pass also removes some redundant COPYs.  For example:
290b57cec5SDimitry Andric //
300b57cec5SDimitry Andric //    %R1 = COPY %R0
310b57cec5SDimitry Andric //    ... // No clobber of %R1
320b57cec5SDimitry Andric //    %R0 = COPY %R1 <<< Removed
330b57cec5SDimitry Andric //
340b57cec5SDimitry Andric // or
350b57cec5SDimitry Andric //
360b57cec5SDimitry Andric //    %R1 = COPY %R0
370b57cec5SDimitry Andric //    ... // No clobber of %R0
380b57cec5SDimitry Andric //    %R1 = COPY %R0 <<< Removed
390b57cec5SDimitry Andric //
40480093f4SDimitry Andric // or
41480093f4SDimitry Andric //
42480093f4SDimitry Andric //    $R0 = OP ...
43480093f4SDimitry Andric //    ... // No read/clobber of $R0 and $R1
44480093f4SDimitry Andric //    $R1 = COPY $R0 // $R0 is killed
45480093f4SDimitry Andric // Replace $R0 with $R1 and remove the COPY
46480093f4SDimitry Andric //    $R1 = OP ...
47480093f4SDimitry Andric //    ...
48480093f4SDimitry Andric //
490b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
500b57cec5SDimitry Andric 
510b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
520b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h"
530b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h"
545ffd83dbSDimitry Andric #include "llvm/ADT/SmallSet.h"
550b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
560b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
570b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h"
580b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h"
590b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h"
600b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
610b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
620b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h"
630b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
640b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h"
650b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h"
660b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
67480093f4SDimitry Andric #include "llvm/InitializePasses.h"
680b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h"
690b57cec5SDimitry Andric #include "llvm/Pass.h"
700b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
710b57cec5SDimitry Andric #include "llvm/Support/DebugCounter.h"
720b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
730b57cec5SDimitry Andric #include <cassert>
740b57cec5SDimitry Andric #include <iterator>
750b57cec5SDimitry Andric 
760b57cec5SDimitry Andric using namespace llvm;
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric #define DEBUG_TYPE "machine-cp"
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric STATISTIC(NumDeletes, "Number of dead copies deleted");
810b57cec5SDimitry Andric STATISTIC(NumCopyForwards, "Number of copy uses forwarded");
82480093f4SDimitry Andric STATISTIC(NumCopyBackwardPropagated, "Number of copy defs backward propagated");
830b57cec5SDimitry Andric DEBUG_COUNTER(FwdCounter, "machine-cp-fwd",
840b57cec5SDimitry Andric               "Controls which register COPYs are forwarded");
850b57cec5SDimitry Andric 
86*81ad6265SDimitry Andric static cl::opt<bool> MCPUseCopyInstr("mcp-use-is-copy-instr", cl::init(false),
87*81ad6265SDimitry Andric                                      cl::Hidden);
88*81ad6265SDimitry Andric 
890b57cec5SDimitry Andric namespace {
900b57cec5SDimitry Andric 
91*81ad6265SDimitry Andric static Optional<DestSourcePair> isCopyInstr(const MachineInstr &MI,
92*81ad6265SDimitry Andric                                             const TargetInstrInfo &TII,
93*81ad6265SDimitry Andric                                             bool UseCopyInstr) {
94*81ad6265SDimitry Andric   if (UseCopyInstr)
95*81ad6265SDimitry Andric     return TII.isCopyInstr(MI);
96*81ad6265SDimitry Andric 
97*81ad6265SDimitry Andric   if (MI.isCopy())
98*81ad6265SDimitry Andric     return Optional<DestSourcePair>(
99*81ad6265SDimitry Andric         DestSourcePair{MI.getOperand(0), MI.getOperand(1)});
100*81ad6265SDimitry Andric 
101*81ad6265SDimitry Andric   return None;
102*81ad6265SDimitry Andric }
103*81ad6265SDimitry Andric 
1040b57cec5SDimitry Andric class CopyTracker {
1050b57cec5SDimitry Andric   struct CopyInfo {
1060b57cec5SDimitry Andric     MachineInstr *MI;
107e8d8bef9SDimitry Andric     SmallVector<MCRegister, 4> DefRegs;
1080b57cec5SDimitry Andric     bool Avail;
1090b57cec5SDimitry Andric   };
1100b57cec5SDimitry Andric 
111e8d8bef9SDimitry Andric   DenseMap<MCRegister, CopyInfo> Copies;
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric public:
1140b57cec5SDimitry Andric   /// Mark all of the given registers and their subregisters as unavailable for
1150b57cec5SDimitry Andric   /// copying.
116e8d8bef9SDimitry Andric   void markRegsUnavailable(ArrayRef<MCRegister> Regs,
1170b57cec5SDimitry Andric                            const TargetRegisterInfo &TRI) {
118e8d8bef9SDimitry Andric     for (MCRegister Reg : Regs) {
1190b57cec5SDimitry Andric       // Source of copy is no longer available for propagation.
1200b57cec5SDimitry Andric       for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
1210b57cec5SDimitry Andric         auto CI = Copies.find(*RUI);
1220b57cec5SDimitry Andric         if (CI != Copies.end())
1230b57cec5SDimitry Andric           CI->second.Avail = false;
1240b57cec5SDimitry Andric       }
1250b57cec5SDimitry Andric     }
1260b57cec5SDimitry Andric   }
1270b57cec5SDimitry Andric 
128480093f4SDimitry Andric   /// Remove register from copy maps.
129*81ad6265SDimitry Andric   void invalidateRegister(MCRegister Reg, const TargetRegisterInfo &TRI,
130*81ad6265SDimitry Andric                           const TargetInstrInfo &TII, bool UseCopyInstr) {
131480093f4SDimitry Andric     // Since Reg might be a subreg of some registers, only invalidate Reg is not
132480093f4SDimitry Andric     // enough. We have to find the COPY defines Reg or registers defined by Reg
133480093f4SDimitry Andric     // and invalidate all of them.
134e8d8bef9SDimitry Andric     SmallSet<MCRegister, 8> RegsToInvalidate;
1355ffd83dbSDimitry Andric     RegsToInvalidate.insert(Reg);
136480093f4SDimitry Andric     for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
137480093f4SDimitry Andric       auto I = Copies.find(*RUI);
138480093f4SDimitry Andric       if (I != Copies.end()) {
139480093f4SDimitry Andric         if (MachineInstr *MI = I->second.MI) {
140*81ad6265SDimitry Andric           Optional<DestSourcePair> CopyOperands =
141*81ad6265SDimitry Andric               isCopyInstr(*MI, TII, UseCopyInstr);
142*81ad6265SDimitry Andric           assert(CopyOperands && "Expect copy");
143*81ad6265SDimitry Andric 
144*81ad6265SDimitry Andric           RegsToInvalidate.insert(
145*81ad6265SDimitry Andric               CopyOperands->Destination->getReg().asMCReg());
146*81ad6265SDimitry Andric           RegsToInvalidate.insert(CopyOperands->Source->getReg().asMCReg());
147480093f4SDimitry Andric         }
148480093f4SDimitry Andric         RegsToInvalidate.insert(I->second.DefRegs.begin(),
149480093f4SDimitry Andric                                 I->second.DefRegs.end());
150480093f4SDimitry Andric       }
151480093f4SDimitry Andric     }
152e8d8bef9SDimitry Andric     for (MCRegister InvalidReg : RegsToInvalidate)
153480093f4SDimitry Andric       for (MCRegUnitIterator RUI(InvalidReg, &TRI); RUI.isValid(); ++RUI)
154480093f4SDimitry Andric         Copies.erase(*RUI);
155480093f4SDimitry Andric   }
156480093f4SDimitry Andric 
1570b57cec5SDimitry Andric   /// Clobber a single register, removing it from the tracker's copy maps.
158*81ad6265SDimitry Andric   void clobberRegister(MCRegister Reg, const TargetRegisterInfo &TRI,
159*81ad6265SDimitry Andric                        const TargetInstrInfo &TII, bool UseCopyInstr) {
1600b57cec5SDimitry Andric     for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
1610b57cec5SDimitry Andric       auto I = Copies.find(*RUI);
1620b57cec5SDimitry Andric       if (I != Copies.end()) {
1630b57cec5SDimitry Andric         // When we clobber the source of a copy, we need to clobber everything
1640b57cec5SDimitry Andric         // it defined.
1650b57cec5SDimitry Andric         markRegsUnavailable(I->second.DefRegs, TRI);
1660b57cec5SDimitry Andric         // When we clobber the destination of a copy, we need to clobber the
1670b57cec5SDimitry Andric         // whole register it defined.
168*81ad6265SDimitry Andric         if (MachineInstr *MI = I->second.MI) {
169*81ad6265SDimitry Andric           Optional<DestSourcePair> CopyOperands =
170*81ad6265SDimitry Andric               isCopyInstr(*MI, TII, UseCopyInstr);
171*81ad6265SDimitry Andric           markRegsUnavailable({CopyOperands->Destination->getReg().asMCReg()},
172*81ad6265SDimitry Andric                               TRI);
173*81ad6265SDimitry Andric         }
1740b57cec5SDimitry Andric         // Now we can erase the copy.
1750b57cec5SDimitry Andric         Copies.erase(I);
1760b57cec5SDimitry Andric       }
1770b57cec5SDimitry Andric     }
1780b57cec5SDimitry Andric   }
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric   /// Add this copy's registers into the tracker's copy maps.
181*81ad6265SDimitry Andric   void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI,
182*81ad6265SDimitry Andric                  const TargetInstrInfo &TII, bool UseCopyInstr) {
183*81ad6265SDimitry Andric     Optional<DestSourcePair> CopyOperands = isCopyInstr(*MI, TII, UseCopyInstr);
184*81ad6265SDimitry Andric     assert(CopyOperands && "Tracking non-copy?");
1850b57cec5SDimitry Andric 
186*81ad6265SDimitry Andric     MCRegister Src = CopyOperands->Source->getReg().asMCReg();
187*81ad6265SDimitry Andric     MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
1880b57cec5SDimitry Andric 
1890b57cec5SDimitry Andric     // Remember Def is defined by the copy.
1900b57cec5SDimitry Andric     for (MCRegUnitIterator RUI(Def, &TRI); RUI.isValid(); ++RUI)
1910b57cec5SDimitry Andric       Copies[*RUI] = {MI, {}, true};
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric     // Remember source that's copied to Def. Once it's clobbered, then
1940b57cec5SDimitry Andric     // it's no longer available for copy propagation.
1950b57cec5SDimitry Andric     for (MCRegUnitIterator RUI(Src, &TRI); RUI.isValid(); ++RUI) {
1960b57cec5SDimitry Andric       auto I = Copies.insert({*RUI, {nullptr, {}, false}});
1970b57cec5SDimitry Andric       auto &Copy = I.first->second;
1980b57cec5SDimitry Andric       if (!is_contained(Copy.DefRegs, Def))
1990b57cec5SDimitry Andric         Copy.DefRegs.push_back(Def);
2000b57cec5SDimitry Andric     }
2010b57cec5SDimitry Andric   }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric   bool hasAnyCopies() {
2040b57cec5SDimitry Andric     return !Copies.empty();
2050b57cec5SDimitry Andric   }
2060b57cec5SDimitry Andric 
207e8d8bef9SDimitry Andric   MachineInstr *findCopyForUnit(MCRegister RegUnit,
208e8d8bef9SDimitry Andric                                 const TargetRegisterInfo &TRI,
2090b57cec5SDimitry Andric                                 bool MustBeAvailable = false) {
2100b57cec5SDimitry Andric     auto CI = Copies.find(RegUnit);
2110b57cec5SDimitry Andric     if (CI == Copies.end())
2120b57cec5SDimitry Andric       return nullptr;
2130b57cec5SDimitry Andric     if (MustBeAvailable && !CI->second.Avail)
2140b57cec5SDimitry Andric       return nullptr;
2150b57cec5SDimitry Andric     return CI->second.MI;
2160b57cec5SDimitry Andric   }
2170b57cec5SDimitry Andric 
218e8d8bef9SDimitry Andric   MachineInstr *findCopyDefViaUnit(MCRegister RegUnit,
219480093f4SDimitry Andric                                    const TargetRegisterInfo &TRI) {
220480093f4SDimitry Andric     auto CI = Copies.find(RegUnit);
221480093f4SDimitry Andric     if (CI == Copies.end())
222480093f4SDimitry Andric       return nullptr;
223480093f4SDimitry Andric     if (CI->second.DefRegs.size() != 1)
224480093f4SDimitry Andric       return nullptr;
225480093f4SDimitry Andric     MCRegUnitIterator RUI(CI->second.DefRegs[0], &TRI);
226480093f4SDimitry Andric     return findCopyForUnit(*RUI, TRI, true);
227480093f4SDimitry Andric   }
228480093f4SDimitry Andric 
229e8d8bef9SDimitry Andric   MachineInstr *findAvailBackwardCopy(MachineInstr &I, MCRegister Reg,
230*81ad6265SDimitry Andric                                       const TargetRegisterInfo &TRI,
231*81ad6265SDimitry Andric                                       const TargetInstrInfo &TII,
232*81ad6265SDimitry Andric                                       bool UseCopyInstr) {
233480093f4SDimitry Andric     MCRegUnitIterator RUI(Reg, &TRI);
234480093f4SDimitry Andric     MachineInstr *AvailCopy = findCopyDefViaUnit(*RUI, TRI);
235*81ad6265SDimitry Andric 
236*81ad6265SDimitry Andric     if (!AvailCopy)
237480093f4SDimitry Andric       return nullptr;
238480093f4SDimitry Andric 
239*81ad6265SDimitry Andric     Optional<DestSourcePair> CopyOperands =
240*81ad6265SDimitry Andric         isCopyInstr(*AvailCopy, TII, UseCopyInstr);
241*81ad6265SDimitry Andric     Register AvailSrc = CopyOperands->Source->getReg();
242*81ad6265SDimitry Andric     Register AvailDef = CopyOperands->Destination->getReg();
243*81ad6265SDimitry Andric     if (!TRI.isSubRegisterEq(AvailSrc, Reg))
244*81ad6265SDimitry Andric       return nullptr;
245*81ad6265SDimitry Andric 
246480093f4SDimitry Andric     for (const MachineInstr &MI :
247480093f4SDimitry Andric          make_range(AvailCopy->getReverseIterator(), I.getReverseIterator()))
248480093f4SDimitry Andric       for (const MachineOperand &MO : MI.operands())
249480093f4SDimitry Andric         if (MO.isRegMask())
250480093f4SDimitry Andric           // FIXME: Shall we simultaneously invalidate AvailSrc or AvailDef?
251480093f4SDimitry Andric           if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
252480093f4SDimitry Andric             return nullptr;
253480093f4SDimitry Andric 
254480093f4SDimitry Andric     return AvailCopy;
255480093f4SDimitry Andric   }
256480093f4SDimitry Andric 
257e8d8bef9SDimitry Andric   MachineInstr *findAvailCopy(MachineInstr &DestCopy, MCRegister Reg,
258*81ad6265SDimitry Andric                               const TargetRegisterInfo &TRI,
259*81ad6265SDimitry Andric                               const TargetInstrInfo &TII, bool UseCopyInstr) {
2600b57cec5SDimitry Andric     // We check the first RegUnit here, since we'll only be interested in the
2610b57cec5SDimitry Andric     // copy if it copies the entire register anyway.
2620b57cec5SDimitry Andric     MCRegUnitIterator RUI(Reg, &TRI);
2630b57cec5SDimitry Andric     MachineInstr *AvailCopy =
2640b57cec5SDimitry Andric         findCopyForUnit(*RUI, TRI, /*MustBeAvailable=*/true);
265*81ad6265SDimitry Andric 
266*81ad6265SDimitry Andric     if (!AvailCopy)
267*81ad6265SDimitry Andric       return nullptr;
268*81ad6265SDimitry Andric 
269*81ad6265SDimitry Andric     Optional<DestSourcePair> CopyOperands =
270*81ad6265SDimitry Andric         isCopyInstr(*AvailCopy, TII, UseCopyInstr);
271*81ad6265SDimitry Andric     Register AvailSrc = CopyOperands->Source->getReg();
272*81ad6265SDimitry Andric     Register AvailDef = CopyOperands->Destination->getReg();
273*81ad6265SDimitry Andric     if (!TRI.isSubRegisterEq(AvailDef, Reg))
2740b57cec5SDimitry Andric       return nullptr;
2750b57cec5SDimitry Andric 
2760b57cec5SDimitry Andric     // Check that the available copy isn't clobbered by any regmasks between
2770b57cec5SDimitry Andric     // itself and the destination.
2780b57cec5SDimitry Andric     for (const MachineInstr &MI :
2790b57cec5SDimitry Andric          make_range(AvailCopy->getIterator(), DestCopy.getIterator()))
2800b57cec5SDimitry Andric       for (const MachineOperand &MO : MI.operands())
2810b57cec5SDimitry Andric         if (MO.isRegMask())
2820b57cec5SDimitry Andric           if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
2830b57cec5SDimitry Andric             return nullptr;
2840b57cec5SDimitry Andric 
2850b57cec5SDimitry Andric     return AvailCopy;
2860b57cec5SDimitry Andric   }
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric   void clear() {
2890b57cec5SDimitry Andric     Copies.clear();
2900b57cec5SDimitry Andric   }
2910b57cec5SDimitry Andric };
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric class MachineCopyPropagation : public MachineFunctionPass {
2940b57cec5SDimitry Andric   const TargetRegisterInfo *TRI;
2950b57cec5SDimitry Andric   const TargetInstrInfo *TII;
2960b57cec5SDimitry Andric   const MachineRegisterInfo *MRI;
2970b57cec5SDimitry Andric 
298*81ad6265SDimitry Andric   // Return true if this is a copy instruction and false otherwise.
299*81ad6265SDimitry Andric   bool UseCopyInstr;
300*81ad6265SDimitry Andric 
3010b57cec5SDimitry Andric public:
3020b57cec5SDimitry Andric   static char ID; // Pass identification, replacement for typeid
3030b57cec5SDimitry Andric 
304*81ad6265SDimitry Andric   MachineCopyPropagation(bool CopyInstr = false)
305*81ad6265SDimitry Andric       : MachineFunctionPass(ID), UseCopyInstr(CopyInstr || MCPUseCopyInstr) {
3060b57cec5SDimitry Andric     initializeMachineCopyPropagationPass(*PassRegistry::getPassRegistry());
3070b57cec5SDimitry Andric   }
3080b57cec5SDimitry Andric 
3090b57cec5SDimitry Andric   void getAnalysisUsage(AnalysisUsage &AU) const override {
3100b57cec5SDimitry Andric     AU.setPreservesCFG();
3110b57cec5SDimitry Andric     MachineFunctionPass::getAnalysisUsage(AU);
3120b57cec5SDimitry Andric   }
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   bool runOnMachineFunction(MachineFunction &MF) override;
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   MachineFunctionProperties getRequiredProperties() const override {
3170b57cec5SDimitry Andric     return MachineFunctionProperties().set(
3180b57cec5SDimitry Andric         MachineFunctionProperties::Property::NoVRegs);
3190b57cec5SDimitry Andric   }
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric private:
3228bcb0991SDimitry Andric   typedef enum { DebugUse = false, RegularUse = true } DebugType;
3238bcb0991SDimitry Andric 
324e8d8bef9SDimitry Andric   void ReadRegister(MCRegister Reg, MachineInstr &Reader, DebugType DT);
325480093f4SDimitry Andric   void ForwardCopyPropagateBlock(MachineBasicBlock &MBB);
326480093f4SDimitry Andric   void BackwardCopyPropagateBlock(MachineBasicBlock &MBB);
327e8d8bef9SDimitry Andric   bool eraseIfRedundant(MachineInstr &Copy, MCRegister Src, MCRegister Def);
3280b57cec5SDimitry Andric   void forwardUses(MachineInstr &MI);
329480093f4SDimitry Andric   void propagateDefs(MachineInstr &MI);
3300b57cec5SDimitry Andric   bool isForwardableRegClassCopy(const MachineInstr &Copy,
3310b57cec5SDimitry Andric                                  const MachineInstr &UseI, unsigned UseIdx);
332480093f4SDimitry Andric   bool isBackwardPropagatableRegClassCopy(const MachineInstr &Copy,
333480093f4SDimitry Andric                                           const MachineInstr &UseI,
334480093f4SDimitry Andric                                           unsigned UseIdx);
3350b57cec5SDimitry Andric   bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use);
336e8d8bef9SDimitry Andric   bool hasOverlappingMultipleDef(const MachineInstr &MI,
337e8d8bef9SDimitry Andric                                  const MachineOperand &MODef, Register Def);
3380b57cec5SDimitry Andric 
3390b57cec5SDimitry Andric   /// Candidates for deletion.
3400b57cec5SDimitry Andric   SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
3410b57cec5SDimitry Andric 
3428bcb0991SDimitry Andric   /// Multimap tracking debug users in current BB
343fe6060f1SDimitry Andric   DenseMap<MachineInstr *, SmallSet<MachineInstr *, 2>> CopyDbgUsers;
3448bcb0991SDimitry Andric 
3450b57cec5SDimitry Andric   CopyTracker Tracker;
3460b57cec5SDimitry Andric 
3470b57cec5SDimitry Andric   bool Changed;
3480b57cec5SDimitry Andric };
3490b57cec5SDimitry Andric 
3500b57cec5SDimitry Andric } // end anonymous namespace
3510b57cec5SDimitry Andric 
3520b57cec5SDimitry Andric char MachineCopyPropagation::ID = 0;
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID;
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE,
3570b57cec5SDimitry Andric                 "Machine Copy Propagation Pass", false, false)
3580b57cec5SDimitry Andric 
359e8d8bef9SDimitry Andric void MachineCopyPropagation::ReadRegister(MCRegister Reg, MachineInstr &Reader,
3608bcb0991SDimitry Andric                                           DebugType DT) {
3610b57cec5SDimitry Andric   // If 'Reg' is defined by a copy, the copy is no longer a candidate
3628bcb0991SDimitry Andric   // for elimination. If a copy is "read" by a debug user, record the user
3638bcb0991SDimitry Andric   // for propagation.
3640b57cec5SDimitry Andric   for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
3650b57cec5SDimitry Andric     if (MachineInstr *Copy = Tracker.findCopyForUnit(*RUI, *TRI)) {
3668bcb0991SDimitry Andric       if (DT == RegularUse) {
3670b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; Copy->dump());
3680b57cec5SDimitry Andric         MaybeDeadCopies.remove(Copy);
3698bcb0991SDimitry Andric       } else {
370fe6060f1SDimitry Andric         CopyDbgUsers[Copy].insert(&Reader);
3718bcb0991SDimitry Andric       }
3720b57cec5SDimitry Andric     }
3730b57cec5SDimitry Andric   }
3740b57cec5SDimitry Andric }
3750b57cec5SDimitry Andric 
3760b57cec5SDimitry Andric /// Return true if \p PreviousCopy did copy register \p Src to register \p Def.
3770b57cec5SDimitry Andric /// This fact may have been obscured by sub register usage or may not be true at
3780b57cec5SDimitry Andric /// all even though Src and Def are subregisters of the registers used in
3790b57cec5SDimitry Andric /// PreviousCopy. e.g.
3800b57cec5SDimitry Andric /// isNopCopy("ecx = COPY eax", AX, CX) == true
3810b57cec5SDimitry Andric /// isNopCopy("ecx = COPY eax", AH, CL) == false
382e8d8bef9SDimitry Andric static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src,
383*81ad6265SDimitry Andric                       MCRegister Def, const TargetRegisterInfo *TRI,
384*81ad6265SDimitry Andric                       const TargetInstrInfo *TII, bool UseCopyInstr) {
385*81ad6265SDimitry Andric 
386*81ad6265SDimitry Andric   Optional<DestSourcePair> CopyOperands =
387*81ad6265SDimitry Andric       isCopyInstr(PreviousCopy, *TII, UseCopyInstr);
388*81ad6265SDimitry Andric   MCRegister PreviousSrc = CopyOperands->Source->getReg().asMCReg();
389*81ad6265SDimitry Andric   MCRegister PreviousDef = CopyOperands->Destination->getReg().asMCReg();
39016d6b3b3SDimitry Andric   if (Src == PreviousSrc && Def == PreviousDef)
3910b57cec5SDimitry Andric     return true;
3920b57cec5SDimitry Andric   if (!TRI->isSubRegister(PreviousSrc, Src))
3930b57cec5SDimitry Andric     return false;
3940b57cec5SDimitry Andric   unsigned SubIdx = TRI->getSubRegIndex(PreviousSrc, Src);
3950b57cec5SDimitry Andric   return SubIdx == TRI->getSubRegIndex(PreviousDef, Def);
3960b57cec5SDimitry Andric }
3970b57cec5SDimitry Andric 
3980b57cec5SDimitry Andric /// Remove instruction \p Copy if there exists a previous copy that copies the
3990b57cec5SDimitry Andric /// register \p Src to the register \p Def; This may happen indirectly by
4000b57cec5SDimitry Andric /// copying the super registers.
401e8d8bef9SDimitry Andric bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy,
402e8d8bef9SDimitry Andric                                               MCRegister Src, MCRegister Def) {
4030b57cec5SDimitry Andric   // Avoid eliminating a copy from/to a reserved registers as we cannot predict
4040b57cec5SDimitry Andric   // the value (Example: The sparc zero register is writable but stays zero).
4050b57cec5SDimitry Andric   if (MRI->isReserved(Src) || MRI->isReserved(Def))
4060b57cec5SDimitry Andric     return false;
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   // Search for an existing copy.
409*81ad6265SDimitry Andric   MachineInstr *PrevCopy =
410*81ad6265SDimitry Andric       Tracker.findAvailCopy(Copy, Def, *TRI, *TII, UseCopyInstr);
4110b57cec5SDimitry Andric   if (!PrevCopy)
4120b57cec5SDimitry Andric     return false;
4130b57cec5SDimitry Andric 
414*81ad6265SDimitry Andric   auto PrevCopyOperands = isCopyInstr(*PrevCopy, *TII, UseCopyInstr);
4150b57cec5SDimitry Andric   // Check that the existing copy uses the correct sub registers.
416*81ad6265SDimitry Andric   if (PrevCopyOperands->Destination->isDead())
4170b57cec5SDimitry Andric     return false;
418*81ad6265SDimitry Andric   if (!isNopCopy(*PrevCopy, Src, Def, TRI, TII, UseCopyInstr))
4190b57cec5SDimitry Andric     return false;
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric   LLVM_DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; Copy.dump());
4220b57cec5SDimitry Andric 
4230b57cec5SDimitry Andric   // Copy was redundantly redefining either Src or Def. Remove earlier kill
4240b57cec5SDimitry Andric   // flags between Copy and PrevCopy because the value will be reused now.
425*81ad6265SDimitry Andric   Optional<DestSourcePair> CopyOperands = isCopyInstr(Copy, *TII, UseCopyInstr);
426*81ad6265SDimitry Andric   assert(CopyOperands);
427*81ad6265SDimitry Andric 
428*81ad6265SDimitry Andric   Register CopyDef = CopyOperands->Destination->getReg();
4290b57cec5SDimitry Andric   assert(CopyDef == Src || CopyDef == Def);
4300b57cec5SDimitry Andric   for (MachineInstr &MI :
4310b57cec5SDimitry Andric        make_range(PrevCopy->getIterator(), Copy.getIterator()))
4320b57cec5SDimitry Andric     MI.clearRegisterKills(CopyDef, TRI);
4330b57cec5SDimitry Andric 
4340b57cec5SDimitry Andric   Copy.eraseFromParent();
4350b57cec5SDimitry Andric   Changed = true;
4360b57cec5SDimitry Andric   ++NumDeletes;
4370b57cec5SDimitry Andric   return true;
4380b57cec5SDimitry Andric }
4390b57cec5SDimitry Andric 
440480093f4SDimitry Andric bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy(
441480093f4SDimitry Andric     const MachineInstr &Copy, const MachineInstr &UseI, unsigned UseIdx) {
442*81ad6265SDimitry Andric 
443*81ad6265SDimitry Andric   Optional<DestSourcePair> CopyOperands = isCopyInstr(Copy, *TII, UseCopyInstr);
444*81ad6265SDimitry Andric   Register Def = CopyOperands->Destination->getReg();
445480093f4SDimitry Andric 
446480093f4SDimitry Andric   if (const TargetRegisterClass *URC =
447480093f4SDimitry Andric           UseI.getRegClassConstraint(UseIdx, TII, TRI))
448480093f4SDimitry Andric     return URC->contains(Def);
449480093f4SDimitry Andric 
450480093f4SDimitry Andric   // We don't process further if UseI is a COPY, since forward copy propagation
451480093f4SDimitry Andric   // should handle that.
452480093f4SDimitry Andric   return false;
453480093f4SDimitry Andric }
454480093f4SDimitry Andric 
4550b57cec5SDimitry Andric /// Decide whether we should forward the source of \param Copy to its use in
4560b57cec5SDimitry Andric /// \param UseI based on the physical register class constraints of the opcode
4570b57cec5SDimitry Andric /// and avoiding introducing more cross-class COPYs.
4580b57cec5SDimitry Andric bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy,
4590b57cec5SDimitry Andric                                                        const MachineInstr &UseI,
4600b57cec5SDimitry Andric                                                        unsigned UseIdx) {
4610b57cec5SDimitry Andric 
462*81ad6265SDimitry Andric   Optional<DestSourcePair> CopyOperands = isCopyInstr(Copy, *TII, UseCopyInstr);
463*81ad6265SDimitry Andric   Register CopySrcReg = CopyOperands->Source->getReg();
4640b57cec5SDimitry Andric 
4650b57cec5SDimitry Andric   // If the new register meets the opcode register constraints, then allow
4660b57cec5SDimitry Andric   // forwarding.
4670b57cec5SDimitry Andric   if (const TargetRegisterClass *URC =
4680b57cec5SDimitry Andric           UseI.getRegClassConstraint(UseIdx, TII, TRI))
4690b57cec5SDimitry Andric     return URC->contains(CopySrcReg);
4700b57cec5SDimitry Andric 
471*81ad6265SDimitry Andric   auto UseICopyOperands = isCopyInstr(UseI, *TII, UseCopyInstr);
472*81ad6265SDimitry Andric   if (!UseICopyOperands)
4730b57cec5SDimitry Andric     return false;
4740b57cec5SDimitry Andric 
4750b57cec5SDimitry Andric   /// COPYs don't have register class constraints, so if the user instruction
4760b57cec5SDimitry Andric   /// is a COPY, we just try to avoid introducing additional cross-class
4770b57cec5SDimitry Andric   /// COPYs.  For example:
4780b57cec5SDimitry Andric   ///
4790b57cec5SDimitry Andric   ///   RegClassA = COPY RegClassB  // Copy parameter
4800b57cec5SDimitry Andric   ///   ...
4810b57cec5SDimitry Andric   ///   RegClassB = COPY RegClassA  // UseI parameter
4820b57cec5SDimitry Andric   ///
4830b57cec5SDimitry Andric   /// which after forwarding becomes
4840b57cec5SDimitry Andric   ///
4850b57cec5SDimitry Andric   ///   RegClassA = COPY RegClassB
4860b57cec5SDimitry Andric   ///   ...
4870b57cec5SDimitry Andric   ///   RegClassB = COPY RegClassB
4880b57cec5SDimitry Andric   ///
4890b57cec5SDimitry Andric   /// so we have reduced the number of cross-class COPYs and potentially
4900b57cec5SDimitry Andric   /// introduced a nop COPY that can be removed.
4910b57cec5SDimitry Andric 
492*81ad6265SDimitry Andric   // Allow forwarding if src and dst belong to any common class, so long as they
493*81ad6265SDimitry Andric   // don't belong to any (possibly smaller) common class that requires copies to
494*81ad6265SDimitry Andric   // go via a different class.
495*81ad6265SDimitry Andric   Register UseDstReg = UseICopyOperands->Destination->getReg();
496*81ad6265SDimitry Andric   bool Found = false;
497*81ad6265SDimitry Andric   bool IsCrossClass = false;
498*81ad6265SDimitry Andric   for (const TargetRegisterClass *RC : TRI->regclasses()) {
499*81ad6265SDimitry Andric     if (RC->contains(CopySrcReg) && RC->contains(UseDstReg)) {
500*81ad6265SDimitry Andric       Found = true;
501*81ad6265SDimitry Andric       if (TRI->getCrossCopyRegClass(RC) != RC) {
502*81ad6265SDimitry Andric         IsCrossClass = true;
503*81ad6265SDimitry Andric         break;
504*81ad6265SDimitry Andric       }
505*81ad6265SDimitry Andric     }
506*81ad6265SDimitry Andric   }
507*81ad6265SDimitry Andric   if (!Found)
508*81ad6265SDimitry Andric     return false;
509*81ad6265SDimitry Andric   if (!IsCrossClass)
510*81ad6265SDimitry Andric     return true;
511*81ad6265SDimitry Andric   // The forwarded copy would be cross-class. Only do this if the original copy
512*81ad6265SDimitry Andric   // was also cross-class.
513*81ad6265SDimitry Andric   Register CopyDstReg = CopyOperands->Destination->getReg();
514*81ad6265SDimitry Andric   for (const TargetRegisterClass *RC : TRI->regclasses()) {
515*81ad6265SDimitry Andric     if (RC->contains(CopySrcReg) && RC->contains(CopyDstReg) &&
516*81ad6265SDimitry Andric         TRI->getCrossCopyRegClass(RC) != RC)
517*81ad6265SDimitry Andric       return true;
518*81ad6265SDimitry Andric   }
5190b57cec5SDimitry Andric   return false;
5200b57cec5SDimitry Andric }
5210b57cec5SDimitry Andric 
5220b57cec5SDimitry Andric /// Check that \p MI does not have implicit uses that overlap with it's \p Use
5230b57cec5SDimitry Andric /// operand (the register being replaced), since these can sometimes be
5240b57cec5SDimitry Andric /// implicitly tied to other operands.  For example, on AMDGPU:
5250b57cec5SDimitry Andric ///
5260b57cec5SDimitry Andric /// V_MOVRELS_B32_e32 %VGPR2, %M0<imp-use>, %EXEC<imp-use>, %VGPR2_VGPR3_VGPR4_VGPR5<imp-use>
5270b57cec5SDimitry Andric ///
5280b57cec5SDimitry Andric /// the %VGPR2 is implicitly tied to the larger reg operand, but we have no
5290b57cec5SDimitry Andric /// way of knowing we need to update the latter when updating the former.
5300b57cec5SDimitry Andric bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI,
5310b57cec5SDimitry Andric                                                 const MachineOperand &Use) {
5320b57cec5SDimitry Andric   for (const MachineOperand &MIUse : MI.uses())
5330b57cec5SDimitry Andric     if (&MIUse != &Use && MIUse.isReg() && MIUse.isImplicit() &&
5340b57cec5SDimitry Andric         MIUse.isUse() && TRI->regsOverlap(Use.getReg(), MIUse.getReg()))
5350b57cec5SDimitry Andric       return true;
5360b57cec5SDimitry Andric 
5370b57cec5SDimitry Andric   return false;
5380b57cec5SDimitry Andric }
5390b57cec5SDimitry Andric 
540e8d8bef9SDimitry Andric /// For an MI that has multiple definitions, check whether \p MI has
541e8d8bef9SDimitry Andric /// a definition that overlaps with another of its definitions.
542e8d8bef9SDimitry Andric /// For example, on ARM: umull   r9, r9, lr, r0
543e8d8bef9SDimitry Andric /// The umull instruction is unpredictable unless RdHi and RdLo are different.
544e8d8bef9SDimitry Andric bool MachineCopyPropagation::hasOverlappingMultipleDef(
545e8d8bef9SDimitry Andric     const MachineInstr &MI, const MachineOperand &MODef, Register Def) {
546e8d8bef9SDimitry Andric   for (const MachineOperand &MIDef : MI.defs()) {
547e8d8bef9SDimitry Andric     if ((&MIDef != &MODef) && MIDef.isReg() &&
548e8d8bef9SDimitry Andric         TRI->regsOverlap(Def, MIDef.getReg()))
549e8d8bef9SDimitry Andric       return true;
550e8d8bef9SDimitry Andric   }
551e8d8bef9SDimitry Andric 
552e8d8bef9SDimitry Andric   return false;
553e8d8bef9SDimitry Andric }
554e8d8bef9SDimitry Andric 
5550b57cec5SDimitry Andric /// Look for available copies whose destination register is used by \p MI and
5560b57cec5SDimitry Andric /// replace the use in \p MI with the copy's source register.
5570b57cec5SDimitry Andric void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
5580b57cec5SDimitry Andric   if (!Tracker.hasAnyCopies())
5590b57cec5SDimitry Andric     return;
5600b57cec5SDimitry Andric 
5610b57cec5SDimitry Andric   // Look for non-tied explicit vreg uses that have an active COPY
5620b57cec5SDimitry Andric   // instruction that defines the physical register allocated to them.
5630b57cec5SDimitry Andric   // Replace the vreg with the source of the active COPY.
5640b57cec5SDimitry Andric   for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx < OpEnd;
5650b57cec5SDimitry Andric        ++OpIdx) {
5660b57cec5SDimitry Andric     MachineOperand &MOUse = MI.getOperand(OpIdx);
5670b57cec5SDimitry Andric     // Don't forward into undef use operands since doing so can cause problems
5680b57cec5SDimitry Andric     // with the machine verifier, since it doesn't treat undef reads as reads,
5690b57cec5SDimitry Andric     // so we can end up with a live range that ends on an undef read, leading to
5700b57cec5SDimitry Andric     // an error that the live range doesn't end on a read of the live range
5710b57cec5SDimitry Andric     // register.
5720b57cec5SDimitry Andric     if (!MOUse.isReg() || MOUse.isTied() || MOUse.isUndef() || MOUse.isDef() ||
5730b57cec5SDimitry Andric         MOUse.isImplicit())
5740b57cec5SDimitry Andric       continue;
5750b57cec5SDimitry Andric 
5760b57cec5SDimitry Andric     if (!MOUse.getReg())
5770b57cec5SDimitry Andric       continue;
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric     // Check that the register is marked 'renamable' so we know it is safe to
5800b57cec5SDimitry Andric     // rename it without violating any constraints that aren't expressed in the
5810b57cec5SDimitry Andric     // IR (e.g. ABI or opcode requirements).
5820b57cec5SDimitry Andric     if (!MOUse.isRenamable())
5830b57cec5SDimitry Andric       continue;
5840b57cec5SDimitry Andric 
585*81ad6265SDimitry Andric     MachineInstr *Copy = Tracker.findAvailCopy(MI, MOUse.getReg().asMCReg(),
586*81ad6265SDimitry Andric                                                *TRI, *TII, UseCopyInstr);
5870b57cec5SDimitry Andric     if (!Copy)
5880b57cec5SDimitry Andric       continue;
5890b57cec5SDimitry Andric 
590*81ad6265SDimitry Andric     Optional<DestSourcePair> CopyOperands =
591*81ad6265SDimitry Andric         isCopyInstr(*Copy, *TII, UseCopyInstr);
592*81ad6265SDimitry Andric     Register CopyDstReg = CopyOperands->Destination->getReg();
593*81ad6265SDimitry Andric     const MachineOperand &CopySrc = *CopyOperands->Source;
5948bcb0991SDimitry Andric     Register CopySrcReg = CopySrc.getReg();
5950b57cec5SDimitry Andric 
5960b57cec5SDimitry Andric     // FIXME: Don't handle partial uses of wider COPYs yet.
5970b57cec5SDimitry Andric     if (MOUse.getReg() != CopyDstReg) {
5980b57cec5SDimitry Andric       LLVM_DEBUG(
5990b57cec5SDimitry Andric           dbgs() << "MCP: FIXME! Not forwarding COPY to sub-register use:\n  "
6000b57cec5SDimitry Andric                  << MI);
6010b57cec5SDimitry Andric       continue;
6020b57cec5SDimitry Andric     }
6030b57cec5SDimitry Andric 
6040b57cec5SDimitry Andric     // Don't forward COPYs of reserved regs unless they are constant.
6050b57cec5SDimitry Andric     if (MRI->isReserved(CopySrcReg) && !MRI->isConstantPhysReg(CopySrcReg))
6060b57cec5SDimitry Andric       continue;
6070b57cec5SDimitry Andric 
6080b57cec5SDimitry Andric     if (!isForwardableRegClassCopy(*Copy, MI, OpIdx))
6090b57cec5SDimitry Andric       continue;
6100b57cec5SDimitry Andric 
6110b57cec5SDimitry Andric     if (hasImplicitOverlap(MI, MOUse))
6120b57cec5SDimitry Andric       continue;
6130b57cec5SDimitry Andric 
614480093f4SDimitry Andric     // Check that the instruction is not a copy that partially overwrites the
615480093f4SDimitry Andric     // original copy source that we are about to use. The tracker mechanism
616480093f4SDimitry Andric     // cannot cope with that.
617*81ad6265SDimitry Andric     if (isCopyInstr(MI, *TII, UseCopyInstr) &&
618*81ad6265SDimitry Andric         MI.modifiesRegister(CopySrcReg, TRI) &&
619480093f4SDimitry Andric         !MI.definesRegister(CopySrcReg)) {
620480093f4SDimitry Andric       LLVM_DEBUG(dbgs() << "MCP: Copy source overlap with dest in " << MI);
621480093f4SDimitry Andric       continue;
622480093f4SDimitry Andric     }
623480093f4SDimitry Andric 
6240b57cec5SDimitry Andric     if (!DebugCounter::shouldExecute(FwdCounter)) {
6250b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "MCP: Skipping forwarding due to debug counter:\n  "
6260b57cec5SDimitry Andric                         << MI);
6270b57cec5SDimitry Andric       continue;
6280b57cec5SDimitry Andric     }
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MOUse.getReg(), TRI)
6310b57cec5SDimitry Andric                       << "\n     with " << printReg(CopySrcReg, TRI)
6320b57cec5SDimitry Andric                       << "\n     in " << MI << "     from " << *Copy);
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric     MOUse.setReg(CopySrcReg);
6350b57cec5SDimitry Andric     if (!CopySrc.isRenamable())
6360b57cec5SDimitry Andric       MOUse.setIsRenamable(false);
637349cc55cSDimitry Andric     MOUse.setIsUndef(CopySrc.isUndef());
6380b57cec5SDimitry Andric 
6390b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
6400b57cec5SDimitry Andric 
6410b57cec5SDimitry Andric     // Clear kill markers that may have been invalidated.
6420b57cec5SDimitry Andric     for (MachineInstr &KMI :
6430b57cec5SDimitry Andric          make_range(Copy->getIterator(), std::next(MI.getIterator())))
6440b57cec5SDimitry Andric       KMI.clearRegisterKills(CopySrcReg, TRI);
6450b57cec5SDimitry Andric 
6460b57cec5SDimitry Andric     ++NumCopyForwards;
6470b57cec5SDimitry Andric     Changed = true;
6480b57cec5SDimitry Andric   }
6490b57cec5SDimitry Andric }
6500b57cec5SDimitry Andric 
651480093f4SDimitry Andric void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
652480093f4SDimitry Andric   LLVM_DEBUG(dbgs() << "MCP: ForwardCopyPropagateBlock " << MBB.getName()
653480093f4SDimitry Andric                     << "\n");
6540b57cec5SDimitry Andric 
655349cc55cSDimitry Andric   for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) {
6560b57cec5SDimitry Andric     // Analyze copies (which don't overlap themselves).
657*81ad6265SDimitry Andric     Optional<DestSourcePair> CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr);
658*81ad6265SDimitry Andric     if (CopyOperands) {
659*81ad6265SDimitry Andric 
660*81ad6265SDimitry Andric       Register RegSrc = CopyOperands->Source->getReg();
661*81ad6265SDimitry Andric       Register RegDef = CopyOperands->Destination->getReg();
662*81ad6265SDimitry Andric 
663*81ad6265SDimitry Andric       if (!TRI->regsOverlap(RegDef, RegSrc)) {
664*81ad6265SDimitry Andric         assert(RegDef.isPhysical() && RegSrc.isPhysical() &&
6650b57cec5SDimitry Andric               "MachineCopyPropagation should be run after register allocation!");
6660b57cec5SDimitry Andric 
667*81ad6265SDimitry Andric         MCRegister Def = RegDef.asMCReg();
668*81ad6265SDimitry Andric         MCRegister Src = RegSrc.asMCReg();
669e8d8bef9SDimitry Andric 
6700b57cec5SDimitry Andric         // The two copies cancel out and the source of the first copy
6710b57cec5SDimitry Andric         // hasn't been overridden, eliminate the second one. e.g.
6720b57cec5SDimitry Andric         //  %ecx = COPY %eax
6730b57cec5SDimitry Andric         //  ... nothing clobbered eax.
6740b57cec5SDimitry Andric         //  %eax = COPY %ecx
6750b57cec5SDimitry Andric         // =>
6760b57cec5SDimitry Andric         //  %ecx = COPY %eax
6770b57cec5SDimitry Andric         //
6780b57cec5SDimitry Andric         // or
6790b57cec5SDimitry Andric         //
6800b57cec5SDimitry Andric         //  %ecx = COPY %eax
6810b57cec5SDimitry Andric         //  ... nothing clobbered eax.
6820b57cec5SDimitry Andric         //  %ecx = COPY %eax
6830b57cec5SDimitry Andric         // =>
6840b57cec5SDimitry Andric         //  %ecx = COPY %eax
685349cc55cSDimitry Andric         if (eraseIfRedundant(MI, Def, Src) || eraseIfRedundant(MI, Src, Def))
6860b57cec5SDimitry Andric           continue;
6870b57cec5SDimitry Andric 
688349cc55cSDimitry Andric         forwardUses(MI);
6890b57cec5SDimitry Andric 
6900b57cec5SDimitry Andric         // Src may have been changed by forwardUses()
691*81ad6265SDimitry Andric         CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr);
692*81ad6265SDimitry Andric         Src = CopyOperands->Source->getReg().asMCReg();
6930b57cec5SDimitry Andric 
6940b57cec5SDimitry Andric         // If Src is defined by a previous copy, the previous copy cannot be
6950b57cec5SDimitry Andric         // eliminated.
696349cc55cSDimitry Andric         ReadRegister(Src, MI, RegularUse);
697349cc55cSDimitry Andric         for (const MachineOperand &MO : MI.implicit_operands()) {
6980b57cec5SDimitry Andric           if (!MO.isReg() || !MO.readsReg())
6990b57cec5SDimitry Andric             continue;
700e8d8bef9SDimitry Andric           MCRegister Reg = MO.getReg().asMCReg();
7010b57cec5SDimitry Andric           if (!Reg)
7020b57cec5SDimitry Andric             continue;
703349cc55cSDimitry Andric           ReadRegister(Reg, MI, RegularUse);
7040b57cec5SDimitry Andric         }
7050b57cec5SDimitry Andric 
706349cc55cSDimitry Andric         LLVM_DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI.dump());
7070b57cec5SDimitry Andric 
7080b57cec5SDimitry Andric         // Copy is now a candidate for deletion.
7090b57cec5SDimitry Andric         if (!MRI->isReserved(Def))
710349cc55cSDimitry Andric           MaybeDeadCopies.insert(&MI);
7110b57cec5SDimitry Andric 
7120b57cec5SDimitry Andric         // If 'Def' is previously source of another copy, then this earlier copy's
7130b57cec5SDimitry Andric         // source is no longer available. e.g.
7140b57cec5SDimitry Andric         // %xmm9 = copy %xmm2
7150b57cec5SDimitry Andric         // ...
7160b57cec5SDimitry Andric         // %xmm2 = copy %xmm0
7170b57cec5SDimitry Andric         // ...
7180b57cec5SDimitry Andric         // %xmm2 = copy %xmm9
719*81ad6265SDimitry Andric         Tracker.clobberRegister(Def, *TRI, *TII, UseCopyInstr);
720349cc55cSDimitry Andric         for (const MachineOperand &MO : MI.implicit_operands()) {
7210b57cec5SDimitry Andric           if (!MO.isReg() || !MO.isDef())
7220b57cec5SDimitry Andric             continue;
723e8d8bef9SDimitry Andric           MCRegister Reg = MO.getReg().asMCReg();
7240b57cec5SDimitry Andric           if (!Reg)
7250b57cec5SDimitry Andric             continue;
726*81ad6265SDimitry Andric           Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
7270b57cec5SDimitry Andric         }
7280b57cec5SDimitry Andric 
729*81ad6265SDimitry Andric         Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr);
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric         continue;
7320b57cec5SDimitry Andric       }
733*81ad6265SDimitry Andric     }
7340b57cec5SDimitry Andric 
7350b57cec5SDimitry Andric     // Clobber any earlyclobber regs first.
736349cc55cSDimitry Andric     for (const MachineOperand &MO : MI.operands())
7370b57cec5SDimitry Andric       if (MO.isReg() && MO.isEarlyClobber()) {
738e8d8bef9SDimitry Andric         MCRegister Reg = MO.getReg().asMCReg();
7390b57cec5SDimitry Andric         // If we have a tied earlyclobber, that means it is also read by this
7400b57cec5SDimitry Andric         // instruction, so we need to make sure we don't remove it as dead
7410b57cec5SDimitry Andric         // later.
7420b57cec5SDimitry Andric         if (MO.isTied())
743349cc55cSDimitry Andric           ReadRegister(Reg, MI, RegularUse);
744*81ad6265SDimitry Andric         Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
7450b57cec5SDimitry Andric       }
7460b57cec5SDimitry Andric 
747349cc55cSDimitry Andric     forwardUses(MI);
7480b57cec5SDimitry Andric 
7490b57cec5SDimitry Andric     // Not a copy.
750e8d8bef9SDimitry Andric     SmallVector<Register, 2> Defs;
7510b57cec5SDimitry Andric     const MachineOperand *RegMask = nullptr;
752349cc55cSDimitry Andric     for (const MachineOperand &MO : MI.operands()) {
7530b57cec5SDimitry Andric       if (MO.isRegMask())
7540b57cec5SDimitry Andric         RegMask = &MO;
7550b57cec5SDimitry Andric       if (!MO.isReg())
7560b57cec5SDimitry Andric         continue;
7578bcb0991SDimitry Andric       Register Reg = MO.getReg();
7580b57cec5SDimitry Andric       if (!Reg)
7590b57cec5SDimitry Andric         continue;
7600b57cec5SDimitry Andric 
761e8d8bef9SDimitry Andric       assert(!Reg.isVirtual() &&
7620b57cec5SDimitry Andric              "MachineCopyPropagation should be run after register allocation!");
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric       if (MO.isDef() && !MO.isEarlyClobber()) {
765e8d8bef9SDimitry Andric         Defs.push_back(Reg.asMCReg());
7660b57cec5SDimitry Andric         continue;
7678bcb0991SDimitry Andric       } else if (MO.readsReg())
768349cc55cSDimitry Andric         ReadRegister(Reg.asMCReg(), MI, MO.isDebug() ? DebugUse : RegularUse);
7690b57cec5SDimitry Andric     }
7700b57cec5SDimitry Andric 
7710b57cec5SDimitry Andric     // The instruction has a register mask operand which means that it clobbers
7720b57cec5SDimitry Andric     // a large set of registers.  Treat clobbered registers the same way as
7730b57cec5SDimitry Andric     // defined registers.
7740b57cec5SDimitry Andric     if (RegMask) {
7750b57cec5SDimitry Andric       // Erase any MaybeDeadCopies whose destination register is clobbered.
7760b57cec5SDimitry Andric       for (SmallSetVector<MachineInstr *, 8>::iterator DI =
7770b57cec5SDimitry Andric                MaybeDeadCopies.begin();
7780b57cec5SDimitry Andric            DI != MaybeDeadCopies.end();) {
7790b57cec5SDimitry Andric         MachineInstr *MaybeDead = *DI;
780*81ad6265SDimitry Andric         Optional<DestSourcePair> CopyOperands =
781*81ad6265SDimitry Andric             isCopyInstr(*MaybeDead, *TII, UseCopyInstr);
782*81ad6265SDimitry Andric         MCRegister Reg = CopyOperands->Destination->getReg().asMCReg();
7830b57cec5SDimitry Andric         assert(!MRI->isReserved(Reg));
7840b57cec5SDimitry Andric 
7850b57cec5SDimitry Andric         if (!RegMask->clobbersPhysReg(Reg)) {
7860b57cec5SDimitry Andric           ++DI;
7870b57cec5SDimitry Andric           continue;
7880b57cec5SDimitry Andric         }
7890b57cec5SDimitry Andric 
7900b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: ";
7910b57cec5SDimitry Andric                    MaybeDead->dump());
7920b57cec5SDimitry Andric 
7930b57cec5SDimitry Andric         // Make sure we invalidate any entries in the copy maps before erasing
7940b57cec5SDimitry Andric         // the instruction.
795*81ad6265SDimitry Andric         Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
7960b57cec5SDimitry Andric 
7970b57cec5SDimitry Andric         // erase() will return the next valid iterator pointing to the next
7980b57cec5SDimitry Andric         // element after the erased one.
7990b57cec5SDimitry Andric         DI = MaybeDeadCopies.erase(DI);
8000b57cec5SDimitry Andric         MaybeDead->eraseFromParent();
8010b57cec5SDimitry Andric         Changed = true;
8020b57cec5SDimitry Andric         ++NumDeletes;
8030b57cec5SDimitry Andric       }
8040b57cec5SDimitry Andric     }
8050b57cec5SDimitry Andric 
8060b57cec5SDimitry Andric     // Any previous copy definition or reading the Defs is no longer available.
807e8d8bef9SDimitry Andric     for (MCRegister Reg : Defs)
808*81ad6265SDimitry Andric       Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
8090b57cec5SDimitry Andric   }
8100b57cec5SDimitry Andric 
8110b57cec5SDimitry Andric   // If MBB doesn't have successors, delete the copies whose defs are not used.
8120b57cec5SDimitry Andric   // If MBB does have successors, then conservative assume the defs are live-out
8130b57cec5SDimitry Andric   // since we don't want to trust live-in lists.
8140b57cec5SDimitry Andric   if (MBB.succ_empty()) {
8150b57cec5SDimitry Andric     for (MachineInstr *MaybeDead : MaybeDeadCopies) {
8160b57cec5SDimitry Andric       LLVM_DEBUG(dbgs() << "MCP: Removing copy due to no live-out succ: ";
8170b57cec5SDimitry Andric                  MaybeDead->dump());
818*81ad6265SDimitry Andric 
819*81ad6265SDimitry Andric       Optional<DestSourcePair> CopyOperands =
820*81ad6265SDimitry Andric           isCopyInstr(*MaybeDead, *TII, UseCopyInstr);
821*81ad6265SDimitry Andric       assert(CopyOperands);
822*81ad6265SDimitry Andric 
823*81ad6265SDimitry Andric       Register SrcReg = CopyOperands->Source->getReg();
824*81ad6265SDimitry Andric       Register DestReg = CopyOperands->Destination->getReg();
825*81ad6265SDimitry Andric       assert(!MRI->isReserved(DestReg));
8260b57cec5SDimitry Andric 
8278bcb0991SDimitry Andric       // Update matching debug values, if any.
828fe6060f1SDimitry Andric       SmallVector<MachineInstr *> MaybeDeadDbgUsers(
829fe6060f1SDimitry Andric           CopyDbgUsers[MaybeDead].begin(), CopyDbgUsers[MaybeDead].end());
830fe6060f1SDimitry Andric       MRI->updateDbgUsersToReg(DestReg.asMCReg(), SrcReg.asMCReg(),
831fe6060f1SDimitry Andric                                MaybeDeadDbgUsers);
8320b57cec5SDimitry Andric 
8330b57cec5SDimitry Andric       MaybeDead->eraseFromParent();
8340b57cec5SDimitry Andric       Changed = true;
8350b57cec5SDimitry Andric       ++NumDeletes;
8360b57cec5SDimitry Andric     }
8370b57cec5SDimitry Andric   }
8380b57cec5SDimitry Andric 
8390b57cec5SDimitry Andric   MaybeDeadCopies.clear();
8408bcb0991SDimitry Andric   CopyDbgUsers.clear();
8410b57cec5SDimitry Andric   Tracker.clear();
8420b57cec5SDimitry Andric }
8430b57cec5SDimitry Andric 
844480093f4SDimitry Andric static bool isBackwardPropagatableCopy(MachineInstr &MI,
845*81ad6265SDimitry Andric                                        const MachineRegisterInfo &MRI,
846*81ad6265SDimitry Andric                                        const TargetInstrInfo &TII,
847*81ad6265SDimitry Andric                                        bool UseCopyInstr) {
848*81ad6265SDimitry Andric   Optional<DestSourcePair> CopyOperands = isCopyInstr(MI, TII, UseCopyInstr);
849*81ad6265SDimitry Andric   assert(CopyOperands && "MI is expected to be a COPY");
850*81ad6265SDimitry Andric 
851*81ad6265SDimitry Andric   Register Def = CopyOperands->Destination->getReg();
852*81ad6265SDimitry Andric   Register Src = CopyOperands->Source->getReg();
853480093f4SDimitry Andric 
854480093f4SDimitry Andric   if (!Def || !Src)
855480093f4SDimitry Andric     return false;
856480093f4SDimitry Andric 
857480093f4SDimitry Andric   if (MRI.isReserved(Def) || MRI.isReserved(Src))
858480093f4SDimitry Andric     return false;
859480093f4SDimitry Andric 
860*81ad6265SDimitry Andric   return CopyOperands->Source->isRenamable() && CopyOperands->Source->isKill();
861480093f4SDimitry Andric }
862480093f4SDimitry Andric 
863480093f4SDimitry Andric void MachineCopyPropagation::propagateDefs(MachineInstr &MI) {
864480093f4SDimitry Andric   if (!Tracker.hasAnyCopies())
865480093f4SDimitry Andric     return;
866480093f4SDimitry Andric 
867480093f4SDimitry Andric   for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx != OpEnd;
868480093f4SDimitry Andric        ++OpIdx) {
869480093f4SDimitry Andric     MachineOperand &MODef = MI.getOperand(OpIdx);
870480093f4SDimitry Andric 
871480093f4SDimitry Andric     if (!MODef.isReg() || MODef.isUse())
872480093f4SDimitry Andric       continue;
873480093f4SDimitry Andric 
874480093f4SDimitry Andric     // Ignore non-trivial cases.
875480093f4SDimitry Andric     if (MODef.isTied() || MODef.isUndef() || MODef.isImplicit())
876480093f4SDimitry Andric       continue;
877480093f4SDimitry Andric 
878480093f4SDimitry Andric     if (!MODef.getReg())
879480093f4SDimitry Andric       continue;
880480093f4SDimitry Andric 
881480093f4SDimitry Andric     // We only handle if the register comes from a vreg.
882480093f4SDimitry Andric     if (!MODef.isRenamable())
883480093f4SDimitry Andric       continue;
884480093f4SDimitry Andric 
885*81ad6265SDimitry Andric     MachineInstr *Copy = Tracker.findAvailBackwardCopy(
886*81ad6265SDimitry Andric         MI, MODef.getReg().asMCReg(), *TRI, *TII, UseCopyInstr);
887480093f4SDimitry Andric     if (!Copy)
888480093f4SDimitry Andric       continue;
889480093f4SDimitry Andric 
890*81ad6265SDimitry Andric     Optional<DestSourcePair> CopyOperands =
891*81ad6265SDimitry Andric         isCopyInstr(*Copy, *TII, UseCopyInstr);
892*81ad6265SDimitry Andric     Register Def = CopyOperands->Destination->getReg();
893*81ad6265SDimitry Andric     Register Src = CopyOperands->Source->getReg();
894480093f4SDimitry Andric 
895480093f4SDimitry Andric     if (MODef.getReg() != Src)
896480093f4SDimitry Andric       continue;
897480093f4SDimitry Andric 
898480093f4SDimitry Andric     if (!isBackwardPropagatableRegClassCopy(*Copy, MI, OpIdx))
899480093f4SDimitry Andric       continue;
900480093f4SDimitry Andric 
901480093f4SDimitry Andric     if (hasImplicitOverlap(MI, MODef))
902480093f4SDimitry Andric       continue;
903480093f4SDimitry Andric 
904e8d8bef9SDimitry Andric     if (hasOverlappingMultipleDef(MI, MODef, Def))
905e8d8bef9SDimitry Andric       continue;
906e8d8bef9SDimitry Andric 
907480093f4SDimitry Andric     LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MODef.getReg(), TRI)
908480093f4SDimitry Andric                       << "\n     with " << printReg(Def, TRI) << "\n     in "
909480093f4SDimitry Andric                       << MI << "     from " << *Copy);
910480093f4SDimitry Andric 
911480093f4SDimitry Andric     MODef.setReg(Def);
912*81ad6265SDimitry Andric     MODef.setIsRenamable(CopyOperands->Destination->isRenamable());
913480093f4SDimitry Andric 
914480093f4SDimitry Andric     LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
915480093f4SDimitry Andric     MaybeDeadCopies.insert(Copy);
916480093f4SDimitry Andric     Changed = true;
917480093f4SDimitry Andric     ++NumCopyBackwardPropagated;
918480093f4SDimitry Andric   }
919480093f4SDimitry Andric }
920480093f4SDimitry Andric 
921480093f4SDimitry Andric void MachineCopyPropagation::BackwardCopyPropagateBlock(
922480093f4SDimitry Andric     MachineBasicBlock &MBB) {
923480093f4SDimitry Andric   LLVM_DEBUG(dbgs() << "MCP: BackwardCopyPropagateBlock " << MBB.getName()
924480093f4SDimitry Andric                     << "\n");
925480093f4SDimitry Andric 
9260eae32dcSDimitry Andric   for (MachineInstr &MI : llvm::make_early_inc_range(llvm::reverse(MBB))) {
927480093f4SDimitry Andric     // Ignore non-trivial COPYs.
928*81ad6265SDimitry Andric     Optional<DestSourcePair> CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr);
929*81ad6265SDimitry Andric     if (CopyOperands && MI.getNumOperands() == 2) {
930*81ad6265SDimitry Andric       Register DefReg = CopyOperands->Destination->getReg();
931*81ad6265SDimitry Andric       Register SrcReg = CopyOperands->Source->getReg();
932480093f4SDimitry Andric 
933*81ad6265SDimitry Andric       if (!TRI->regsOverlap(DefReg, SrcReg)) {
934*81ad6265SDimitry Andric         MCRegister Def = DefReg.asMCReg();
935*81ad6265SDimitry Andric         MCRegister Src = SrcReg.asMCReg();
936480093f4SDimitry Andric 
937480093f4SDimitry Andric         // Unlike forward cp, we don't invoke propagateDefs here,
938480093f4SDimitry Andric         // just let forward cp do COPY-to-COPY propagation.
939*81ad6265SDimitry Andric         if (isBackwardPropagatableCopy(MI, *MRI, *TII, UseCopyInstr)) {
940*81ad6265SDimitry Andric           Tracker.invalidateRegister(Src, *TRI, *TII, UseCopyInstr);
941*81ad6265SDimitry Andric           Tracker.invalidateRegister(Def, *TRI, *TII, UseCopyInstr);
942*81ad6265SDimitry Andric           Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr);
943480093f4SDimitry Andric           continue;
944480093f4SDimitry Andric         }
945480093f4SDimitry Andric       }
946*81ad6265SDimitry Andric     }
947480093f4SDimitry Andric 
948480093f4SDimitry Andric     // Invalidate any earlyclobber regs first.
9490eae32dcSDimitry Andric     for (const MachineOperand &MO : MI.operands())
950480093f4SDimitry Andric       if (MO.isReg() && MO.isEarlyClobber()) {
951e8d8bef9SDimitry Andric         MCRegister Reg = MO.getReg().asMCReg();
952480093f4SDimitry Andric         if (!Reg)
953480093f4SDimitry Andric           continue;
954*81ad6265SDimitry Andric         Tracker.invalidateRegister(Reg, *TRI, *TII, UseCopyInstr);
955480093f4SDimitry Andric       }
956480093f4SDimitry Andric 
9570eae32dcSDimitry Andric     propagateDefs(MI);
9580eae32dcSDimitry Andric     for (const MachineOperand &MO : MI.operands()) {
959480093f4SDimitry Andric       if (!MO.isReg())
960480093f4SDimitry Andric         continue;
961480093f4SDimitry Andric 
962480093f4SDimitry Andric       if (!MO.getReg())
963480093f4SDimitry Andric         continue;
964480093f4SDimitry Andric 
965480093f4SDimitry Andric       if (MO.isDef())
966*81ad6265SDimitry Andric         Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII,
967*81ad6265SDimitry Andric                                    UseCopyInstr);
968480093f4SDimitry Andric 
969fe6060f1SDimitry Andric       if (MO.readsReg()) {
970fe6060f1SDimitry Andric         if (MO.isDebug()) {
971fe6060f1SDimitry Andric           //  Check if the register in the debug instruction is utilized
972fe6060f1SDimitry Andric           // in a copy instruction, so we can update the debug info if the
973fe6060f1SDimitry Andric           // register is changed.
974fe6060f1SDimitry Andric           for (MCRegUnitIterator RUI(MO.getReg().asMCReg(), TRI); RUI.isValid();
975fe6060f1SDimitry Andric                ++RUI) {
976fe6060f1SDimitry Andric             if (auto *Copy = Tracker.findCopyDefViaUnit(*RUI, *TRI)) {
9770eae32dcSDimitry Andric               CopyDbgUsers[Copy].insert(&MI);
978fe6060f1SDimitry Andric             }
979fe6060f1SDimitry Andric           }
980fe6060f1SDimitry Andric         } else {
981*81ad6265SDimitry Andric           Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII,
982*81ad6265SDimitry Andric                                      UseCopyInstr);
983480093f4SDimitry Andric         }
984480093f4SDimitry Andric       }
985fe6060f1SDimitry Andric     }
986fe6060f1SDimitry Andric   }
987480093f4SDimitry Andric 
988480093f4SDimitry Andric   for (auto *Copy : MaybeDeadCopies) {
989fe6060f1SDimitry Andric 
990*81ad6265SDimitry Andric     Optional<DestSourcePair> CopyOperands =
991*81ad6265SDimitry Andric         isCopyInstr(*Copy, *TII, UseCopyInstr);
992*81ad6265SDimitry Andric     Register Src = CopyOperands->Source->getReg();
993*81ad6265SDimitry Andric     Register Def = CopyOperands->Destination->getReg();
994fe6060f1SDimitry Andric     SmallVector<MachineInstr *> MaybeDeadDbgUsers(CopyDbgUsers[Copy].begin(),
995fe6060f1SDimitry Andric                                                   CopyDbgUsers[Copy].end());
996fe6060f1SDimitry Andric 
997fe6060f1SDimitry Andric     MRI->updateDbgUsersToReg(Src.asMCReg(), Def.asMCReg(), MaybeDeadDbgUsers);
998480093f4SDimitry Andric     Copy->eraseFromParent();
999480093f4SDimitry Andric     ++NumDeletes;
1000480093f4SDimitry Andric   }
1001480093f4SDimitry Andric 
1002480093f4SDimitry Andric   MaybeDeadCopies.clear();
1003480093f4SDimitry Andric   CopyDbgUsers.clear();
1004480093f4SDimitry Andric   Tracker.clear();
1005480093f4SDimitry Andric }
1006480093f4SDimitry Andric 
10070b57cec5SDimitry Andric bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) {
10080b57cec5SDimitry Andric   if (skipFunction(MF.getFunction()))
10090b57cec5SDimitry Andric     return false;
10100b57cec5SDimitry Andric 
10110b57cec5SDimitry Andric   Changed = false;
10120b57cec5SDimitry Andric 
10130b57cec5SDimitry Andric   TRI = MF.getSubtarget().getRegisterInfo();
10140b57cec5SDimitry Andric   TII = MF.getSubtarget().getInstrInfo();
10150b57cec5SDimitry Andric   MRI = &MF.getRegInfo();
10160b57cec5SDimitry Andric 
1017480093f4SDimitry Andric   for (MachineBasicBlock &MBB : MF) {
1018480093f4SDimitry Andric     BackwardCopyPropagateBlock(MBB);
1019480093f4SDimitry Andric     ForwardCopyPropagateBlock(MBB);
1020480093f4SDimitry Andric   }
10210b57cec5SDimitry Andric 
10220b57cec5SDimitry Andric   return Changed;
10230b57cec5SDimitry Andric }
1024*81ad6265SDimitry Andric 
1025*81ad6265SDimitry Andric MachineFunctionPass *
1026*81ad6265SDimitry Andric llvm::createMachineCopyPropagationPass(bool UseCopyInstr = false) {
1027*81ad6265SDimitry Andric   return new MachineCopyPropagation(UseCopyInstr);
1028*81ad6265SDimitry Andric }
1029