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" 54*097a140dSpatrick #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; 9109467b48Spatrick SmallVector<unsigned, 4> DefRegs; 9209467b48Spatrick bool Avail; 9309467b48Spatrick }; 9409467b48Spatrick 9509467b48Spatrick DenseMap<unsigned, CopyInfo> Copies; 9609467b48Spatrick 9709467b48Spatrick public: 9809467b48Spatrick /// Mark all of the given registers and their subregisters as unavailable for 9909467b48Spatrick /// copying. 10009467b48Spatrick void markRegsUnavailable(ArrayRef<unsigned> Regs, 10109467b48Spatrick const TargetRegisterInfo &TRI) { 10209467b48Spatrick for (unsigned 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. 11309467b48Spatrick void invalidateRegister(unsigned 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*097a140dSpatrick SmallSet<unsigned, 8> RegsToInvalidate; 118*097a140dSpatrick 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) { 12309467b48Spatrick RegsToInvalidate.insert(MI->getOperand(0).getReg()); 12409467b48Spatrick RegsToInvalidate.insert(MI->getOperand(1).getReg()); 12509467b48Spatrick } 12609467b48Spatrick RegsToInvalidate.insert(I->second.DefRegs.begin(), 12709467b48Spatrick I->second.DefRegs.end()); 12809467b48Spatrick } 12909467b48Spatrick } 13009467b48Spatrick for (unsigned 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. 13609467b48Spatrick void clobberRegister(unsigned 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) 14609467b48Spatrick markRegsUnavailable({MI->getOperand(0).getReg()}, 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 15709467b48Spatrick Register Def = MI->getOperand(0).getReg(); 15809467b48Spatrick Register Src = MI->getOperand(1).getReg(); 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 17809467b48Spatrick MachineInstr *findCopyForUnit(unsigned RegUnit, const TargetRegisterInfo &TRI, 17909467b48Spatrick bool MustBeAvailable = false) { 18009467b48Spatrick auto CI = Copies.find(RegUnit); 18109467b48Spatrick if (CI == Copies.end()) 18209467b48Spatrick return nullptr; 18309467b48Spatrick if (MustBeAvailable && !CI->second.Avail) 18409467b48Spatrick return nullptr; 18509467b48Spatrick return CI->second.MI; 18609467b48Spatrick } 18709467b48Spatrick 18809467b48Spatrick MachineInstr *findCopyDefViaUnit(unsigned RegUnit, 18909467b48Spatrick const TargetRegisterInfo &TRI) { 19009467b48Spatrick auto CI = Copies.find(RegUnit); 19109467b48Spatrick if (CI == Copies.end()) 19209467b48Spatrick return nullptr; 19309467b48Spatrick if (CI->second.DefRegs.size() != 1) 19409467b48Spatrick return nullptr; 19509467b48Spatrick MCRegUnitIterator RUI(CI->second.DefRegs[0], &TRI); 19609467b48Spatrick return findCopyForUnit(*RUI, TRI, true); 19709467b48Spatrick } 19809467b48Spatrick 19909467b48Spatrick MachineInstr *findAvailBackwardCopy(MachineInstr &I, unsigned Reg, 20009467b48Spatrick const TargetRegisterInfo &TRI) { 20109467b48Spatrick MCRegUnitIterator RUI(Reg, &TRI); 20209467b48Spatrick MachineInstr *AvailCopy = findCopyDefViaUnit(*RUI, TRI); 20309467b48Spatrick if (!AvailCopy || 20409467b48Spatrick !TRI.isSubRegisterEq(AvailCopy->getOperand(1).getReg(), Reg)) 20509467b48Spatrick return nullptr; 20609467b48Spatrick 20709467b48Spatrick Register AvailSrc = AvailCopy->getOperand(1).getReg(); 20809467b48Spatrick Register AvailDef = AvailCopy->getOperand(0).getReg(); 20909467b48Spatrick for (const MachineInstr &MI : 21009467b48Spatrick make_range(AvailCopy->getReverseIterator(), I.getReverseIterator())) 21109467b48Spatrick for (const MachineOperand &MO : MI.operands()) 21209467b48Spatrick if (MO.isRegMask()) 21309467b48Spatrick // FIXME: Shall we simultaneously invalidate AvailSrc or AvailDef? 21409467b48Spatrick if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef)) 21509467b48Spatrick return nullptr; 21609467b48Spatrick 21709467b48Spatrick return AvailCopy; 21809467b48Spatrick } 21909467b48Spatrick 22009467b48Spatrick MachineInstr *findAvailCopy(MachineInstr &DestCopy, unsigned Reg, 22109467b48Spatrick const TargetRegisterInfo &TRI) { 22209467b48Spatrick // We check the first RegUnit here, since we'll only be interested in the 22309467b48Spatrick // copy if it copies the entire register anyway. 22409467b48Spatrick MCRegUnitIterator RUI(Reg, &TRI); 22509467b48Spatrick MachineInstr *AvailCopy = 22609467b48Spatrick findCopyForUnit(*RUI, TRI, /*MustBeAvailable=*/true); 22709467b48Spatrick if (!AvailCopy || 22809467b48Spatrick !TRI.isSubRegisterEq(AvailCopy->getOperand(0).getReg(), Reg)) 22909467b48Spatrick return nullptr; 23009467b48Spatrick 23109467b48Spatrick // Check that the available copy isn't clobbered by any regmasks between 23209467b48Spatrick // itself and the destination. 23309467b48Spatrick Register AvailSrc = AvailCopy->getOperand(1).getReg(); 23409467b48Spatrick Register AvailDef = AvailCopy->getOperand(0).getReg(); 23509467b48Spatrick for (const MachineInstr &MI : 23609467b48Spatrick make_range(AvailCopy->getIterator(), DestCopy.getIterator())) 23709467b48Spatrick for (const MachineOperand &MO : MI.operands()) 23809467b48Spatrick if (MO.isRegMask()) 23909467b48Spatrick if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef)) 24009467b48Spatrick return nullptr; 24109467b48Spatrick 24209467b48Spatrick return AvailCopy; 24309467b48Spatrick } 24409467b48Spatrick 24509467b48Spatrick void clear() { 24609467b48Spatrick Copies.clear(); 24709467b48Spatrick } 24809467b48Spatrick }; 24909467b48Spatrick 25009467b48Spatrick class MachineCopyPropagation : public MachineFunctionPass { 25109467b48Spatrick const TargetRegisterInfo *TRI; 25209467b48Spatrick const TargetInstrInfo *TII; 25309467b48Spatrick const MachineRegisterInfo *MRI; 25409467b48Spatrick 25509467b48Spatrick public: 25609467b48Spatrick static char ID; // Pass identification, replacement for typeid 25709467b48Spatrick 25809467b48Spatrick MachineCopyPropagation() : MachineFunctionPass(ID) { 25909467b48Spatrick initializeMachineCopyPropagationPass(*PassRegistry::getPassRegistry()); 26009467b48Spatrick } 26109467b48Spatrick 26209467b48Spatrick void getAnalysisUsage(AnalysisUsage &AU) const override { 26309467b48Spatrick AU.setPreservesCFG(); 26409467b48Spatrick MachineFunctionPass::getAnalysisUsage(AU); 26509467b48Spatrick } 26609467b48Spatrick 26709467b48Spatrick bool runOnMachineFunction(MachineFunction &MF) override; 26809467b48Spatrick 26909467b48Spatrick MachineFunctionProperties getRequiredProperties() const override { 27009467b48Spatrick return MachineFunctionProperties().set( 27109467b48Spatrick MachineFunctionProperties::Property::NoVRegs); 27209467b48Spatrick } 27309467b48Spatrick 27409467b48Spatrick private: 27509467b48Spatrick typedef enum { DebugUse = false, RegularUse = true } DebugType; 27609467b48Spatrick 27709467b48Spatrick void ClobberRegister(unsigned Reg); 27809467b48Spatrick void ReadRegister(unsigned Reg, MachineInstr &Reader, 27909467b48Spatrick DebugType DT); 28009467b48Spatrick void ForwardCopyPropagateBlock(MachineBasicBlock &MBB); 28109467b48Spatrick void BackwardCopyPropagateBlock(MachineBasicBlock &MBB); 28209467b48Spatrick bool eraseIfRedundant(MachineInstr &Copy, unsigned Src, unsigned Def); 28309467b48Spatrick void forwardUses(MachineInstr &MI); 28409467b48Spatrick void propagateDefs(MachineInstr &MI); 28509467b48Spatrick bool isForwardableRegClassCopy(const MachineInstr &Copy, 28609467b48Spatrick const MachineInstr &UseI, unsigned UseIdx); 28709467b48Spatrick bool isBackwardPropagatableRegClassCopy(const MachineInstr &Copy, 28809467b48Spatrick const MachineInstr &UseI, 28909467b48Spatrick unsigned UseIdx); 29009467b48Spatrick bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use); 29109467b48Spatrick 29209467b48Spatrick /// Candidates for deletion. 29309467b48Spatrick SmallSetVector<MachineInstr *, 8> MaybeDeadCopies; 29409467b48Spatrick 29509467b48Spatrick /// Multimap tracking debug users in current BB 29609467b48Spatrick DenseMap<MachineInstr*, SmallVector<MachineInstr*, 2>> CopyDbgUsers; 29709467b48Spatrick 29809467b48Spatrick CopyTracker Tracker; 29909467b48Spatrick 30009467b48Spatrick bool Changed; 30109467b48Spatrick }; 30209467b48Spatrick 30309467b48Spatrick } // end anonymous namespace 30409467b48Spatrick 30509467b48Spatrick char MachineCopyPropagation::ID = 0; 30609467b48Spatrick 30709467b48Spatrick char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID; 30809467b48Spatrick 30909467b48Spatrick INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE, 31009467b48Spatrick "Machine Copy Propagation Pass", false, false) 31109467b48Spatrick 31209467b48Spatrick void MachineCopyPropagation::ReadRegister(unsigned Reg, MachineInstr &Reader, 31309467b48Spatrick DebugType DT) { 31409467b48Spatrick // If 'Reg' is defined by a copy, the copy is no longer a candidate 31509467b48Spatrick // for elimination. If a copy is "read" by a debug user, record the user 31609467b48Spatrick // for propagation. 31709467b48Spatrick for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) { 31809467b48Spatrick if (MachineInstr *Copy = Tracker.findCopyForUnit(*RUI, *TRI)) { 31909467b48Spatrick if (DT == RegularUse) { 32009467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; Copy->dump()); 32109467b48Spatrick MaybeDeadCopies.remove(Copy); 32209467b48Spatrick } else { 32309467b48Spatrick CopyDbgUsers[Copy].push_back(&Reader); 32409467b48Spatrick } 32509467b48Spatrick } 32609467b48Spatrick } 32709467b48Spatrick } 32809467b48Spatrick 32909467b48Spatrick /// Return true if \p PreviousCopy did copy register \p Src to register \p Def. 33009467b48Spatrick /// This fact may have been obscured by sub register usage or may not be true at 33109467b48Spatrick /// all even though Src and Def are subregisters of the registers used in 33209467b48Spatrick /// PreviousCopy. e.g. 33309467b48Spatrick /// isNopCopy("ecx = COPY eax", AX, CX) == true 33409467b48Spatrick /// isNopCopy("ecx = COPY eax", AH, CL) == false 33509467b48Spatrick static bool isNopCopy(const MachineInstr &PreviousCopy, unsigned Src, 33609467b48Spatrick unsigned Def, const TargetRegisterInfo *TRI) { 33709467b48Spatrick Register PreviousSrc = PreviousCopy.getOperand(1).getReg(); 33809467b48Spatrick Register PreviousDef = PreviousCopy.getOperand(0).getReg(); 339*097a140dSpatrick if (Src == PreviousSrc && Def == PreviousDef) 34009467b48Spatrick return true; 34109467b48Spatrick if (!TRI->isSubRegister(PreviousSrc, Src)) 34209467b48Spatrick return false; 34309467b48Spatrick unsigned SubIdx = TRI->getSubRegIndex(PreviousSrc, Src); 34409467b48Spatrick return SubIdx == TRI->getSubRegIndex(PreviousDef, Def); 34509467b48Spatrick } 34609467b48Spatrick 34709467b48Spatrick /// Remove instruction \p Copy if there exists a previous copy that copies the 34809467b48Spatrick /// register \p Src to the register \p Def; This may happen indirectly by 34909467b48Spatrick /// copying the super registers. 35009467b48Spatrick bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src, 35109467b48Spatrick unsigned Def) { 35209467b48Spatrick // Avoid eliminating a copy from/to a reserved registers as we cannot predict 35309467b48Spatrick // the value (Example: The sparc zero register is writable but stays zero). 35409467b48Spatrick if (MRI->isReserved(Src) || MRI->isReserved(Def)) 35509467b48Spatrick return false; 35609467b48Spatrick 35709467b48Spatrick // Search for an existing copy. 35809467b48Spatrick MachineInstr *PrevCopy = Tracker.findAvailCopy(Copy, Def, *TRI); 35909467b48Spatrick if (!PrevCopy) 36009467b48Spatrick return false; 36109467b48Spatrick 36209467b48Spatrick // Check that the existing copy uses the correct sub registers. 36309467b48Spatrick if (PrevCopy->getOperand(0).isDead()) 36409467b48Spatrick return false; 36509467b48Spatrick if (!isNopCopy(*PrevCopy, Src, Def, TRI)) 36609467b48Spatrick return false; 36709467b48Spatrick 36809467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; Copy.dump()); 36909467b48Spatrick 37009467b48Spatrick // Copy was redundantly redefining either Src or Def. Remove earlier kill 37109467b48Spatrick // flags between Copy and PrevCopy because the value will be reused now. 37209467b48Spatrick assert(Copy.isCopy()); 37309467b48Spatrick Register CopyDef = Copy.getOperand(0).getReg(); 37409467b48Spatrick assert(CopyDef == Src || CopyDef == Def); 37509467b48Spatrick for (MachineInstr &MI : 37609467b48Spatrick make_range(PrevCopy->getIterator(), Copy.getIterator())) 37709467b48Spatrick MI.clearRegisterKills(CopyDef, TRI); 37809467b48Spatrick 37909467b48Spatrick Copy.eraseFromParent(); 38009467b48Spatrick Changed = true; 38109467b48Spatrick ++NumDeletes; 38209467b48Spatrick return true; 38309467b48Spatrick } 38409467b48Spatrick 38509467b48Spatrick bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy( 38609467b48Spatrick const MachineInstr &Copy, const MachineInstr &UseI, unsigned UseIdx) { 38709467b48Spatrick Register Def = Copy.getOperand(0).getReg(); 38809467b48Spatrick 38909467b48Spatrick if (const TargetRegisterClass *URC = 39009467b48Spatrick UseI.getRegClassConstraint(UseIdx, TII, TRI)) 39109467b48Spatrick return URC->contains(Def); 39209467b48Spatrick 39309467b48Spatrick // We don't process further if UseI is a COPY, since forward copy propagation 39409467b48Spatrick // should handle that. 39509467b48Spatrick return false; 39609467b48Spatrick } 39709467b48Spatrick 39809467b48Spatrick /// Decide whether we should forward the source of \param Copy to its use in 39909467b48Spatrick /// \param UseI based on the physical register class constraints of the opcode 40009467b48Spatrick /// and avoiding introducing more cross-class COPYs. 40109467b48Spatrick bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy, 40209467b48Spatrick const MachineInstr &UseI, 40309467b48Spatrick unsigned UseIdx) { 40409467b48Spatrick 40509467b48Spatrick Register CopySrcReg = Copy.getOperand(1).getReg(); 40609467b48Spatrick 40709467b48Spatrick // If the new register meets the opcode register constraints, then allow 40809467b48Spatrick // forwarding. 40909467b48Spatrick if (const TargetRegisterClass *URC = 41009467b48Spatrick UseI.getRegClassConstraint(UseIdx, TII, TRI)) 41109467b48Spatrick return URC->contains(CopySrcReg); 41209467b48Spatrick 41309467b48Spatrick if (!UseI.isCopy()) 41409467b48Spatrick return false; 41509467b48Spatrick 41609467b48Spatrick /// COPYs don't have register class constraints, so if the user instruction 41709467b48Spatrick /// is a COPY, we just try to avoid introducing additional cross-class 41809467b48Spatrick /// COPYs. For example: 41909467b48Spatrick /// 42009467b48Spatrick /// RegClassA = COPY RegClassB // Copy parameter 42109467b48Spatrick /// ... 42209467b48Spatrick /// RegClassB = COPY RegClassA // UseI parameter 42309467b48Spatrick /// 42409467b48Spatrick /// which after forwarding becomes 42509467b48Spatrick /// 42609467b48Spatrick /// RegClassA = COPY RegClassB 42709467b48Spatrick /// ... 42809467b48Spatrick /// RegClassB = COPY RegClassB 42909467b48Spatrick /// 43009467b48Spatrick /// so we have reduced the number of cross-class COPYs and potentially 43109467b48Spatrick /// introduced a nop COPY that can be removed. 43209467b48Spatrick const TargetRegisterClass *UseDstRC = 43309467b48Spatrick TRI->getMinimalPhysRegClass(UseI.getOperand(0).getReg()); 43409467b48Spatrick 43509467b48Spatrick const TargetRegisterClass *SuperRC = UseDstRC; 43609467b48Spatrick for (TargetRegisterClass::sc_iterator SuperRCI = UseDstRC->getSuperClasses(); 43709467b48Spatrick SuperRC; SuperRC = *SuperRCI++) 43809467b48Spatrick if (SuperRC->contains(CopySrcReg)) 43909467b48Spatrick return true; 44009467b48Spatrick 44109467b48Spatrick return false; 44209467b48Spatrick } 44309467b48Spatrick 44409467b48Spatrick /// Check that \p MI does not have implicit uses that overlap with it's \p Use 44509467b48Spatrick /// operand (the register being replaced), since these can sometimes be 44609467b48Spatrick /// implicitly tied to other operands. For example, on AMDGPU: 44709467b48Spatrick /// 44809467b48Spatrick /// V_MOVRELS_B32_e32 %VGPR2, %M0<imp-use>, %EXEC<imp-use>, %VGPR2_VGPR3_VGPR4_VGPR5<imp-use> 44909467b48Spatrick /// 45009467b48Spatrick /// the %VGPR2 is implicitly tied to the larger reg operand, but we have no 45109467b48Spatrick /// way of knowing we need to update the latter when updating the former. 45209467b48Spatrick bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI, 45309467b48Spatrick const MachineOperand &Use) { 45409467b48Spatrick for (const MachineOperand &MIUse : MI.uses()) 45509467b48Spatrick if (&MIUse != &Use && MIUse.isReg() && MIUse.isImplicit() && 45609467b48Spatrick MIUse.isUse() && TRI->regsOverlap(Use.getReg(), MIUse.getReg())) 45709467b48Spatrick return true; 45809467b48Spatrick 45909467b48Spatrick return false; 46009467b48Spatrick } 46109467b48Spatrick 46209467b48Spatrick /// Look for available copies whose destination register is used by \p MI and 46309467b48Spatrick /// replace the use in \p MI with the copy's source register. 46409467b48Spatrick void MachineCopyPropagation::forwardUses(MachineInstr &MI) { 46509467b48Spatrick if (!Tracker.hasAnyCopies()) 46609467b48Spatrick return; 46709467b48Spatrick 46809467b48Spatrick // Look for non-tied explicit vreg uses that have an active COPY 46909467b48Spatrick // instruction that defines the physical register allocated to them. 47009467b48Spatrick // Replace the vreg with the source of the active COPY. 47109467b48Spatrick for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx < OpEnd; 47209467b48Spatrick ++OpIdx) { 47309467b48Spatrick MachineOperand &MOUse = MI.getOperand(OpIdx); 47409467b48Spatrick // Don't forward into undef use operands since doing so can cause problems 47509467b48Spatrick // with the machine verifier, since it doesn't treat undef reads as reads, 47609467b48Spatrick // so we can end up with a live range that ends on an undef read, leading to 47709467b48Spatrick // an error that the live range doesn't end on a read of the live range 47809467b48Spatrick // register. 47909467b48Spatrick if (!MOUse.isReg() || MOUse.isTied() || MOUse.isUndef() || MOUse.isDef() || 48009467b48Spatrick MOUse.isImplicit()) 48109467b48Spatrick continue; 48209467b48Spatrick 48309467b48Spatrick if (!MOUse.getReg()) 48409467b48Spatrick continue; 48509467b48Spatrick 48609467b48Spatrick // Check that the register is marked 'renamable' so we know it is safe to 48709467b48Spatrick // rename it without violating any constraints that aren't expressed in the 48809467b48Spatrick // IR (e.g. ABI or opcode requirements). 48909467b48Spatrick if (!MOUse.isRenamable()) 49009467b48Spatrick continue; 49109467b48Spatrick 49209467b48Spatrick MachineInstr *Copy = Tracker.findAvailCopy(MI, MOUse.getReg(), *TRI); 49309467b48Spatrick if (!Copy) 49409467b48Spatrick continue; 49509467b48Spatrick 49609467b48Spatrick Register CopyDstReg = Copy->getOperand(0).getReg(); 49709467b48Spatrick const MachineOperand &CopySrc = Copy->getOperand(1); 49809467b48Spatrick Register CopySrcReg = CopySrc.getReg(); 49909467b48Spatrick 50009467b48Spatrick // FIXME: Don't handle partial uses of wider COPYs yet. 50109467b48Spatrick if (MOUse.getReg() != CopyDstReg) { 50209467b48Spatrick LLVM_DEBUG( 50309467b48Spatrick dbgs() << "MCP: FIXME! Not forwarding COPY to sub-register use:\n " 50409467b48Spatrick << MI); 50509467b48Spatrick continue; 50609467b48Spatrick } 50709467b48Spatrick 50809467b48Spatrick // Don't forward COPYs of reserved regs unless they are constant. 50909467b48Spatrick if (MRI->isReserved(CopySrcReg) && !MRI->isConstantPhysReg(CopySrcReg)) 51009467b48Spatrick continue; 51109467b48Spatrick 51209467b48Spatrick if (!isForwardableRegClassCopy(*Copy, MI, OpIdx)) 51309467b48Spatrick continue; 51409467b48Spatrick 51509467b48Spatrick if (hasImplicitOverlap(MI, MOUse)) 51609467b48Spatrick continue; 51709467b48Spatrick 51809467b48Spatrick // Check that the instruction is not a copy that partially overwrites the 51909467b48Spatrick // original copy source that we are about to use. The tracker mechanism 52009467b48Spatrick // cannot cope with that. 52109467b48Spatrick if (MI.isCopy() && MI.modifiesRegister(CopySrcReg, TRI) && 52209467b48Spatrick !MI.definesRegister(CopySrcReg)) { 52309467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: Copy source overlap with dest in " << MI); 52409467b48Spatrick continue; 52509467b48Spatrick } 52609467b48Spatrick 52709467b48Spatrick if (!DebugCounter::shouldExecute(FwdCounter)) { 52809467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: Skipping forwarding due to debug counter:\n " 52909467b48Spatrick << MI); 53009467b48Spatrick continue; 53109467b48Spatrick } 53209467b48Spatrick 53309467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MOUse.getReg(), TRI) 53409467b48Spatrick << "\n with " << printReg(CopySrcReg, TRI) 53509467b48Spatrick << "\n in " << MI << " from " << *Copy); 53609467b48Spatrick 53709467b48Spatrick MOUse.setReg(CopySrcReg); 53809467b48Spatrick if (!CopySrc.isRenamable()) 53909467b48Spatrick MOUse.setIsRenamable(false); 54009467b48Spatrick 54109467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n"); 54209467b48Spatrick 54309467b48Spatrick // Clear kill markers that may have been invalidated. 54409467b48Spatrick for (MachineInstr &KMI : 54509467b48Spatrick make_range(Copy->getIterator(), std::next(MI.getIterator()))) 54609467b48Spatrick KMI.clearRegisterKills(CopySrcReg, TRI); 54709467b48Spatrick 54809467b48Spatrick ++NumCopyForwards; 54909467b48Spatrick Changed = true; 55009467b48Spatrick } 55109467b48Spatrick } 55209467b48Spatrick 55309467b48Spatrick void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { 55409467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: ForwardCopyPropagateBlock " << MBB.getName() 55509467b48Spatrick << "\n"); 55609467b48Spatrick 55709467b48Spatrick for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ) { 55809467b48Spatrick MachineInstr *MI = &*I; 55909467b48Spatrick ++I; 56009467b48Spatrick 56109467b48Spatrick // Analyze copies (which don't overlap themselves). 56209467b48Spatrick if (MI->isCopy() && !TRI->regsOverlap(MI->getOperand(0).getReg(), 56309467b48Spatrick MI->getOperand(1).getReg())) { 56409467b48Spatrick Register Def = MI->getOperand(0).getReg(); 56509467b48Spatrick Register Src = MI->getOperand(1).getReg(); 56609467b48Spatrick 56709467b48Spatrick assert(!Register::isVirtualRegister(Def) && 56809467b48Spatrick !Register::isVirtualRegister(Src) && 56909467b48Spatrick "MachineCopyPropagation should be run after register allocation!"); 57009467b48Spatrick 57109467b48Spatrick // The two copies cancel out and the source of the first copy 57209467b48Spatrick // hasn't been overridden, eliminate the second one. e.g. 57309467b48Spatrick // %ecx = COPY %eax 57409467b48Spatrick // ... nothing clobbered eax. 57509467b48Spatrick // %eax = COPY %ecx 57609467b48Spatrick // => 57709467b48Spatrick // %ecx = COPY %eax 57809467b48Spatrick // 57909467b48Spatrick // or 58009467b48Spatrick // 58109467b48Spatrick // %ecx = COPY %eax 58209467b48Spatrick // ... nothing clobbered eax. 58309467b48Spatrick // %ecx = COPY %eax 58409467b48Spatrick // => 58509467b48Spatrick // %ecx = COPY %eax 58609467b48Spatrick if (eraseIfRedundant(*MI, Def, Src) || eraseIfRedundant(*MI, Src, Def)) 58709467b48Spatrick continue; 58809467b48Spatrick 58909467b48Spatrick forwardUses(*MI); 59009467b48Spatrick 59109467b48Spatrick // Src may have been changed by forwardUses() 59209467b48Spatrick Src = MI->getOperand(1).getReg(); 59309467b48Spatrick 59409467b48Spatrick // If Src is defined by a previous copy, the previous copy cannot be 59509467b48Spatrick // eliminated. 59609467b48Spatrick ReadRegister(Src, *MI, RegularUse); 59709467b48Spatrick for (const MachineOperand &MO : MI->implicit_operands()) { 59809467b48Spatrick if (!MO.isReg() || !MO.readsReg()) 59909467b48Spatrick continue; 60009467b48Spatrick Register Reg = MO.getReg(); 60109467b48Spatrick if (!Reg) 60209467b48Spatrick continue; 60309467b48Spatrick ReadRegister(Reg, *MI, RegularUse); 60409467b48Spatrick } 60509467b48Spatrick 60609467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI->dump()); 60709467b48Spatrick 60809467b48Spatrick // Copy is now a candidate for deletion. 60909467b48Spatrick if (!MRI->isReserved(Def)) 61009467b48Spatrick MaybeDeadCopies.insert(MI); 61109467b48Spatrick 61209467b48Spatrick // If 'Def' is previously source of another copy, then this earlier copy's 61309467b48Spatrick // source is no longer available. e.g. 61409467b48Spatrick // %xmm9 = copy %xmm2 61509467b48Spatrick // ... 61609467b48Spatrick // %xmm2 = copy %xmm0 61709467b48Spatrick // ... 61809467b48Spatrick // %xmm2 = copy %xmm9 61909467b48Spatrick Tracker.clobberRegister(Def, *TRI); 62009467b48Spatrick for (const MachineOperand &MO : MI->implicit_operands()) { 62109467b48Spatrick if (!MO.isReg() || !MO.isDef()) 62209467b48Spatrick continue; 62309467b48Spatrick Register Reg = MO.getReg(); 62409467b48Spatrick if (!Reg) 62509467b48Spatrick continue; 62609467b48Spatrick Tracker.clobberRegister(Reg, *TRI); 62709467b48Spatrick } 62809467b48Spatrick 62909467b48Spatrick Tracker.trackCopy(MI, *TRI); 63009467b48Spatrick 63109467b48Spatrick continue; 63209467b48Spatrick } 63309467b48Spatrick 63409467b48Spatrick // Clobber any earlyclobber regs first. 63509467b48Spatrick for (const MachineOperand &MO : MI->operands()) 63609467b48Spatrick if (MO.isReg() && MO.isEarlyClobber()) { 63709467b48Spatrick Register Reg = MO.getReg(); 63809467b48Spatrick // If we have a tied earlyclobber, that means it is also read by this 63909467b48Spatrick // instruction, so we need to make sure we don't remove it as dead 64009467b48Spatrick // later. 64109467b48Spatrick if (MO.isTied()) 64209467b48Spatrick ReadRegister(Reg, *MI, RegularUse); 64309467b48Spatrick Tracker.clobberRegister(Reg, *TRI); 64409467b48Spatrick } 64509467b48Spatrick 64609467b48Spatrick forwardUses(*MI); 64709467b48Spatrick 64809467b48Spatrick // Not a copy. 64909467b48Spatrick SmallVector<unsigned, 2> Defs; 65009467b48Spatrick const MachineOperand *RegMask = nullptr; 65109467b48Spatrick for (const MachineOperand &MO : MI->operands()) { 65209467b48Spatrick if (MO.isRegMask()) 65309467b48Spatrick RegMask = &MO; 65409467b48Spatrick if (!MO.isReg()) 65509467b48Spatrick continue; 65609467b48Spatrick Register Reg = MO.getReg(); 65709467b48Spatrick if (!Reg) 65809467b48Spatrick continue; 65909467b48Spatrick 66009467b48Spatrick assert(!Register::isVirtualRegister(Reg) && 66109467b48Spatrick "MachineCopyPropagation should be run after register allocation!"); 66209467b48Spatrick 66309467b48Spatrick if (MO.isDef() && !MO.isEarlyClobber()) { 66409467b48Spatrick Defs.push_back(Reg); 66509467b48Spatrick continue; 66609467b48Spatrick } else if (MO.readsReg()) 66709467b48Spatrick ReadRegister(Reg, *MI, MO.isDebug() ? DebugUse : RegularUse); 66809467b48Spatrick } 66909467b48Spatrick 67009467b48Spatrick // The instruction has a register mask operand which means that it clobbers 67109467b48Spatrick // a large set of registers. Treat clobbered registers the same way as 67209467b48Spatrick // defined registers. 67309467b48Spatrick if (RegMask) { 67409467b48Spatrick // Erase any MaybeDeadCopies whose destination register is clobbered. 67509467b48Spatrick for (SmallSetVector<MachineInstr *, 8>::iterator DI = 67609467b48Spatrick MaybeDeadCopies.begin(); 67709467b48Spatrick DI != MaybeDeadCopies.end();) { 67809467b48Spatrick MachineInstr *MaybeDead = *DI; 67909467b48Spatrick Register Reg = MaybeDead->getOperand(0).getReg(); 68009467b48Spatrick assert(!MRI->isReserved(Reg)); 68109467b48Spatrick 68209467b48Spatrick if (!RegMask->clobbersPhysReg(Reg)) { 68309467b48Spatrick ++DI; 68409467b48Spatrick continue; 68509467b48Spatrick } 68609467b48Spatrick 68709467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: "; 68809467b48Spatrick MaybeDead->dump()); 68909467b48Spatrick 69009467b48Spatrick // Make sure we invalidate any entries in the copy maps before erasing 69109467b48Spatrick // the instruction. 69209467b48Spatrick Tracker.clobberRegister(Reg, *TRI); 69309467b48Spatrick 69409467b48Spatrick // erase() will return the next valid iterator pointing to the next 69509467b48Spatrick // element after the erased one. 69609467b48Spatrick DI = MaybeDeadCopies.erase(DI); 69709467b48Spatrick MaybeDead->eraseFromParent(); 69809467b48Spatrick Changed = true; 69909467b48Spatrick ++NumDeletes; 70009467b48Spatrick } 70109467b48Spatrick } 70209467b48Spatrick 70309467b48Spatrick // Any previous copy definition or reading the Defs is no longer available. 70409467b48Spatrick for (unsigned Reg : Defs) 70509467b48Spatrick Tracker.clobberRegister(Reg, *TRI); 70609467b48Spatrick } 70709467b48Spatrick 70809467b48Spatrick // If MBB doesn't have successors, delete the copies whose defs are not used. 70909467b48Spatrick // If MBB does have successors, then conservative assume the defs are live-out 71009467b48Spatrick // since we don't want to trust live-in lists. 71109467b48Spatrick if (MBB.succ_empty()) { 71209467b48Spatrick for (MachineInstr *MaybeDead : MaybeDeadCopies) { 71309467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: Removing copy due to no live-out succ: "; 71409467b48Spatrick MaybeDead->dump()); 71509467b48Spatrick assert(!MRI->isReserved(MaybeDead->getOperand(0).getReg())); 71609467b48Spatrick 71709467b48Spatrick // Update matching debug values, if any. 71809467b48Spatrick assert(MaybeDead->isCopy()); 71909467b48Spatrick unsigned SrcReg = MaybeDead->getOperand(1).getReg(); 72009467b48Spatrick MRI->updateDbgUsersToReg(SrcReg, CopyDbgUsers[MaybeDead]); 72109467b48Spatrick 72209467b48Spatrick MaybeDead->eraseFromParent(); 72309467b48Spatrick Changed = true; 72409467b48Spatrick ++NumDeletes; 72509467b48Spatrick } 72609467b48Spatrick } 72709467b48Spatrick 72809467b48Spatrick MaybeDeadCopies.clear(); 72909467b48Spatrick CopyDbgUsers.clear(); 73009467b48Spatrick Tracker.clear(); 73109467b48Spatrick } 73209467b48Spatrick 73309467b48Spatrick static bool isBackwardPropagatableCopy(MachineInstr &MI, 73409467b48Spatrick const MachineRegisterInfo &MRI) { 73509467b48Spatrick assert(MI.isCopy() && "MI is expected to be a COPY"); 73609467b48Spatrick Register Def = MI.getOperand(0).getReg(); 73709467b48Spatrick Register Src = MI.getOperand(1).getReg(); 73809467b48Spatrick 73909467b48Spatrick if (!Def || !Src) 74009467b48Spatrick return false; 74109467b48Spatrick 74209467b48Spatrick if (MRI.isReserved(Def) || MRI.isReserved(Src)) 74309467b48Spatrick return false; 74409467b48Spatrick 74509467b48Spatrick return MI.getOperand(1).isRenamable() && MI.getOperand(1).isKill(); 74609467b48Spatrick } 74709467b48Spatrick 74809467b48Spatrick void MachineCopyPropagation::propagateDefs(MachineInstr &MI) { 74909467b48Spatrick if (!Tracker.hasAnyCopies()) 75009467b48Spatrick return; 75109467b48Spatrick 75209467b48Spatrick for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx != OpEnd; 75309467b48Spatrick ++OpIdx) { 75409467b48Spatrick MachineOperand &MODef = MI.getOperand(OpIdx); 75509467b48Spatrick 75609467b48Spatrick if (!MODef.isReg() || MODef.isUse()) 75709467b48Spatrick continue; 75809467b48Spatrick 75909467b48Spatrick // Ignore non-trivial cases. 76009467b48Spatrick if (MODef.isTied() || MODef.isUndef() || MODef.isImplicit()) 76109467b48Spatrick continue; 76209467b48Spatrick 76309467b48Spatrick if (!MODef.getReg()) 76409467b48Spatrick continue; 76509467b48Spatrick 76609467b48Spatrick // We only handle if the register comes from a vreg. 76709467b48Spatrick if (!MODef.isRenamable()) 76809467b48Spatrick continue; 76909467b48Spatrick 77009467b48Spatrick MachineInstr *Copy = 77109467b48Spatrick Tracker.findAvailBackwardCopy(MI, MODef.getReg(), *TRI); 77209467b48Spatrick if (!Copy) 77309467b48Spatrick continue; 77409467b48Spatrick 77509467b48Spatrick Register Def = Copy->getOperand(0).getReg(); 77609467b48Spatrick Register Src = Copy->getOperand(1).getReg(); 77709467b48Spatrick 77809467b48Spatrick if (MODef.getReg() != Src) 77909467b48Spatrick continue; 78009467b48Spatrick 78109467b48Spatrick if (!isBackwardPropagatableRegClassCopy(*Copy, MI, OpIdx)) 78209467b48Spatrick continue; 78309467b48Spatrick 78409467b48Spatrick if (hasImplicitOverlap(MI, MODef)) 78509467b48Spatrick continue; 78609467b48Spatrick 78709467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MODef.getReg(), TRI) 78809467b48Spatrick << "\n with " << printReg(Def, TRI) << "\n in " 78909467b48Spatrick << MI << " from " << *Copy); 79009467b48Spatrick 79109467b48Spatrick MODef.setReg(Def); 79209467b48Spatrick MODef.setIsRenamable(Copy->getOperand(0).isRenamable()); 79309467b48Spatrick 79409467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n"); 79509467b48Spatrick MaybeDeadCopies.insert(Copy); 79609467b48Spatrick Changed = true; 79709467b48Spatrick ++NumCopyBackwardPropagated; 79809467b48Spatrick } 79909467b48Spatrick } 80009467b48Spatrick 80109467b48Spatrick void MachineCopyPropagation::BackwardCopyPropagateBlock( 80209467b48Spatrick MachineBasicBlock &MBB) { 80309467b48Spatrick LLVM_DEBUG(dbgs() << "MCP: BackwardCopyPropagateBlock " << MBB.getName() 80409467b48Spatrick << "\n"); 80509467b48Spatrick 80609467b48Spatrick for (MachineBasicBlock::reverse_iterator I = MBB.rbegin(), E = MBB.rend(); 80709467b48Spatrick I != E;) { 80809467b48Spatrick MachineInstr *MI = &*I; 80909467b48Spatrick ++I; 81009467b48Spatrick 81109467b48Spatrick // Ignore non-trivial COPYs. 81209467b48Spatrick if (MI->isCopy() && MI->getNumOperands() == 2 && 81309467b48Spatrick !TRI->regsOverlap(MI->getOperand(0).getReg(), 81409467b48Spatrick MI->getOperand(1).getReg())) { 81509467b48Spatrick 81609467b48Spatrick Register Def = MI->getOperand(0).getReg(); 81709467b48Spatrick Register Src = MI->getOperand(1).getReg(); 81809467b48Spatrick 81909467b48Spatrick // Unlike forward cp, we don't invoke propagateDefs here, 82009467b48Spatrick // just let forward cp do COPY-to-COPY propagation. 82109467b48Spatrick if (isBackwardPropagatableCopy(*MI, *MRI)) { 82209467b48Spatrick Tracker.invalidateRegister(Src, *TRI); 82309467b48Spatrick Tracker.invalidateRegister(Def, *TRI); 82409467b48Spatrick Tracker.trackCopy(MI, *TRI); 82509467b48Spatrick continue; 82609467b48Spatrick } 82709467b48Spatrick } 82809467b48Spatrick 82909467b48Spatrick // Invalidate any earlyclobber regs first. 83009467b48Spatrick for (const MachineOperand &MO : MI->operands()) 83109467b48Spatrick if (MO.isReg() && MO.isEarlyClobber()) { 83209467b48Spatrick Register Reg = MO.getReg(); 83309467b48Spatrick if (!Reg) 83409467b48Spatrick continue; 83509467b48Spatrick Tracker.invalidateRegister(Reg, *TRI); 83609467b48Spatrick } 83709467b48Spatrick 83809467b48Spatrick propagateDefs(*MI); 83909467b48Spatrick for (const MachineOperand &MO : MI->operands()) { 84009467b48Spatrick if (!MO.isReg()) 84109467b48Spatrick continue; 84209467b48Spatrick 84309467b48Spatrick if (!MO.getReg()) 84409467b48Spatrick continue; 84509467b48Spatrick 84609467b48Spatrick if (MO.isDef()) 84709467b48Spatrick Tracker.invalidateRegister(MO.getReg(), *TRI); 84809467b48Spatrick 84909467b48Spatrick if (MO.readsReg()) 85009467b48Spatrick Tracker.invalidateRegister(MO.getReg(), *TRI); 85109467b48Spatrick } 85209467b48Spatrick } 85309467b48Spatrick 85409467b48Spatrick for (auto *Copy : MaybeDeadCopies) { 85509467b48Spatrick Copy->eraseFromParent(); 85609467b48Spatrick ++NumDeletes; 85709467b48Spatrick } 85809467b48Spatrick 85909467b48Spatrick MaybeDeadCopies.clear(); 86009467b48Spatrick CopyDbgUsers.clear(); 86109467b48Spatrick Tracker.clear(); 86209467b48Spatrick } 86309467b48Spatrick 86409467b48Spatrick bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) { 86509467b48Spatrick if (skipFunction(MF.getFunction())) 86609467b48Spatrick return false; 86709467b48Spatrick 86809467b48Spatrick Changed = false; 86909467b48Spatrick 87009467b48Spatrick TRI = MF.getSubtarget().getRegisterInfo(); 87109467b48Spatrick TII = MF.getSubtarget().getInstrInfo(); 87209467b48Spatrick MRI = &MF.getRegInfo(); 87309467b48Spatrick 87409467b48Spatrick for (MachineBasicBlock &MBB : MF) { 87509467b48Spatrick BackwardCopyPropagateBlock(MBB); 87609467b48Spatrick ForwardCopyPropagateBlock(MBB); 87709467b48Spatrick } 87809467b48Spatrick 87909467b48Spatrick return Changed; 88009467b48Spatrick } 881