xref: /openbsd-src/gnu/llvm/llvm/lib/CodeGen/MachineCopyPropagation.cpp (revision 73471bf04ceb096474c7f0fa83b1b65c70a787a1)
109467b48Spatrick //===- MachineCopyPropagation.cpp - Machine Copy Propagation Pass ---------===//
209467b48Spatrick //
309467b48Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
409467b48Spatrick // See https://llvm.org/LICENSE.txt for license information.
509467b48Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
609467b48Spatrick //
709467b48Spatrick //===----------------------------------------------------------------------===//
809467b48Spatrick //
909467b48Spatrick // This is an extremely simple MachineInstr-level copy propagation pass.
1009467b48Spatrick //
1109467b48Spatrick // This pass forwards the source of COPYs to the users of their destinations
1209467b48Spatrick // when doing so is legal.  For example:
1309467b48Spatrick //
1409467b48Spatrick //   %reg1 = COPY %reg0
1509467b48Spatrick //   ...
1609467b48Spatrick //   ... = OP %reg1
1709467b48Spatrick //
1809467b48Spatrick // If
1909467b48Spatrick //   - %reg0 has not been clobbered by the time of the use of %reg1
2009467b48Spatrick //   - the register class constraints are satisfied
2109467b48Spatrick //   - the COPY def is the only value that reaches OP
2209467b48Spatrick // then this pass replaces the above with:
2309467b48Spatrick //
2409467b48Spatrick //   %reg1 = COPY %reg0
2509467b48Spatrick //   ...
2609467b48Spatrick //   ... = OP %reg0
2709467b48Spatrick //
2809467b48Spatrick // This pass also removes some redundant COPYs.  For example:
2909467b48Spatrick //
3009467b48Spatrick //    %R1 = COPY %R0
3109467b48Spatrick //    ... // No clobber of %R1
3209467b48Spatrick //    %R0 = COPY %R1 <<< Removed
3309467b48Spatrick //
3409467b48Spatrick // or
3509467b48Spatrick //
3609467b48Spatrick //    %R1 = COPY %R0
3709467b48Spatrick //    ... // No clobber of %R0
3809467b48Spatrick //    %R1 = COPY %R0 <<< Removed
3909467b48Spatrick //
4009467b48Spatrick // or
4109467b48Spatrick //
4209467b48Spatrick //    $R0 = OP ...
4309467b48Spatrick //    ... // No read/clobber of $R0 and $R1
4409467b48Spatrick //    $R1 = COPY $R0 // $R0 is killed
4509467b48Spatrick // Replace $R0 with $R1 and remove the COPY
4609467b48Spatrick //    $R1 = OP ...
4709467b48Spatrick //    ...
4809467b48Spatrick //
4909467b48Spatrick //===----------------------------------------------------------------------===//
5009467b48Spatrick 
5109467b48Spatrick #include "llvm/ADT/DenseMap.h"
5209467b48Spatrick #include "llvm/ADT/STLExtras.h"
5309467b48Spatrick #include "llvm/ADT/SetVector.h"
54097a140dSpatrick #include "llvm/ADT/SmallSet.h"
5509467b48Spatrick #include "llvm/ADT/SmallVector.h"
5609467b48Spatrick #include "llvm/ADT/Statistic.h"
5709467b48Spatrick #include "llvm/ADT/iterator_range.h"
5809467b48Spatrick #include "llvm/CodeGen/MachineBasicBlock.h"
5909467b48Spatrick #include "llvm/CodeGen/MachineFunction.h"
6009467b48Spatrick #include "llvm/CodeGen/MachineFunctionPass.h"
6109467b48Spatrick #include "llvm/CodeGen/MachineInstr.h"
6209467b48Spatrick #include "llvm/CodeGen/MachineOperand.h"
6309467b48Spatrick #include "llvm/CodeGen/MachineRegisterInfo.h"
6409467b48Spatrick #include "llvm/CodeGen/TargetInstrInfo.h"
6509467b48Spatrick #include "llvm/CodeGen/TargetRegisterInfo.h"
6609467b48Spatrick #include "llvm/CodeGen/TargetSubtargetInfo.h"
6709467b48Spatrick #include "llvm/InitializePasses.h"
6809467b48Spatrick #include "llvm/MC/MCRegisterInfo.h"
6909467b48Spatrick #include "llvm/Pass.h"
7009467b48Spatrick #include "llvm/Support/Debug.h"
7109467b48Spatrick #include "llvm/Support/DebugCounter.h"
7209467b48Spatrick #include "llvm/Support/raw_ostream.h"
7309467b48Spatrick #include <cassert>
7409467b48Spatrick #include <iterator>
7509467b48Spatrick 
7609467b48Spatrick using namespace llvm;
7709467b48Spatrick 
7809467b48Spatrick #define DEBUG_TYPE "machine-cp"
7909467b48Spatrick 
8009467b48Spatrick STATISTIC(NumDeletes, "Number of dead copies deleted");
8109467b48Spatrick STATISTIC(NumCopyForwards, "Number of copy uses forwarded");
8209467b48Spatrick STATISTIC(NumCopyBackwardPropagated, "Number of copy defs backward propagated");
8309467b48Spatrick DEBUG_COUNTER(FwdCounter, "machine-cp-fwd",
8409467b48Spatrick               "Controls which register COPYs are forwarded");
8509467b48Spatrick 
8609467b48Spatrick namespace {
8709467b48Spatrick 
8809467b48Spatrick class CopyTracker {
8909467b48Spatrick   struct CopyInfo {
9009467b48Spatrick     MachineInstr *MI;
91*73471bf0Spatrick     SmallVector<MCRegister, 4> DefRegs;
9209467b48Spatrick     bool Avail;
9309467b48Spatrick   };
9409467b48Spatrick 
95*73471bf0Spatrick   DenseMap<MCRegister, CopyInfo> Copies;
9609467b48Spatrick 
9709467b48Spatrick public:
9809467b48Spatrick   /// Mark all of the given registers and their subregisters as unavailable for
9909467b48Spatrick   /// copying.
100*73471bf0Spatrick   void markRegsUnavailable(ArrayRef<MCRegister> Regs,
10109467b48Spatrick                            const TargetRegisterInfo &TRI) {
102*73471bf0Spatrick     for (MCRegister Reg : Regs) {
10309467b48Spatrick       // Source of copy is no longer available for propagation.
10409467b48Spatrick       for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
10509467b48Spatrick         auto CI = Copies.find(*RUI);
10609467b48Spatrick         if (CI != Copies.end())
10709467b48Spatrick           CI->second.Avail = false;
10809467b48Spatrick       }
10909467b48Spatrick     }
11009467b48Spatrick   }
11109467b48Spatrick 
11209467b48Spatrick   /// Remove register from copy maps.
113*73471bf0Spatrick   void invalidateRegister(MCRegister Reg, const TargetRegisterInfo &TRI) {
11409467b48Spatrick     // Since Reg might be a subreg of some registers, only invalidate Reg is not
11509467b48Spatrick     // enough. We have to find the COPY defines Reg or registers defined by Reg
11609467b48Spatrick     // and invalidate all of them.
117*73471bf0Spatrick     SmallSet<MCRegister, 8> RegsToInvalidate;
118097a140dSpatrick     RegsToInvalidate.insert(Reg);
11909467b48Spatrick     for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
12009467b48Spatrick       auto I = Copies.find(*RUI);
12109467b48Spatrick       if (I != Copies.end()) {
12209467b48Spatrick         if (MachineInstr *MI = I->second.MI) {
123*73471bf0Spatrick           RegsToInvalidate.insert(MI->getOperand(0).getReg().asMCReg());
124*73471bf0Spatrick           RegsToInvalidate.insert(MI->getOperand(1).getReg().asMCReg());
12509467b48Spatrick         }
12609467b48Spatrick         RegsToInvalidate.insert(I->second.DefRegs.begin(),
12709467b48Spatrick                                 I->second.DefRegs.end());
12809467b48Spatrick       }
12909467b48Spatrick     }
130*73471bf0Spatrick     for (MCRegister InvalidReg : RegsToInvalidate)
13109467b48Spatrick       for (MCRegUnitIterator RUI(InvalidReg, &TRI); RUI.isValid(); ++RUI)
13209467b48Spatrick         Copies.erase(*RUI);
13309467b48Spatrick   }
13409467b48Spatrick 
13509467b48Spatrick   /// Clobber a single register, removing it from the tracker's copy maps.
136*73471bf0Spatrick   void clobberRegister(MCRegister Reg, const TargetRegisterInfo &TRI) {
13709467b48Spatrick     for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
13809467b48Spatrick       auto I = Copies.find(*RUI);
13909467b48Spatrick       if (I != Copies.end()) {
14009467b48Spatrick         // When we clobber the source of a copy, we need to clobber everything
14109467b48Spatrick         // it defined.
14209467b48Spatrick         markRegsUnavailable(I->second.DefRegs, TRI);
14309467b48Spatrick         // When we clobber the destination of a copy, we need to clobber the
14409467b48Spatrick         // whole register it defined.
14509467b48Spatrick         if (MachineInstr *MI = I->second.MI)
146*73471bf0Spatrick           markRegsUnavailable({MI->getOperand(0).getReg().asMCReg()}, TRI);
14709467b48Spatrick         // Now we can erase the copy.
14809467b48Spatrick         Copies.erase(I);
14909467b48Spatrick       }
15009467b48Spatrick     }
15109467b48Spatrick   }
15209467b48Spatrick 
15309467b48Spatrick   /// Add this copy's registers into the tracker's copy maps.
15409467b48Spatrick   void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI) {
15509467b48Spatrick     assert(MI->isCopy() && "Tracking non-copy?");
15609467b48Spatrick 
157*73471bf0Spatrick     MCRegister Def = MI->getOperand(0).getReg().asMCReg();
158*73471bf0Spatrick     MCRegister Src = MI->getOperand(1).getReg().asMCReg();
15909467b48Spatrick 
16009467b48Spatrick     // Remember Def is defined by the copy.
16109467b48Spatrick     for (MCRegUnitIterator RUI(Def, &TRI); RUI.isValid(); ++RUI)
16209467b48Spatrick       Copies[*RUI] = {MI, {}, true};
16309467b48Spatrick 
16409467b48Spatrick     // Remember source that's copied to Def. Once it's clobbered, then
16509467b48Spatrick     // it's no longer available for copy propagation.
16609467b48Spatrick     for (MCRegUnitIterator RUI(Src, &TRI); RUI.isValid(); ++RUI) {
16709467b48Spatrick       auto I = Copies.insert({*RUI, {nullptr, {}, false}});
16809467b48Spatrick       auto &Copy = I.first->second;
16909467b48Spatrick       if (!is_contained(Copy.DefRegs, Def))
17009467b48Spatrick         Copy.DefRegs.push_back(Def);
17109467b48Spatrick     }
17209467b48Spatrick   }
17309467b48Spatrick 
17409467b48Spatrick   bool hasAnyCopies() {
17509467b48Spatrick     return !Copies.empty();
17609467b48Spatrick   }
17709467b48Spatrick 
178*73471bf0Spatrick   MachineInstr *findCopyForUnit(MCRegister RegUnit,
179*73471bf0Spatrick                                 const TargetRegisterInfo &TRI,
18009467b48Spatrick                                 bool MustBeAvailable = false) {
18109467b48Spatrick     auto CI = Copies.find(RegUnit);
18209467b48Spatrick     if (CI == Copies.end())
18309467b48Spatrick       return nullptr;
18409467b48Spatrick     if (MustBeAvailable && !CI->second.Avail)
18509467b48Spatrick       return nullptr;
18609467b48Spatrick     return CI->second.MI;
18709467b48Spatrick   }
18809467b48Spatrick 
189*73471bf0Spatrick   MachineInstr *findCopyDefViaUnit(MCRegister RegUnit,
19009467b48Spatrick                                    const TargetRegisterInfo &TRI) {
19109467b48Spatrick     auto CI = Copies.find(RegUnit);
19209467b48Spatrick     if (CI == Copies.end())
19309467b48Spatrick       return nullptr;
19409467b48Spatrick     if (CI->second.DefRegs.size() != 1)
19509467b48Spatrick       return nullptr;
19609467b48Spatrick     MCRegUnitIterator RUI(CI->second.DefRegs[0], &TRI);
19709467b48Spatrick     return findCopyForUnit(*RUI, TRI, true);
19809467b48Spatrick   }
19909467b48Spatrick 
200*73471bf0Spatrick   MachineInstr *findAvailBackwardCopy(MachineInstr &I, MCRegister Reg,
20109467b48Spatrick                                       const TargetRegisterInfo &TRI) {
20209467b48Spatrick     MCRegUnitIterator RUI(Reg, &TRI);
20309467b48Spatrick     MachineInstr *AvailCopy = findCopyDefViaUnit(*RUI, TRI);
20409467b48Spatrick     if (!AvailCopy ||
20509467b48Spatrick         !TRI.isSubRegisterEq(AvailCopy->getOperand(1).getReg(), Reg))
20609467b48Spatrick       return nullptr;
20709467b48Spatrick 
20809467b48Spatrick     Register AvailSrc = AvailCopy->getOperand(1).getReg();
20909467b48Spatrick     Register AvailDef = AvailCopy->getOperand(0).getReg();
21009467b48Spatrick     for (const MachineInstr &MI :
21109467b48Spatrick          make_range(AvailCopy->getReverseIterator(), I.getReverseIterator()))
21209467b48Spatrick       for (const MachineOperand &MO : MI.operands())
21309467b48Spatrick         if (MO.isRegMask())
21409467b48Spatrick           // FIXME: Shall we simultaneously invalidate AvailSrc or AvailDef?
21509467b48Spatrick           if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
21609467b48Spatrick             return nullptr;
21709467b48Spatrick 
21809467b48Spatrick     return AvailCopy;
21909467b48Spatrick   }
22009467b48Spatrick 
221*73471bf0Spatrick   MachineInstr *findAvailCopy(MachineInstr &DestCopy, MCRegister Reg,
22209467b48Spatrick                               const TargetRegisterInfo &TRI) {
22309467b48Spatrick     // We check the first RegUnit here, since we'll only be interested in the
22409467b48Spatrick     // copy if it copies the entire register anyway.
22509467b48Spatrick     MCRegUnitIterator RUI(Reg, &TRI);
22609467b48Spatrick     MachineInstr *AvailCopy =
22709467b48Spatrick         findCopyForUnit(*RUI, TRI, /*MustBeAvailable=*/true);
22809467b48Spatrick     if (!AvailCopy ||
22909467b48Spatrick         !TRI.isSubRegisterEq(AvailCopy->getOperand(0).getReg(), Reg))
23009467b48Spatrick       return nullptr;
23109467b48Spatrick 
23209467b48Spatrick     // Check that the available copy isn't clobbered by any regmasks between
23309467b48Spatrick     // itself and the destination.
23409467b48Spatrick     Register AvailSrc = AvailCopy->getOperand(1).getReg();
23509467b48Spatrick     Register AvailDef = AvailCopy->getOperand(0).getReg();
23609467b48Spatrick     for (const MachineInstr &MI :
23709467b48Spatrick          make_range(AvailCopy->getIterator(), DestCopy.getIterator()))
23809467b48Spatrick       for (const MachineOperand &MO : MI.operands())
23909467b48Spatrick         if (MO.isRegMask())
24009467b48Spatrick           if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
24109467b48Spatrick             return nullptr;
24209467b48Spatrick 
24309467b48Spatrick     return AvailCopy;
24409467b48Spatrick   }
24509467b48Spatrick 
24609467b48Spatrick   void clear() {
24709467b48Spatrick     Copies.clear();
24809467b48Spatrick   }
24909467b48Spatrick };
25009467b48Spatrick 
25109467b48Spatrick class MachineCopyPropagation : public MachineFunctionPass {
25209467b48Spatrick   const TargetRegisterInfo *TRI;
25309467b48Spatrick   const TargetInstrInfo *TII;
25409467b48Spatrick   const MachineRegisterInfo *MRI;
25509467b48Spatrick 
25609467b48Spatrick public:
25709467b48Spatrick   static char ID; // Pass identification, replacement for typeid
25809467b48Spatrick 
25909467b48Spatrick   MachineCopyPropagation() : MachineFunctionPass(ID) {
26009467b48Spatrick     initializeMachineCopyPropagationPass(*PassRegistry::getPassRegistry());
26109467b48Spatrick   }
26209467b48Spatrick 
26309467b48Spatrick   void getAnalysisUsage(AnalysisUsage &AU) const override {
26409467b48Spatrick     AU.setPreservesCFG();
26509467b48Spatrick     MachineFunctionPass::getAnalysisUsage(AU);
26609467b48Spatrick   }
26709467b48Spatrick 
26809467b48Spatrick   bool runOnMachineFunction(MachineFunction &MF) override;
26909467b48Spatrick 
27009467b48Spatrick   MachineFunctionProperties getRequiredProperties() const override {
27109467b48Spatrick     return MachineFunctionProperties().set(
27209467b48Spatrick         MachineFunctionProperties::Property::NoVRegs);
27309467b48Spatrick   }
27409467b48Spatrick 
27509467b48Spatrick private:
27609467b48Spatrick   typedef enum { DebugUse = false, RegularUse = true } DebugType;
27709467b48Spatrick 
278*73471bf0Spatrick   void ReadRegister(MCRegister Reg, MachineInstr &Reader, DebugType DT);
27909467b48Spatrick   void ForwardCopyPropagateBlock(MachineBasicBlock &MBB);
28009467b48Spatrick   void BackwardCopyPropagateBlock(MachineBasicBlock &MBB);
281*73471bf0Spatrick   bool eraseIfRedundant(MachineInstr &Copy, MCRegister Src, MCRegister Def);
28209467b48Spatrick   void forwardUses(MachineInstr &MI);
28309467b48Spatrick   void propagateDefs(MachineInstr &MI);
28409467b48Spatrick   bool isForwardableRegClassCopy(const MachineInstr &Copy,
28509467b48Spatrick                                  const MachineInstr &UseI, unsigned UseIdx);
28609467b48Spatrick   bool isBackwardPropagatableRegClassCopy(const MachineInstr &Copy,
28709467b48Spatrick                                           const MachineInstr &UseI,
28809467b48Spatrick                                           unsigned UseIdx);
28909467b48Spatrick   bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use);
290*73471bf0Spatrick   bool hasOverlappingMultipleDef(const MachineInstr &MI,
291*73471bf0Spatrick                                  const MachineOperand &MODef, Register Def);
29209467b48Spatrick 
29309467b48Spatrick   /// Candidates for deletion.
29409467b48Spatrick   SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
29509467b48Spatrick 
29609467b48Spatrick   /// Multimap tracking debug users in current BB
297*73471bf0Spatrick   DenseMap<MachineInstr *, SmallSet<MachineInstr *, 2>> CopyDbgUsers;
29809467b48Spatrick 
29909467b48Spatrick   CopyTracker Tracker;
30009467b48Spatrick 
30109467b48Spatrick   bool Changed;
30209467b48Spatrick };
30309467b48Spatrick 
30409467b48Spatrick } // end anonymous namespace
30509467b48Spatrick 
30609467b48Spatrick char MachineCopyPropagation::ID = 0;
30709467b48Spatrick 
30809467b48Spatrick char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID;
30909467b48Spatrick 
31009467b48Spatrick INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE,
31109467b48Spatrick                 "Machine Copy Propagation Pass", false, false)
31209467b48Spatrick 
313*73471bf0Spatrick void MachineCopyPropagation::ReadRegister(MCRegister Reg, MachineInstr &Reader,
31409467b48Spatrick                                           DebugType DT) {
31509467b48Spatrick   // If 'Reg' is defined by a copy, the copy is no longer a candidate
31609467b48Spatrick   // for elimination. If a copy is "read" by a debug user, record the user
31709467b48Spatrick   // for propagation.
31809467b48Spatrick   for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
31909467b48Spatrick     if (MachineInstr *Copy = Tracker.findCopyForUnit(*RUI, *TRI)) {
32009467b48Spatrick       if (DT == RegularUse) {
32109467b48Spatrick         LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; Copy->dump());
32209467b48Spatrick         MaybeDeadCopies.remove(Copy);
32309467b48Spatrick       } else {
324*73471bf0Spatrick         CopyDbgUsers[Copy].insert(&Reader);
32509467b48Spatrick       }
32609467b48Spatrick     }
32709467b48Spatrick   }
32809467b48Spatrick }
32909467b48Spatrick 
33009467b48Spatrick /// Return true if \p PreviousCopy did copy register \p Src to register \p Def.
33109467b48Spatrick /// This fact may have been obscured by sub register usage or may not be true at
33209467b48Spatrick /// all even though Src and Def are subregisters of the registers used in
33309467b48Spatrick /// PreviousCopy. e.g.
33409467b48Spatrick /// isNopCopy("ecx = COPY eax", AX, CX) == true
33509467b48Spatrick /// isNopCopy("ecx = COPY eax", AH, CL) == false
336*73471bf0Spatrick static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src,
337*73471bf0Spatrick                       MCRegister Def, const TargetRegisterInfo *TRI) {
338*73471bf0Spatrick   MCRegister PreviousSrc = PreviousCopy.getOperand(1).getReg().asMCReg();
339*73471bf0Spatrick   MCRegister PreviousDef = PreviousCopy.getOperand(0).getReg().asMCReg();
340097a140dSpatrick   if (Src == PreviousSrc && Def == PreviousDef)
34109467b48Spatrick     return true;
34209467b48Spatrick   if (!TRI->isSubRegister(PreviousSrc, Src))
34309467b48Spatrick     return false;
34409467b48Spatrick   unsigned SubIdx = TRI->getSubRegIndex(PreviousSrc, Src);
34509467b48Spatrick   return SubIdx == TRI->getSubRegIndex(PreviousDef, Def);
34609467b48Spatrick }
34709467b48Spatrick 
34809467b48Spatrick /// Remove instruction \p Copy if there exists a previous copy that copies the
34909467b48Spatrick /// register \p Src to the register \p Def; This may happen indirectly by
35009467b48Spatrick /// copying the super registers.
351*73471bf0Spatrick bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy,
352*73471bf0Spatrick                                               MCRegister Src, MCRegister Def) {
35309467b48Spatrick   // Avoid eliminating a copy from/to a reserved registers as we cannot predict
35409467b48Spatrick   // the value (Example: The sparc zero register is writable but stays zero).
35509467b48Spatrick   if (MRI->isReserved(Src) || MRI->isReserved(Def))
35609467b48Spatrick     return false;
35709467b48Spatrick 
35809467b48Spatrick   // Search for an existing copy.
35909467b48Spatrick   MachineInstr *PrevCopy = Tracker.findAvailCopy(Copy, Def, *TRI);
36009467b48Spatrick   if (!PrevCopy)
36109467b48Spatrick     return false;
36209467b48Spatrick 
36309467b48Spatrick   // Check that the existing copy uses the correct sub registers.
36409467b48Spatrick   if (PrevCopy->getOperand(0).isDead())
36509467b48Spatrick     return false;
36609467b48Spatrick   if (!isNopCopy(*PrevCopy, Src, Def, TRI))
36709467b48Spatrick     return false;
36809467b48Spatrick 
36909467b48Spatrick   LLVM_DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; Copy.dump());
37009467b48Spatrick 
37109467b48Spatrick   // Copy was redundantly redefining either Src or Def. Remove earlier kill
37209467b48Spatrick   // flags between Copy and PrevCopy because the value will be reused now.
37309467b48Spatrick   assert(Copy.isCopy());
37409467b48Spatrick   Register CopyDef = Copy.getOperand(0).getReg();
37509467b48Spatrick   assert(CopyDef == Src || CopyDef == Def);
37609467b48Spatrick   for (MachineInstr &MI :
37709467b48Spatrick        make_range(PrevCopy->getIterator(), Copy.getIterator()))
37809467b48Spatrick     MI.clearRegisterKills(CopyDef, TRI);
37909467b48Spatrick 
38009467b48Spatrick   Copy.eraseFromParent();
38109467b48Spatrick   Changed = true;
38209467b48Spatrick   ++NumDeletes;
38309467b48Spatrick   return true;
38409467b48Spatrick }
38509467b48Spatrick 
38609467b48Spatrick bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy(
38709467b48Spatrick     const MachineInstr &Copy, const MachineInstr &UseI, unsigned UseIdx) {
38809467b48Spatrick   Register Def = Copy.getOperand(0).getReg();
38909467b48Spatrick 
39009467b48Spatrick   if (const TargetRegisterClass *URC =
39109467b48Spatrick           UseI.getRegClassConstraint(UseIdx, TII, TRI))
39209467b48Spatrick     return URC->contains(Def);
39309467b48Spatrick 
39409467b48Spatrick   // We don't process further if UseI is a COPY, since forward copy propagation
39509467b48Spatrick   // should handle that.
39609467b48Spatrick   return false;
39709467b48Spatrick }
39809467b48Spatrick 
39909467b48Spatrick /// Decide whether we should forward the source of \param Copy to its use in
40009467b48Spatrick /// \param UseI based on the physical register class constraints of the opcode
40109467b48Spatrick /// and avoiding introducing more cross-class COPYs.
40209467b48Spatrick bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy,
40309467b48Spatrick                                                        const MachineInstr &UseI,
40409467b48Spatrick                                                        unsigned UseIdx) {
40509467b48Spatrick 
40609467b48Spatrick   Register CopySrcReg = Copy.getOperand(1).getReg();
40709467b48Spatrick 
40809467b48Spatrick   // If the new register meets the opcode register constraints, then allow
40909467b48Spatrick   // forwarding.
41009467b48Spatrick   if (const TargetRegisterClass *URC =
41109467b48Spatrick           UseI.getRegClassConstraint(UseIdx, TII, TRI))
41209467b48Spatrick     return URC->contains(CopySrcReg);
41309467b48Spatrick 
41409467b48Spatrick   if (!UseI.isCopy())
41509467b48Spatrick     return false;
41609467b48Spatrick 
41709467b48Spatrick   /// COPYs don't have register class constraints, so if the user instruction
41809467b48Spatrick   /// is a COPY, we just try to avoid introducing additional cross-class
41909467b48Spatrick   /// COPYs.  For example:
42009467b48Spatrick   ///
42109467b48Spatrick   ///   RegClassA = COPY RegClassB  // Copy parameter
42209467b48Spatrick   ///   ...
42309467b48Spatrick   ///   RegClassB = COPY RegClassA  // UseI parameter
42409467b48Spatrick   ///
42509467b48Spatrick   /// which after forwarding becomes
42609467b48Spatrick   ///
42709467b48Spatrick   ///   RegClassA = COPY RegClassB
42809467b48Spatrick   ///   ...
42909467b48Spatrick   ///   RegClassB = COPY RegClassB
43009467b48Spatrick   ///
43109467b48Spatrick   /// so we have reduced the number of cross-class COPYs and potentially
43209467b48Spatrick   /// introduced a nop COPY that can be removed.
43309467b48Spatrick   const TargetRegisterClass *UseDstRC =
43409467b48Spatrick       TRI->getMinimalPhysRegClass(UseI.getOperand(0).getReg());
43509467b48Spatrick 
43609467b48Spatrick   const TargetRegisterClass *SuperRC = UseDstRC;
43709467b48Spatrick   for (TargetRegisterClass::sc_iterator SuperRCI = UseDstRC->getSuperClasses();
43809467b48Spatrick        SuperRC; SuperRC = *SuperRCI++)
43909467b48Spatrick     if (SuperRC->contains(CopySrcReg))
44009467b48Spatrick       return true;
44109467b48Spatrick 
44209467b48Spatrick   return false;
44309467b48Spatrick }
44409467b48Spatrick 
44509467b48Spatrick /// Check that \p MI does not have implicit uses that overlap with it's \p Use
44609467b48Spatrick /// operand (the register being replaced), since these can sometimes be
44709467b48Spatrick /// implicitly tied to other operands.  For example, on AMDGPU:
44809467b48Spatrick ///
44909467b48Spatrick /// V_MOVRELS_B32_e32 %VGPR2, %M0<imp-use>, %EXEC<imp-use>, %VGPR2_VGPR3_VGPR4_VGPR5<imp-use>
45009467b48Spatrick ///
45109467b48Spatrick /// the %VGPR2 is implicitly tied to the larger reg operand, but we have no
45209467b48Spatrick /// way of knowing we need to update the latter when updating the former.
45309467b48Spatrick bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI,
45409467b48Spatrick                                                 const MachineOperand &Use) {
45509467b48Spatrick   for (const MachineOperand &MIUse : MI.uses())
45609467b48Spatrick     if (&MIUse != &Use && MIUse.isReg() && MIUse.isImplicit() &&
45709467b48Spatrick         MIUse.isUse() && TRI->regsOverlap(Use.getReg(), MIUse.getReg()))
45809467b48Spatrick       return true;
45909467b48Spatrick 
46009467b48Spatrick   return false;
46109467b48Spatrick }
46209467b48Spatrick 
463*73471bf0Spatrick /// For an MI that has multiple definitions, check whether \p MI has
464*73471bf0Spatrick /// a definition that overlaps with another of its definitions.
465*73471bf0Spatrick /// For example, on ARM: umull   r9, r9, lr, r0
466*73471bf0Spatrick /// The umull instruction is unpredictable unless RdHi and RdLo are different.
467*73471bf0Spatrick bool MachineCopyPropagation::hasOverlappingMultipleDef(
468*73471bf0Spatrick     const MachineInstr &MI, const MachineOperand &MODef, Register Def) {
469*73471bf0Spatrick   for (const MachineOperand &MIDef : MI.defs()) {
470*73471bf0Spatrick     if ((&MIDef != &MODef) && MIDef.isReg() &&
471*73471bf0Spatrick         TRI->regsOverlap(Def, MIDef.getReg()))
472*73471bf0Spatrick       return true;
473*73471bf0Spatrick   }
474*73471bf0Spatrick 
475*73471bf0Spatrick   return false;
476*73471bf0Spatrick }
477*73471bf0Spatrick 
47809467b48Spatrick /// Look for available copies whose destination register is used by \p MI and
47909467b48Spatrick /// replace the use in \p MI with the copy's source register.
48009467b48Spatrick void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
48109467b48Spatrick   if (!Tracker.hasAnyCopies())
48209467b48Spatrick     return;
48309467b48Spatrick 
48409467b48Spatrick   // Look for non-tied explicit vreg uses that have an active COPY
48509467b48Spatrick   // instruction that defines the physical register allocated to them.
48609467b48Spatrick   // Replace the vreg with the source of the active COPY.
48709467b48Spatrick   for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx < OpEnd;
48809467b48Spatrick        ++OpIdx) {
48909467b48Spatrick     MachineOperand &MOUse = MI.getOperand(OpIdx);
49009467b48Spatrick     // Don't forward into undef use operands since doing so can cause problems
49109467b48Spatrick     // with the machine verifier, since it doesn't treat undef reads as reads,
49209467b48Spatrick     // so we can end up with a live range that ends on an undef read, leading to
49309467b48Spatrick     // an error that the live range doesn't end on a read of the live range
49409467b48Spatrick     // register.
49509467b48Spatrick     if (!MOUse.isReg() || MOUse.isTied() || MOUse.isUndef() || MOUse.isDef() ||
49609467b48Spatrick         MOUse.isImplicit())
49709467b48Spatrick       continue;
49809467b48Spatrick 
49909467b48Spatrick     if (!MOUse.getReg())
50009467b48Spatrick       continue;
50109467b48Spatrick 
50209467b48Spatrick     // Check that the register is marked 'renamable' so we know it is safe to
50309467b48Spatrick     // rename it without violating any constraints that aren't expressed in the
50409467b48Spatrick     // IR (e.g. ABI or opcode requirements).
50509467b48Spatrick     if (!MOUse.isRenamable())
50609467b48Spatrick       continue;
50709467b48Spatrick 
508*73471bf0Spatrick     MachineInstr *Copy =
509*73471bf0Spatrick         Tracker.findAvailCopy(MI, MOUse.getReg().asMCReg(), *TRI);
51009467b48Spatrick     if (!Copy)
51109467b48Spatrick       continue;
51209467b48Spatrick 
51309467b48Spatrick     Register CopyDstReg = Copy->getOperand(0).getReg();
51409467b48Spatrick     const MachineOperand &CopySrc = Copy->getOperand(1);
51509467b48Spatrick     Register CopySrcReg = CopySrc.getReg();
51609467b48Spatrick 
51709467b48Spatrick     // FIXME: Don't handle partial uses of wider COPYs yet.
51809467b48Spatrick     if (MOUse.getReg() != CopyDstReg) {
51909467b48Spatrick       LLVM_DEBUG(
52009467b48Spatrick           dbgs() << "MCP: FIXME! Not forwarding COPY to sub-register use:\n  "
52109467b48Spatrick                  << MI);
52209467b48Spatrick       continue;
52309467b48Spatrick     }
52409467b48Spatrick 
52509467b48Spatrick     // Don't forward COPYs of reserved regs unless they are constant.
52609467b48Spatrick     if (MRI->isReserved(CopySrcReg) && !MRI->isConstantPhysReg(CopySrcReg))
52709467b48Spatrick       continue;
52809467b48Spatrick 
52909467b48Spatrick     if (!isForwardableRegClassCopy(*Copy, MI, OpIdx))
53009467b48Spatrick       continue;
53109467b48Spatrick 
53209467b48Spatrick     if (hasImplicitOverlap(MI, MOUse))
53309467b48Spatrick       continue;
53409467b48Spatrick 
53509467b48Spatrick     // Check that the instruction is not a copy that partially overwrites the
53609467b48Spatrick     // original copy source that we are about to use. The tracker mechanism
53709467b48Spatrick     // cannot cope with that.
53809467b48Spatrick     if (MI.isCopy() && MI.modifiesRegister(CopySrcReg, TRI) &&
53909467b48Spatrick         !MI.definesRegister(CopySrcReg)) {
54009467b48Spatrick       LLVM_DEBUG(dbgs() << "MCP: Copy source overlap with dest in " << MI);
54109467b48Spatrick       continue;
54209467b48Spatrick     }
54309467b48Spatrick 
54409467b48Spatrick     if (!DebugCounter::shouldExecute(FwdCounter)) {
54509467b48Spatrick       LLVM_DEBUG(dbgs() << "MCP: Skipping forwarding due to debug counter:\n  "
54609467b48Spatrick                         << MI);
54709467b48Spatrick       continue;
54809467b48Spatrick     }
54909467b48Spatrick 
55009467b48Spatrick     LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MOUse.getReg(), TRI)
55109467b48Spatrick                       << "\n     with " << printReg(CopySrcReg, TRI)
55209467b48Spatrick                       << "\n     in " << MI << "     from " << *Copy);
55309467b48Spatrick 
55409467b48Spatrick     MOUse.setReg(CopySrcReg);
55509467b48Spatrick     if (!CopySrc.isRenamable())
55609467b48Spatrick       MOUse.setIsRenamable(false);
55709467b48Spatrick 
55809467b48Spatrick     LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
55909467b48Spatrick 
56009467b48Spatrick     // Clear kill markers that may have been invalidated.
56109467b48Spatrick     for (MachineInstr &KMI :
56209467b48Spatrick          make_range(Copy->getIterator(), std::next(MI.getIterator())))
56309467b48Spatrick       KMI.clearRegisterKills(CopySrcReg, TRI);
56409467b48Spatrick 
56509467b48Spatrick     ++NumCopyForwards;
56609467b48Spatrick     Changed = true;
56709467b48Spatrick   }
56809467b48Spatrick }
56909467b48Spatrick 
57009467b48Spatrick void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
57109467b48Spatrick   LLVM_DEBUG(dbgs() << "MCP: ForwardCopyPropagateBlock " << MBB.getName()
57209467b48Spatrick                     << "\n");
57309467b48Spatrick 
57409467b48Spatrick   for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ) {
57509467b48Spatrick     MachineInstr *MI = &*I;
57609467b48Spatrick     ++I;
57709467b48Spatrick 
57809467b48Spatrick     // Analyze copies (which don't overlap themselves).
57909467b48Spatrick     if (MI->isCopy() && !TRI->regsOverlap(MI->getOperand(0).getReg(),
58009467b48Spatrick                                           MI->getOperand(1).getReg())) {
581*73471bf0Spatrick       assert(MI->getOperand(0).getReg().isPhysical() &&
582*73471bf0Spatrick              MI->getOperand(1).getReg().isPhysical() &&
58309467b48Spatrick              "MachineCopyPropagation should be run after register allocation!");
58409467b48Spatrick 
585*73471bf0Spatrick       MCRegister Def = MI->getOperand(0).getReg().asMCReg();
586*73471bf0Spatrick       MCRegister Src = MI->getOperand(1).getReg().asMCReg();
587*73471bf0Spatrick 
58809467b48Spatrick       // The two copies cancel out and the source of the first copy
58909467b48Spatrick       // hasn't been overridden, eliminate the second one. e.g.
59009467b48Spatrick       //  %ecx = COPY %eax
59109467b48Spatrick       //  ... nothing clobbered eax.
59209467b48Spatrick       //  %eax = COPY %ecx
59309467b48Spatrick       // =>
59409467b48Spatrick       //  %ecx = COPY %eax
59509467b48Spatrick       //
59609467b48Spatrick       // or
59709467b48Spatrick       //
59809467b48Spatrick       //  %ecx = COPY %eax
59909467b48Spatrick       //  ... nothing clobbered eax.
60009467b48Spatrick       //  %ecx = COPY %eax
60109467b48Spatrick       // =>
60209467b48Spatrick       //  %ecx = COPY %eax
60309467b48Spatrick       if (eraseIfRedundant(*MI, Def, Src) || eraseIfRedundant(*MI, Src, Def))
60409467b48Spatrick         continue;
60509467b48Spatrick 
60609467b48Spatrick       forwardUses(*MI);
60709467b48Spatrick 
60809467b48Spatrick       // Src may have been changed by forwardUses()
609*73471bf0Spatrick       Src = MI->getOperand(1).getReg().asMCReg();
61009467b48Spatrick 
61109467b48Spatrick       // If Src is defined by a previous copy, the previous copy cannot be
61209467b48Spatrick       // eliminated.
61309467b48Spatrick       ReadRegister(Src, *MI, RegularUse);
61409467b48Spatrick       for (const MachineOperand &MO : MI->implicit_operands()) {
61509467b48Spatrick         if (!MO.isReg() || !MO.readsReg())
61609467b48Spatrick           continue;
617*73471bf0Spatrick         MCRegister Reg = MO.getReg().asMCReg();
61809467b48Spatrick         if (!Reg)
61909467b48Spatrick           continue;
62009467b48Spatrick         ReadRegister(Reg, *MI, RegularUse);
62109467b48Spatrick       }
62209467b48Spatrick 
62309467b48Spatrick       LLVM_DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI->dump());
62409467b48Spatrick 
62509467b48Spatrick       // Copy is now a candidate for deletion.
62609467b48Spatrick       if (!MRI->isReserved(Def))
62709467b48Spatrick         MaybeDeadCopies.insert(MI);
62809467b48Spatrick 
62909467b48Spatrick       // If 'Def' is previously source of another copy, then this earlier copy's
63009467b48Spatrick       // source is no longer available. e.g.
63109467b48Spatrick       // %xmm9 = copy %xmm2
63209467b48Spatrick       // ...
63309467b48Spatrick       // %xmm2 = copy %xmm0
63409467b48Spatrick       // ...
63509467b48Spatrick       // %xmm2 = copy %xmm9
63609467b48Spatrick       Tracker.clobberRegister(Def, *TRI);
63709467b48Spatrick       for (const MachineOperand &MO : MI->implicit_operands()) {
63809467b48Spatrick         if (!MO.isReg() || !MO.isDef())
63909467b48Spatrick           continue;
640*73471bf0Spatrick         MCRegister Reg = MO.getReg().asMCReg();
64109467b48Spatrick         if (!Reg)
64209467b48Spatrick           continue;
64309467b48Spatrick         Tracker.clobberRegister(Reg, *TRI);
64409467b48Spatrick       }
64509467b48Spatrick 
64609467b48Spatrick       Tracker.trackCopy(MI, *TRI);
64709467b48Spatrick 
64809467b48Spatrick       continue;
64909467b48Spatrick     }
65009467b48Spatrick 
65109467b48Spatrick     // Clobber any earlyclobber regs first.
65209467b48Spatrick     for (const MachineOperand &MO : MI->operands())
65309467b48Spatrick       if (MO.isReg() && MO.isEarlyClobber()) {
654*73471bf0Spatrick         MCRegister Reg = MO.getReg().asMCReg();
65509467b48Spatrick         // If we have a tied earlyclobber, that means it is also read by this
65609467b48Spatrick         // instruction, so we need to make sure we don't remove it as dead
65709467b48Spatrick         // later.
65809467b48Spatrick         if (MO.isTied())
65909467b48Spatrick           ReadRegister(Reg, *MI, RegularUse);
66009467b48Spatrick         Tracker.clobberRegister(Reg, *TRI);
66109467b48Spatrick       }
66209467b48Spatrick 
66309467b48Spatrick     forwardUses(*MI);
66409467b48Spatrick 
66509467b48Spatrick     // Not a copy.
666*73471bf0Spatrick     SmallVector<Register, 2> Defs;
66709467b48Spatrick     const MachineOperand *RegMask = nullptr;
66809467b48Spatrick     for (const MachineOperand &MO : MI->operands()) {
66909467b48Spatrick       if (MO.isRegMask())
67009467b48Spatrick         RegMask = &MO;
67109467b48Spatrick       if (!MO.isReg())
67209467b48Spatrick         continue;
67309467b48Spatrick       Register Reg = MO.getReg();
67409467b48Spatrick       if (!Reg)
67509467b48Spatrick         continue;
67609467b48Spatrick 
677*73471bf0Spatrick       assert(!Reg.isVirtual() &&
67809467b48Spatrick              "MachineCopyPropagation should be run after register allocation!");
67909467b48Spatrick 
68009467b48Spatrick       if (MO.isDef() && !MO.isEarlyClobber()) {
681*73471bf0Spatrick         Defs.push_back(Reg.asMCReg());
68209467b48Spatrick         continue;
68309467b48Spatrick       } else if (MO.readsReg())
684*73471bf0Spatrick         ReadRegister(Reg.asMCReg(), *MI, MO.isDebug() ? DebugUse : RegularUse);
68509467b48Spatrick     }
68609467b48Spatrick 
68709467b48Spatrick     // The instruction has a register mask operand which means that it clobbers
68809467b48Spatrick     // a large set of registers.  Treat clobbered registers the same way as
68909467b48Spatrick     // defined registers.
69009467b48Spatrick     if (RegMask) {
69109467b48Spatrick       // Erase any MaybeDeadCopies whose destination register is clobbered.
69209467b48Spatrick       for (SmallSetVector<MachineInstr *, 8>::iterator DI =
69309467b48Spatrick                MaybeDeadCopies.begin();
69409467b48Spatrick            DI != MaybeDeadCopies.end();) {
69509467b48Spatrick         MachineInstr *MaybeDead = *DI;
696*73471bf0Spatrick         MCRegister Reg = MaybeDead->getOperand(0).getReg().asMCReg();
69709467b48Spatrick         assert(!MRI->isReserved(Reg));
69809467b48Spatrick 
69909467b48Spatrick         if (!RegMask->clobbersPhysReg(Reg)) {
70009467b48Spatrick           ++DI;
70109467b48Spatrick           continue;
70209467b48Spatrick         }
70309467b48Spatrick 
70409467b48Spatrick         LLVM_DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: ";
70509467b48Spatrick                    MaybeDead->dump());
70609467b48Spatrick 
70709467b48Spatrick         // Make sure we invalidate any entries in the copy maps before erasing
70809467b48Spatrick         // the instruction.
70909467b48Spatrick         Tracker.clobberRegister(Reg, *TRI);
71009467b48Spatrick 
71109467b48Spatrick         // erase() will return the next valid iterator pointing to the next
71209467b48Spatrick         // element after the erased one.
71309467b48Spatrick         DI = MaybeDeadCopies.erase(DI);
71409467b48Spatrick         MaybeDead->eraseFromParent();
71509467b48Spatrick         Changed = true;
71609467b48Spatrick         ++NumDeletes;
71709467b48Spatrick       }
71809467b48Spatrick     }
71909467b48Spatrick 
72009467b48Spatrick     // Any previous copy definition or reading the Defs is no longer available.
721*73471bf0Spatrick     for (MCRegister Reg : Defs)
72209467b48Spatrick       Tracker.clobberRegister(Reg, *TRI);
72309467b48Spatrick   }
72409467b48Spatrick 
72509467b48Spatrick   // If MBB doesn't have successors, delete the copies whose defs are not used.
72609467b48Spatrick   // If MBB does have successors, then conservative assume the defs are live-out
72709467b48Spatrick   // since we don't want to trust live-in lists.
72809467b48Spatrick   if (MBB.succ_empty()) {
72909467b48Spatrick     for (MachineInstr *MaybeDead : MaybeDeadCopies) {
73009467b48Spatrick       LLVM_DEBUG(dbgs() << "MCP: Removing copy due to no live-out succ: ";
73109467b48Spatrick                  MaybeDead->dump());
73209467b48Spatrick       assert(!MRI->isReserved(MaybeDead->getOperand(0).getReg()));
73309467b48Spatrick 
73409467b48Spatrick       // Update matching debug values, if any.
73509467b48Spatrick       assert(MaybeDead->isCopy());
736*73471bf0Spatrick       Register SrcReg = MaybeDead->getOperand(1).getReg();
737*73471bf0Spatrick       Register DestReg = MaybeDead->getOperand(0).getReg();
738*73471bf0Spatrick       SmallVector<MachineInstr *> MaybeDeadDbgUsers(
739*73471bf0Spatrick           CopyDbgUsers[MaybeDead].begin(), CopyDbgUsers[MaybeDead].end());
740*73471bf0Spatrick       MRI->updateDbgUsersToReg(DestReg.asMCReg(), SrcReg.asMCReg(),
741*73471bf0Spatrick                                MaybeDeadDbgUsers);
74209467b48Spatrick 
74309467b48Spatrick       MaybeDead->eraseFromParent();
74409467b48Spatrick       Changed = true;
74509467b48Spatrick       ++NumDeletes;
74609467b48Spatrick     }
74709467b48Spatrick   }
74809467b48Spatrick 
74909467b48Spatrick   MaybeDeadCopies.clear();
75009467b48Spatrick   CopyDbgUsers.clear();
75109467b48Spatrick   Tracker.clear();
75209467b48Spatrick }
75309467b48Spatrick 
75409467b48Spatrick static bool isBackwardPropagatableCopy(MachineInstr &MI,
75509467b48Spatrick                                        const MachineRegisterInfo &MRI) {
75609467b48Spatrick   assert(MI.isCopy() && "MI is expected to be a COPY");
75709467b48Spatrick   Register Def = MI.getOperand(0).getReg();
75809467b48Spatrick   Register Src = MI.getOperand(1).getReg();
75909467b48Spatrick 
76009467b48Spatrick   if (!Def || !Src)
76109467b48Spatrick     return false;
76209467b48Spatrick 
76309467b48Spatrick   if (MRI.isReserved(Def) || MRI.isReserved(Src))
76409467b48Spatrick     return false;
76509467b48Spatrick 
76609467b48Spatrick   return MI.getOperand(1).isRenamable() && MI.getOperand(1).isKill();
76709467b48Spatrick }
76809467b48Spatrick 
76909467b48Spatrick void MachineCopyPropagation::propagateDefs(MachineInstr &MI) {
77009467b48Spatrick   if (!Tracker.hasAnyCopies())
77109467b48Spatrick     return;
77209467b48Spatrick 
77309467b48Spatrick   for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx != OpEnd;
77409467b48Spatrick        ++OpIdx) {
77509467b48Spatrick     MachineOperand &MODef = MI.getOperand(OpIdx);
77609467b48Spatrick 
77709467b48Spatrick     if (!MODef.isReg() || MODef.isUse())
77809467b48Spatrick       continue;
77909467b48Spatrick 
78009467b48Spatrick     // Ignore non-trivial cases.
78109467b48Spatrick     if (MODef.isTied() || MODef.isUndef() || MODef.isImplicit())
78209467b48Spatrick       continue;
78309467b48Spatrick 
78409467b48Spatrick     if (!MODef.getReg())
78509467b48Spatrick       continue;
78609467b48Spatrick 
78709467b48Spatrick     // We only handle if the register comes from a vreg.
78809467b48Spatrick     if (!MODef.isRenamable())
78909467b48Spatrick       continue;
79009467b48Spatrick 
79109467b48Spatrick     MachineInstr *Copy =
792*73471bf0Spatrick         Tracker.findAvailBackwardCopy(MI, MODef.getReg().asMCReg(), *TRI);
79309467b48Spatrick     if (!Copy)
79409467b48Spatrick       continue;
79509467b48Spatrick 
79609467b48Spatrick     Register Def = Copy->getOperand(0).getReg();
79709467b48Spatrick     Register Src = Copy->getOperand(1).getReg();
79809467b48Spatrick 
79909467b48Spatrick     if (MODef.getReg() != Src)
80009467b48Spatrick       continue;
80109467b48Spatrick 
80209467b48Spatrick     if (!isBackwardPropagatableRegClassCopy(*Copy, MI, OpIdx))
80309467b48Spatrick       continue;
80409467b48Spatrick 
80509467b48Spatrick     if (hasImplicitOverlap(MI, MODef))
80609467b48Spatrick       continue;
80709467b48Spatrick 
808*73471bf0Spatrick     if (hasOverlappingMultipleDef(MI, MODef, Def))
809*73471bf0Spatrick       continue;
810*73471bf0Spatrick 
81109467b48Spatrick     LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MODef.getReg(), TRI)
81209467b48Spatrick                       << "\n     with " << printReg(Def, TRI) << "\n     in "
81309467b48Spatrick                       << MI << "     from " << *Copy);
81409467b48Spatrick 
81509467b48Spatrick     MODef.setReg(Def);
81609467b48Spatrick     MODef.setIsRenamable(Copy->getOperand(0).isRenamable());
81709467b48Spatrick 
81809467b48Spatrick     LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
81909467b48Spatrick     MaybeDeadCopies.insert(Copy);
82009467b48Spatrick     Changed = true;
82109467b48Spatrick     ++NumCopyBackwardPropagated;
82209467b48Spatrick   }
82309467b48Spatrick }
82409467b48Spatrick 
82509467b48Spatrick void MachineCopyPropagation::BackwardCopyPropagateBlock(
82609467b48Spatrick     MachineBasicBlock &MBB) {
82709467b48Spatrick   LLVM_DEBUG(dbgs() << "MCP: BackwardCopyPropagateBlock " << MBB.getName()
82809467b48Spatrick                     << "\n");
82909467b48Spatrick 
83009467b48Spatrick   for (MachineBasicBlock::reverse_iterator I = MBB.rbegin(), E = MBB.rend();
83109467b48Spatrick        I != E;) {
83209467b48Spatrick     MachineInstr *MI = &*I;
83309467b48Spatrick     ++I;
83409467b48Spatrick 
83509467b48Spatrick     // Ignore non-trivial COPYs.
83609467b48Spatrick     if (MI->isCopy() && MI->getNumOperands() == 2 &&
83709467b48Spatrick         !TRI->regsOverlap(MI->getOperand(0).getReg(),
83809467b48Spatrick                           MI->getOperand(1).getReg())) {
83909467b48Spatrick 
840*73471bf0Spatrick       MCRegister Def = MI->getOperand(0).getReg().asMCReg();
841*73471bf0Spatrick       MCRegister Src = MI->getOperand(1).getReg().asMCReg();
84209467b48Spatrick 
84309467b48Spatrick       // Unlike forward cp, we don't invoke propagateDefs here,
84409467b48Spatrick       // just let forward cp do COPY-to-COPY propagation.
84509467b48Spatrick       if (isBackwardPropagatableCopy(*MI, *MRI)) {
84609467b48Spatrick         Tracker.invalidateRegister(Src, *TRI);
84709467b48Spatrick         Tracker.invalidateRegister(Def, *TRI);
84809467b48Spatrick         Tracker.trackCopy(MI, *TRI);
84909467b48Spatrick         continue;
85009467b48Spatrick       }
85109467b48Spatrick     }
85209467b48Spatrick 
85309467b48Spatrick     // Invalidate any earlyclobber regs first.
85409467b48Spatrick     for (const MachineOperand &MO : MI->operands())
85509467b48Spatrick       if (MO.isReg() && MO.isEarlyClobber()) {
856*73471bf0Spatrick         MCRegister Reg = MO.getReg().asMCReg();
85709467b48Spatrick         if (!Reg)
85809467b48Spatrick           continue;
85909467b48Spatrick         Tracker.invalidateRegister(Reg, *TRI);
86009467b48Spatrick       }
86109467b48Spatrick 
86209467b48Spatrick     propagateDefs(*MI);
86309467b48Spatrick     for (const MachineOperand &MO : MI->operands()) {
86409467b48Spatrick       if (!MO.isReg())
86509467b48Spatrick         continue;
86609467b48Spatrick 
86709467b48Spatrick       if (!MO.getReg())
86809467b48Spatrick         continue;
86909467b48Spatrick 
87009467b48Spatrick       if (MO.isDef())
871*73471bf0Spatrick         Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI);
87209467b48Spatrick 
873*73471bf0Spatrick       if (MO.readsReg()) {
874*73471bf0Spatrick         if (MO.isDebug()) {
875*73471bf0Spatrick           //  Check if the register in the debug instruction is utilized
876*73471bf0Spatrick           // in a copy instruction, so we can update the debug info if the
877*73471bf0Spatrick           // register is changed.
878*73471bf0Spatrick           for (MCRegUnitIterator RUI(MO.getReg().asMCReg(), TRI); RUI.isValid();
879*73471bf0Spatrick                ++RUI) {
880*73471bf0Spatrick             if (auto *Copy = Tracker.findCopyDefViaUnit(*RUI, *TRI)) {
881*73471bf0Spatrick               CopyDbgUsers[Copy].insert(MI);
882*73471bf0Spatrick             }
883*73471bf0Spatrick           }
884*73471bf0Spatrick         } else {
885*73471bf0Spatrick           Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI);
886*73471bf0Spatrick         }
887*73471bf0Spatrick       }
88809467b48Spatrick     }
88909467b48Spatrick   }
89009467b48Spatrick 
89109467b48Spatrick   for (auto *Copy : MaybeDeadCopies) {
892*73471bf0Spatrick 
893*73471bf0Spatrick     Register Src = Copy->getOperand(1).getReg();
894*73471bf0Spatrick     Register Def = Copy->getOperand(0).getReg();
895*73471bf0Spatrick     SmallVector<MachineInstr *> MaybeDeadDbgUsers(CopyDbgUsers[Copy].begin(),
896*73471bf0Spatrick                                                   CopyDbgUsers[Copy].end());
897*73471bf0Spatrick 
898*73471bf0Spatrick     MRI->updateDbgUsersToReg(Src.asMCReg(), Def.asMCReg(), MaybeDeadDbgUsers);
89909467b48Spatrick     Copy->eraseFromParent();
90009467b48Spatrick     ++NumDeletes;
90109467b48Spatrick   }
90209467b48Spatrick 
90309467b48Spatrick   MaybeDeadCopies.clear();
90409467b48Spatrick   CopyDbgUsers.clear();
90509467b48Spatrick   Tracker.clear();
90609467b48Spatrick }
90709467b48Spatrick 
90809467b48Spatrick bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) {
90909467b48Spatrick   if (skipFunction(MF.getFunction()))
91009467b48Spatrick     return false;
91109467b48Spatrick 
91209467b48Spatrick   Changed = false;
91309467b48Spatrick 
91409467b48Spatrick   TRI = MF.getSubtarget().getRegisterInfo();
91509467b48Spatrick   TII = MF.getSubtarget().getInstrInfo();
91609467b48Spatrick   MRI = &MF.getRegInfo();
91709467b48Spatrick 
91809467b48Spatrick   for (MachineBasicBlock &MBB : MF) {
91909467b48Spatrick     BackwardCopyPropagateBlock(MBB);
92009467b48Spatrick     ForwardCopyPropagateBlock(MBB);
92109467b48Spatrick   }
92209467b48Spatrick 
92309467b48Spatrick   return Changed;
92409467b48Spatrick }
925