10b57cec5SDimitry Andric //===- MachineCopyPropagation.cpp - Machine Copy Propagation Pass ---------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This is an extremely simple MachineInstr-level copy propagation pass. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric // This pass forwards the source of COPYs to the users of their destinations 120b57cec5SDimitry Andric // when doing so is legal. For example: 130b57cec5SDimitry Andric // 140b57cec5SDimitry Andric // %reg1 = COPY %reg0 150b57cec5SDimitry Andric // ... 160b57cec5SDimitry Andric // ... = OP %reg1 170b57cec5SDimitry Andric // 180b57cec5SDimitry Andric // If 190b57cec5SDimitry Andric // - %reg0 has not been clobbered by the time of the use of %reg1 200b57cec5SDimitry Andric // - the register class constraints are satisfied 210b57cec5SDimitry Andric // - the COPY def is the only value that reaches OP 220b57cec5SDimitry Andric // then this pass replaces the above with: 230b57cec5SDimitry Andric // 240b57cec5SDimitry Andric // %reg1 = COPY %reg0 250b57cec5SDimitry Andric // ... 260b57cec5SDimitry Andric // ... = OP %reg0 270b57cec5SDimitry Andric // 280b57cec5SDimitry Andric // This pass also removes some redundant COPYs. For example: 290b57cec5SDimitry Andric // 300b57cec5SDimitry Andric // %R1 = COPY %R0 310b57cec5SDimitry Andric // ... // No clobber of %R1 320b57cec5SDimitry Andric // %R0 = COPY %R1 <<< Removed 330b57cec5SDimitry Andric // 340b57cec5SDimitry Andric // or 350b57cec5SDimitry Andric // 360b57cec5SDimitry Andric // %R1 = COPY %R0 370b57cec5SDimitry Andric // ... // No clobber of %R0 380b57cec5SDimitry Andric // %R1 = COPY %R0 <<< Removed 390b57cec5SDimitry Andric // 400b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h" 430b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 440b57cec5SDimitry Andric #include "llvm/ADT/SetVector.h" 450b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 460b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h" 470b57cec5SDimitry Andric #include "llvm/ADT/iterator_range.h" 480b57cec5SDimitry Andric #include "llvm/CodeGen/MachineBasicBlock.h" 490b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 500b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h" 510b57cec5SDimitry Andric #include "llvm/CodeGen/MachineInstr.h" 520b57cec5SDimitry Andric #include "llvm/CodeGen/MachineOperand.h" 530b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 540b57cec5SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 550b57cec5SDimitry Andric #include "llvm/CodeGen/TargetRegisterInfo.h" 560b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h" 570b57cec5SDimitry Andric #include "llvm/MC/MCRegisterInfo.h" 580b57cec5SDimitry Andric #include "llvm/Pass.h" 590b57cec5SDimitry Andric #include "llvm/Support/Debug.h" 600b57cec5SDimitry Andric #include "llvm/Support/DebugCounter.h" 610b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h" 620b57cec5SDimitry Andric #include <cassert> 630b57cec5SDimitry Andric #include <iterator> 640b57cec5SDimitry Andric 650b57cec5SDimitry Andric using namespace llvm; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric #define DEBUG_TYPE "machine-cp" 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric STATISTIC(NumDeletes, "Number of dead copies deleted"); 700b57cec5SDimitry Andric STATISTIC(NumCopyForwards, "Number of copy uses forwarded"); 710b57cec5SDimitry Andric DEBUG_COUNTER(FwdCounter, "machine-cp-fwd", 720b57cec5SDimitry Andric "Controls which register COPYs are forwarded"); 730b57cec5SDimitry Andric 740b57cec5SDimitry Andric namespace { 750b57cec5SDimitry Andric 760b57cec5SDimitry Andric class CopyTracker { 770b57cec5SDimitry Andric struct CopyInfo { 780b57cec5SDimitry Andric MachineInstr *MI; 790b57cec5SDimitry Andric SmallVector<unsigned, 4> DefRegs; 800b57cec5SDimitry Andric bool Avail; 810b57cec5SDimitry Andric }; 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric DenseMap<unsigned, CopyInfo> Copies; 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric public: 860b57cec5SDimitry Andric /// Mark all of the given registers and their subregisters as unavailable for 870b57cec5SDimitry Andric /// copying. 880b57cec5SDimitry Andric void markRegsUnavailable(ArrayRef<unsigned> Regs, 890b57cec5SDimitry Andric const TargetRegisterInfo &TRI) { 900b57cec5SDimitry Andric for (unsigned Reg : Regs) { 910b57cec5SDimitry Andric // Source of copy is no longer available for propagation. 920b57cec5SDimitry Andric for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) { 930b57cec5SDimitry Andric auto CI = Copies.find(*RUI); 940b57cec5SDimitry Andric if (CI != Copies.end()) 950b57cec5SDimitry Andric CI->second.Avail = false; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric } 990b57cec5SDimitry Andric 1000b57cec5SDimitry Andric /// Clobber a single register, removing it from the tracker's copy maps. 1010b57cec5SDimitry Andric void clobberRegister(unsigned Reg, const TargetRegisterInfo &TRI) { 1020b57cec5SDimitry Andric for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) { 1030b57cec5SDimitry Andric auto I = Copies.find(*RUI); 1040b57cec5SDimitry Andric if (I != Copies.end()) { 1050b57cec5SDimitry Andric // When we clobber the source of a copy, we need to clobber everything 1060b57cec5SDimitry Andric // it defined. 1070b57cec5SDimitry Andric markRegsUnavailable(I->second.DefRegs, TRI); 1080b57cec5SDimitry Andric // When we clobber the destination of a copy, we need to clobber the 1090b57cec5SDimitry Andric // whole register it defined. 1100b57cec5SDimitry Andric if (MachineInstr *MI = I->second.MI) 1110b57cec5SDimitry Andric markRegsUnavailable({MI->getOperand(0).getReg()}, TRI); 1120b57cec5SDimitry Andric // Now we can erase the copy. 1130b57cec5SDimitry Andric Copies.erase(I); 1140b57cec5SDimitry Andric } 1150b57cec5SDimitry Andric } 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric /// Add this copy's registers into the tracker's copy maps. 1190b57cec5SDimitry Andric void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI) { 1200b57cec5SDimitry Andric assert(MI->isCopy() && "Tracking non-copy?"); 1210b57cec5SDimitry Andric 122*8bcb0991SDimitry Andric Register Def = MI->getOperand(0).getReg(); 123*8bcb0991SDimitry Andric Register Src = MI->getOperand(1).getReg(); 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric // Remember Def is defined by the copy. 1260b57cec5SDimitry Andric for (MCRegUnitIterator RUI(Def, &TRI); RUI.isValid(); ++RUI) 1270b57cec5SDimitry Andric Copies[*RUI] = {MI, {}, true}; 1280b57cec5SDimitry Andric 1290b57cec5SDimitry Andric // Remember source that's copied to Def. Once it's clobbered, then 1300b57cec5SDimitry Andric // it's no longer available for copy propagation. 1310b57cec5SDimitry Andric for (MCRegUnitIterator RUI(Src, &TRI); RUI.isValid(); ++RUI) { 1320b57cec5SDimitry Andric auto I = Copies.insert({*RUI, {nullptr, {}, false}}); 1330b57cec5SDimitry Andric auto &Copy = I.first->second; 1340b57cec5SDimitry Andric if (!is_contained(Copy.DefRegs, Def)) 1350b57cec5SDimitry Andric Copy.DefRegs.push_back(Def); 1360b57cec5SDimitry Andric } 1370b57cec5SDimitry Andric } 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric bool hasAnyCopies() { 1400b57cec5SDimitry Andric return !Copies.empty(); 1410b57cec5SDimitry Andric } 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric MachineInstr *findCopyForUnit(unsigned RegUnit, const TargetRegisterInfo &TRI, 1440b57cec5SDimitry Andric bool MustBeAvailable = false) { 1450b57cec5SDimitry Andric auto CI = Copies.find(RegUnit); 1460b57cec5SDimitry Andric if (CI == Copies.end()) 1470b57cec5SDimitry Andric return nullptr; 1480b57cec5SDimitry Andric if (MustBeAvailable && !CI->second.Avail) 1490b57cec5SDimitry Andric return nullptr; 1500b57cec5SDimitry Andric return CI->second.MI; 1510b57cec5SDimitry Andric } 1520b57cec5SDimitry Andric 1530b57cec5SDimitry Andric MachineInstr *findAvailCopy(MachineInstr &DestCopy, unsigned Reg, 1540b57cec5SDimitry Andric const TargetRegisterInfo &TRI) { 1550b57cec5SDimitry Andric // We check the first RegUnit here, since we'll only be interested in the 1560b57cec5SDimitry Andric // copy if it copies the entire register anyway. 1570b57cec5SDimitry Andric MCRegUnitIterator RUI(Reg, &TRI); 1580b57cec5SDimitry Andric MachineInstr *AvailCopy = 1590b57cec5SDimitry Andric findCopyForUnit(*RUI, TRI, /*MustBeAvailable=*/true); 1600b57cec5SDimitry Andric if (!AvailCopy || 1610b57cec5SDimitry Andric !TRI.isSubRegisterEq(AvailCopy->getOperand(0).getReg(), Reg)) 1620b57cec5SDimitry Andric return nullptr; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric // Check that the available copy isn't clobbered by any regmasks between 1650b57cec5SDimitry Andric // itself and the destination. 166*8bcb0991SDimitry Andric Register AvailSrc = AvailCopy->getOperand(1).getReg(); 167*8bcb0991SDimitry Andric Register AvailDef = AvailCopy->getOperand(0).getReg(); 1680b57cec5SDimitry Andric for (const MachineInstr &MI : 1690b57cec5SDimitry Andric make_range(AvailCopy->getIterator(), DestCopy.getIterator())) 1700b57cec5SDimitry Andric for (const MachineOperand &MO : MI.operands()) 1710b57cec5SDimitry Andric if (MO.isRegMask()) 1720b57cec5SDimitry Andric if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef)) 1730b57cec5SDimitry Andric return nullptr; 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric return AvailCopy; 1760b57cec5SDimitry Andric } 1770b57cec5SDimitry Andric 1780b57cec5SDimitry Andric void clear() { 1790b57cec5SDimitry Andric Copies.clear(); 1800b57cec5SDimitry Andric } 1810b57cec5SDimitry Andric }; 1820b57cec5SDimitry Andric 1830b57cec5SDimitry Andric class MachineCopyPropagation : public MachineFunctionPass { 1840b57cec5SDimitry Andric const TargetRegisterInfo *TRI; 1850b57cec5SDimitry Andric const TargetInstrInfo *TII; 1860b57cec5SDimitry Andric const MachineRegisterInfo *MRI; 1870b57cec5SDimitry Andric 1880b57cec5SDimitry Andric public: 1890b57cec5SDimitry Andric static char ID; // Pass identification, replacement for typeid 1900b57cec5SDimitry Andric 1910b57cec5SDimitry Andric MachineCopyPropagation() : MachineFunctionPass(ID) { 1920b57cec5SDimitry Andric initializeMachineCopyPropagationPass(*PassRegistry::getPassRegistry()); 1930b57cec5SDimitry Andric } 1940b57cec5SDimitry Andric 1950b57cec5SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override { 1960b57cec5SDimitry Andric AU.setPreservesCFG(); 1970b57cec5SDimitry Andric MachineFunctionPass::getAnalysisUsage(AU); 1980b57cec5SDimitry Andric } 1990b57cec5SDimitry Andric 2000b57cec5SDimitry Andric bool runOnMachineFunction(MachineFunction &MF) override; 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric MachineFunctionProperties getRequiredProperties() const override { 2030b57cec5SDimitry Andric return MachineFunctionProperties().set( 2040b57cec5SDimitry Andric MachineFunctionProperties::Property::NoVRegs); 2050b57cec5SDimitry Andric } 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric private: 208*8bcb0991SDimitry Andric typedef enum { DebugUse = false, RegularUse = true } DebugType; 209*8bcb0991SDimitry Andric 2100b57cec5SDimitry Andric void ClobberRegister(unsigned Reg); 211*8bcb0991SDimitry Andric void ReadRegister(unsigned Reg, MachineInstr &Reader, 212*8bcb0991SDimitry Andric DebugType DT); 2130b57cec5SDimitry Andric void CopyPropagateBlock(MachineBasicBlock &MBB); 2140b57cec5SDimitry Andric bool eraseIfRedundant(MachineInstr &Copy, unsigned Src, unsigned Def); 2150b57cec5SDimitry Andric void forwardUses(MachineInstr &MI); 2160b57cec5SDimitry Andric bool isForwardableRegClassCopy(const MachineInstr &Copy, 2170b57cec5SDimitry Andric const MachineInstr &UseI, unsigned UseIdx); 2180b57cec5SDimitry Andric bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use); 2190b57cec5SDimitry Andric 2200b57cec5SDimitry Andric /// Candidates for deletion. 2210b57cec5SDimitry Andric SmallSetVector<MachineInstr *, 8> MaybeDeadCopies; 2220b57cec5SDimitry Andric 223*8bcb0991SDimitry Andric /// Multimap tracking debug users in current BB 224*8bcb0991SDimitry Andric DenseMap<MachineInstr*, SmallVector<MachineInstr*, 2>> CopyDbgUsers; 225*8bcb0991SDimitry Andric 2260b57cec5SDimitry Andric CopyTracker Tracker; 2270b57cec5SDimitry Andric 2280b57cec5SDimitry Andric bool Changed; 2290b57cec5SDimitry Andric }; 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric } // end anonymous namespace 2320b57cec5SDimitry Andric 2330b57cec5SDimitry Andric char MachineCopyPropagation::ID = 0; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID; 2360b57cec5SDimitry Andric 2370b57cec5SDimitry Andric INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE, 2380b57cec5SDimitry Andric "Machine Copy Propagation Pass", false, false) 2390b57cec5SDimitry Andric 240*8bcb0991SDimitry Andric void MachineCopyPropagation::ReadRegister(unsigned Reg, MachineInstr &Reader, 241*8bcb0991SDimitry Andric DebugType DT) { 2420b57cec5SDimitry Andric // If 'Reg' is defined by a copy, the copy is no longer a candidate 243*8bcb0991SDimitry Andric // for elimination. If a copy is "read" by a debug user, record the user 244*8bcb0991SDimitry Andric // for propagation. 2450b57cec5SDimitry Andric for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) { 2460b57cec5SDimitry Andric if (MachineInstr *Copy = Tracker.findCopyForUnit(*RUI, *TRI)) { 247*8bcb0991SDimitry Andric if (DT == RegularUse) { 2480b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; Copy->dump()); 2490b57cec5SDimitry Andric MaybeDeadCopies.remove(Copy); 250*8bcb0991SDimitry Andric } else { 251*8bcb0991SDimitry Andric CopyDbgUsers[Copy].push_back(&Reader); 252*8bcb0991SDimitry Andric } 2530b57cec5SDimitry Andric } 2540b57cec5SDimitry Andric } 2550b57cec5SDimitry Andric } 2560b57cec5SDimitry Andric 2570b57cec5SDimitry Andric /// Return true if \p PreviousCopy did copy register \p Src to register \p Def. 2580b57cec5SDimitry Andric /// This fact may have been obscured by sub register usage or may not be true at 2590b57cec5SDimitry Andric /// all even though Src and Def are subregisters of the registers used in 2600b57cec5SDimitry Andric /// PreviousCopy. e.g. 2610b57cec5SDimitry Andric /// isNopCopy("ecx = COPY eax", AX, CX) == true 2620b57cec5SDimitry Andric /// isNopCopy("ecx = COPY eax", AH, CL) == false 2630b57cec5SDimitry Andric static bool isNopCopy(const MachineInstr &PreviousCopy, unsigned Src, 2640b57cec5SDimitry Andric unsigned Def, const TargetRegisterInfo *TRI) { 265*8bcb0991SDimitry Andric Register PreviousSrc = PreviousCopy.getOperand(1).getReg(); 266*8bcb0991SDimitry Andric Register PreviousDef = PreviousCopy.getOperand(0).getReg(); 2670b57cec5SDimitry Andric if (Src == PreviousSrc) { 2680b57cec5SDimitry Andric assert(Def == PreviousDef); 2690b57cec5SDimitry Andric return true; 2700b57cec5SDimitry Andric } 2710b57cec5SDimitry Andric if (!TRI->isSubRegister(PreviousSrc, Src)) 2720b57cec5SDimitry Andric return false; 2730b57cec5SDimitry Andric unsigned SubIdx = TRI->getSubRegIndex(PreviousSrc, Src); 2740b57cec5SDimitry Andric return SubIdx == TRI->getSubRegIndex(PreviousDef, Def); 2750b57cec5SDimitry Andric } 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric /// Remove instruction \p Copy if there exists a previous copy that copies the 2780b57cec5SDimitry Andric /// register \p Src to the register \p Def; This may happen indirectly by 2790b57cec5SDimitry Andric /// copying the super registers. 2800b57cec5SDimitry Andric bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src, 2810b57cec5SDimitry Andric unsigned Def) { 2820b57cec5SDimitry Andric // Avoid eliminating a copy from/to a reserved registers as we cannot predict 2830b57cec5SDimitry Andric // the value (Example: The sparc zero register is writable but stays zero). 2840b57cec5SDimitry Andric if (MRI->isReserved(Src) || MRI->isReserved(Def)) 2850b57cec5SDimitry Andric return false; 2860b57cec5SDimitry Andric 2870b57cec5SDimitry Andric // Search for an existing copy. 2880b57cec5SDimitry Andric MachineInstr *PrevCopy = Tracker.findAvailCopy(Copy, Def, *TRI); 2890b57cec5SDimitry Andric if (!PrevCopy) 2900b57cec5SDimitry Andric return false; 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric // Check that the existing copy uses the correct sub registers. 2930b57cec5SDimitry Andric if (PrevCopy->getOperand(0).isDead()) 2940b57cec5SDimitry Andric return false; 2950b57cec5SDimitry Andric if (!isNopCopy(*PrevCopy, Src, Def, TRI)) 2960b57cec5SDimitry Andric return false; 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; Copy.dump()); 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric // Copy was redundantly redefining either Src or Def. Remove earlier kill 3010b57cec5SDimitry Andric // flags between Copy and PrevCopy because the value will be reused now. 3020b57cec5SDimitry Andric assert(Copy.isCopy()); 303*8bcb0991SDimitry Andric Register CopyDef = Copy.getOperand(0).getReg(); 3040b57cec5SDimitry Andric assert(CopyDef == Src || CopyDef == Def); 3050b57cec5SDimitry Andric for (MachineInstr &MI : 3060b57cec5SDimitry Andric make_range(PrevCopy->getIterator(), Copy.getIterator())) 3070b57cec5SDimitry Andric MI.clearRegisterKills(CopyDef, TRI); 3080b57cec5SDimitry Andric 3090b57cec5SDimitry Andric Copy.eraseFromParent(); 3100b57cec5SDimitry Andric Changed = true; 3110b57cec5SDimitry Andric ++NumDeletes; 3120b57cec5SDimitry Andric return true; 3130b57cec5SDimitry Andric } 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric /// Decide whether we should forward the source of \param Copy to its use in 3160b57cec5SDimitry Andric /// \param UseI based on the physical register class constraints of the opcode 3170b57cec5SDimitry Andric /// and avoiding introducing more cross-class COPYs. 3180b57cec5SDimitry Andric bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy, 3190b57cec5SDimitry Andric const MachineInstr &UseI, 3200b57cec5SDimitry Andric unsigned UseIdx) { 3210b57cec5SDimitry Andric 322*8bcb0991SDimitry Andric Register CopySrcReg = Copy.getOperand(1).getReg(); 3230b57cec5SDimitry Andric 3240b57cec5SDimitry Andric // If the new register meets the opcode register constraints, then allow 3250b57cec5SDimitry Andric // forwarding. 3260b57cec5SDimitry Andric if (const TargetRegisterClass *URC = 3270b57cec5SDimitry Andric UseI.getRegClassConstraint(UseIdx, TII, TRI)) 3280b57cec5SDimitry Andric return URC->contains(CopySrcReg); 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric if (!UseI.isCopy()) 3310b57cec5SDimitry Andric return false; 3320b57cec5SDimitry Andric 3330b57cec5SDimitry Andric /// COPYs don't have register class constraints, so if the user instruction 3340b57cec5SDimitry Andric /// is a COPY, we just try to avoid introducing additional cross-class 3350b57cec5SDimitry Andric /// COPYs. For example: 3360b57cec5SDimitry Andric /// 3370b57cec5SDimitry Andric /// RegClassA = COPY RegClassB // Copy parameter 3380b57cec5SDimitry Andric /// ... 3390b57cec5SDimitry Andric /// RegClassB = COPY RegClassA // UseI parameter 3400b57cec5SDimitry Andric /// 3410b57cec5SDimitry Andric /// which after forwarding becomes 3420b57cec5SDimitry Andric /// 3430b57cec5SDimitry Andric /// RegClassA = COPY RegClassB 3440b57cec5SDimitry Andric /// ... 3450b57cec5SDimitry Andric /// RegClassB = COPY RegClassB 3460b57cec5SDimitry Andric /// 3470b57cec5SDimitry Andric /// so we have reduced the number of cross-class COPYs and potentially 3480b57cec5SDimitry Andric /// introduced a nop COPY that can be removed. 3490b57cec5SDimitry Andric const TargetRegisterClass *UseDstRC = 3500b57cec5SDimitry Andric TRI->getMinimalPhysRegClass(UseI.getOperand(0).getReg()); 3510b57cec5SDimitry Andric 3520b57cec5SDimitry Andric const TargetRegisterClass *SuperRC = UseDstRC; 3530b57cec5SDimitry Andric for (TargetRegisterClass::sc_iterator SuperRCI = UseDstRC->getSuperClasses(); 3540b57cec5SDimitry Andric SuperRC; SuperRC = *SuperRCI++) 3550b57cec5SDimitry Andric if (SuperRC->contains(CopySrcReg)) 3560b57cec5SDimitry Andric return true; 3570b57cec5SDimitry Andric 3580b57cec5SDimitry Andric return false; 3590b57cec5SDimitry Andric } 3600b57cec5SDimitry Andric 3610b57cec5SDimitry Andric /// Check that \p MI does not have implicit uses that overlap with it's \p Use 3620b57cec5SDimitry Andric /// operand (the register being replaced), since these can sometimes be 3630b57cec5SDimitry Andric /// implicitly tied to other operands. For example, on AMDGPU: 3640b57cec5SDimitry Andric /// 3650b57cec5SDimitry Andric /// V_MOVRELS_B32_e32 %VGPR2, %M0<imp-use>, %EXEC<imp-use>, %VGPR2_VGPR3_VGPR4_VGPR5<imp-use> 3660b57cec5SDimitry Andric /// 3670b57cec5SDimitry Andric /// the %VGPR2 is implicitly tied to the larger reg operand, but we have no 3680b57cec5SDimitry Andric /// way of knowing we need to update the latter when updating the former. 3690b57cec5SDimitry Andric bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI, 3700b57cec5SDimitry Andric const MachineOperand &Use) { 3710b57cec5SDimitry Andric for (const MachineOperand &MIUse : MI.uses()) 3720b57cec5SDimitry Andric if (&MIUse != &Use && MIUse.isReg() && MIUse.isImplicit() && 3730b57cec5SDimitry Andric MIUse.isUse() && TRI->regsOverlap(Use.getReg(), MIUse.getReg())) 3740b57cec5SDimitry Andric return true; 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric return false; 3770b57cec5SDimitry Andric } 3780b57cec5SDimitry Andric 3790b57cec5SDimitry Andric /// Look for available copies whose destination register is used by \p MI and 3800b57cec5SDimitry Andric /// replace the use in \p MI with the copy's source register. 3810b57cec5SDimitry Andric void MachineCopyPropagation::forwardUses(MachineInstr &MI) { 3820b57cec5SDimitry Andric if (!Tracker.hasAnyCopies()) 3830b57cec5SDimitry Andric return; 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric // Look for non-tied explicit vreg uses that have an active COPY 3860b57cec5SDimitry Andric // instruction that defines the physical register allocated to them. 3870b57cec5SDimitry Andric // Replace the vreg with the source of the active COPY. 3880b57cec5SDimitry Andric for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx < OpEnd; 3890b57cec5SDimitry Andric ++OpIdx) { 3900b57cec5SDimitry Andric MachineOperand &MOUse = MI.getOperand(OpIdx); 3910b57cec5SDimitry Andric // Don't forward into undef use operands since doing so can cause problems 3920b57cec5SDimitry Andric // with the machine verifier, since it doesn't treat undef reads as reads, 3930b57cec5SDimitry Andric // so we can end up with a live range that ends on an undef read, leading to 3940b57cec5SDimitry Andric // an error that the live range doesn't end on a read of the live range 3950b57cec5SDimitry Andric // register. 3960b57cec5SDimitry Andric if (!MOUse.isReg() || MOUse.isTied() || MOUse.isUndef() || MOUse.isDef() || 3970b57cec5SDimitry Andric MOUse.isImplicit()) 3980b57cec5SDimitry Andric continue; 3990b57cec5SDimitry Andric 4000b57cec5SDimitry Andric if (!MOUse.getReg()) 4010b57cec5SDimitry Andric continue; 4020b57cec5SDimitry Andric 4030b57cec5SDimitry Andric // Check that the register is marked 'renamable' so we know it is safe to 4040b57cec5SDimitry Andric // rename it without violating any constraints that aren't expressed in the 4050b57cec5SDimitry Andric // IR (e.g. ABI or opcode requirements). 4060b57cec5SDimitry Andric if (!MOUse.isRenamable()) 4070b57cec5SDimitry Andric continue; 4080b57cec5SDimitry Andric 4090b57cec5SDimitry Andric MachineInstr *Copy = Tracker.findAvailCopy(MI, MOUse.getReg(), *TRI); 4100b57cec5SDimitry Andric if (!Copy) 4110b57cec5SDimitry Andric continue; 4120b57cec5SDimitry Andric 413*8bcb0991SDimitry Andric Register CopyDstReg = Copy->getOperand(0).getReg(); 4140b57cec5SDimitry Andric const MachineOperand &CopySrc = Copy->getOperand(1); 415*8bcb0991SDimitry Andric Register CopySrcReg = CopySrc.getReg(); 4160b57cec5SDimitry Andric 4170b57cec5SDimitry Andric // FIXME: Don't handle partial uses of wider COPYs yet. 4180b57cec5SDimitry Andric if (MOUse.getReg() != CopyDstReg) { 4190b57cec5SDimitry Andric LLVM_DEBUG( 4200b57cec5SDimitry Andric dbgs() << "MCP: FIXME! Not forwarding COPY to sub-register use:\n " 4210b57cec5SDimitry Andric << MI); 4220b57cec5SDimitry Andric continue; 4230b57cec5SDimitry Andric } 4240b57cec5SDimitry Andric 4250b57cec5SDimitry Andric // Don't forward COPYs of reserved regs unless they are constant. 4260b57cec5SDimitry Andric if (MRI->isReserved(CopySrcReg) && !MRI->isConstantPhysReg(CopySrcReg)) 4270b57cec5SDimitry Andric continue; 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric if (!isForwardableRegClassCopy(*Copy, MI, OpIdx)) 4300b57cec5SDimitry Andric continue; 4310b57cec5SDimitry Andric 4320b57cec5SDimitry Andric if (hasImplicitOverlap(MI, MOUse)) 4330b57cec5SDimitry Andric continue; 4340b57cec5SDimitry Andric 4350b57cec5SDimitry Andric if (!DebugCounter::shouldExecute(FwdCounter)) { 4360b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "MCP: Skipping forwarding due to debug counter:\n " 4370b57cec5SDimitry Andric << MI); 4380b57cec5SDimitry Andric continue; 4390b57cec5SDimitry Andric } 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MOUse.getReg(), TRI) 4420b57cec5SDimitry Andric << "\n with " << printReg(CopySrcReg, TRI) 4430b57cec5SDimitry Andric << "\n in " << MI << " from " << *Copy); 4440b57cec5SDimitry Andric 4450b57cec5SDimitry Andric MOUse.setReg(CopySrcReg); 4460b57cec5SDimitry Andric if (!CopySrc.isRenamable()) 4470b57cec5SDimitry Andric MOUse.setIsRenamable(false); 4480b57cec5SDimitry Andric 4490b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n"); 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric // Clear kill markers that may have been invalidated. 4520b57cec5SDimitry Andric for (MachineInstr &KMI : 4530b57cec5SDimitry Andric make_range(Copy->getIterator(), std::next(MI.getIterator()))) 4540b57cec5SDimitry Andric KMI.clearRegisterKills(CopySrcReg, TRI); 4550b57cec5SDimitry Andric 4560b57cec5SDimitry Andric ++NumCopyForwards; 4570b57cec5SDimitry Andric Changed = true; 4580b57cec5SDimitry Andric } 4590b57cec5SDimitry Andric } 4600b57cec5SDimitry Andric 4610b57cec5SDimitry Andric void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { 4620b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "MCP: CopyPropagateBlock " << MBB.getName() << "\n"); 4630b57cec5SDimitry Andric 4640b57cec5SDimitry Andric for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ) { 4650b57cec5SDimitry Andric MachineInstr *MI = &*I; 4660b57cec5SDimitry Andric ++I; 4670b57cec5SDimitry Andric 4680b57cec5SDimitry Andric // Analyze copies (which don't overlap themselves). 4690b57cec5SDimitry Andric if (MI->isCopy() && !TRI->regsOverlap(MI->getOperand(0).getReg(), 4700b57cec5SDimitry Andric MI->getOperand(1).getReg())) { 471*8bcb0991SDimitry Andric Register Def = MI->getOperand(0).getReg(); 472*8bcb0991SDimitry Andric Register Src = MI->getOperand(1).getReg(); 4730b57cec5SDimitry Andric 474*8bcb0991SDimitry Andric assert(!Register::isVirtualRegister(Def) && 475*8bcb0991SDimitry Andric !Register::isVirtualRegister(Src) && 4760b57cec5SDimitry Andric "MachineCopyPropagation should be run after register allocation!"); 4770b57cec5SDimitry Andric 4780b57cec5SDimitry Andric // The two copies cancel out and the source of the first copy 4790b57cec5SDimitry Andric // hasn't been overridden, eliminate the second one. e.g. 4800b57cec5SDimitry Andric // %ecx = COPY %eax 4810b57cec5SDimitry Andric // ... nothing clobbered eax. 4820b57cec5SDimitry Andric // %eax = COPY %ecx 4830b57cec5SDimitry Andric // => 4840b57cec5SDimitry Andric // %ecx = COPY %eax 4850b57cec5SDimitry Andric // 4860b57cec5SDimitry Andric // or 4870b57cec5SDimitry Andric // 4880b57cec5SDimitry Andric // %ecx = COPY %eax 4890b57cec5SDimitry Andric // ... nothing clobbered eax. 4900b57cec5SDimitry Andric // %ecx = COPY %eax 4910b57cec5SDimitry Andric // => 4920b57cec5SDimitry Andric // %ecx = COPY %eax 4930b57cec5SDimitry Andric if (eraseIfRedundant(*MI, Def, Src) || eraseIfRedundant(*MI, Src, Def)) 4940b57cec5SDimitry Andric continue; 4950b57cec5SDimitry Andric 4960b57cec5SDimitry Andric forwardUses(*MI); 4970b57cec5SDimitry Andric 4980b57cec5SDimitry Andric // Src may have been changed by forwardUses() 4990b57cec5SDimitry Andric Src = MI->getOperand(1).getReg(); 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric // If Src is defined by a previous copy, the previous copy cannot be 5020b57cec5SDimitry Andric // eliminated. 503*8bcb0991SDimitry Andric ReadRegister(Src, *MI, RegularUse); 5040b57cec5SDimitry Andric for (const MachineOperand &MO : MI->implicit_operands()) { 5050b57cec5SDimitry Andric if (!MO.isReg() || !MO.readsReg()) 5060b57cec5SDimitry Andric continue; 507*8bcb0991SDimitry Andric Register Reg = MO.getReg(); 5080b57cec5SDimitry Andric if (!Reg) 5090b57cec5SDimitry Andric continue; 510*8bcb0991SDimitry Andric ReadRegister(Reg, *MI, RegularUse); 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI->dump()); 5140b57cec5SDimitry Andric 5150b57cec5SDimitry Andric // Copy is now a candidate for deletion. 5160b57cec5SDimitry Andric if (!MRI->isReserved(Def)) 5170b57cec5SDimitry Andric MaybeDeadCopies.insert(MI); 5180b57cec5SDimitry Andric 5190b57cec5SDimitry Andric // If 'Def' is previously source of another copy, then this earlier copy's 5200b57cec5SDimitry Andric // source is no longer available. e.g. 5210b57cec5SDimitry Andric // %xmm9 = copy %xmm2 5220b57cec5SDimitry Andric // ... 5230b57cec5SDimitry Andric // %xmm2 = copy %xmm0 5240b57cec5SDimitry Andric // ... 5250b57cec5SDimitry Andric // %xmm2 = copy %xmm9 5260b57cec5SDimitry Andric Tracker.clobberRegister(Def, *TRI); 5270b57cec5SDimitry Andric for (const MachineOperand &MO : MI->implicit_operands()) { 5280b57cec5SDimitry Andric if (!MO.isReg() || !MO.isDef()) 5290b57cec5SDimitry Andric continue; 530*8bcb0991SDimitry Andric Register Reg = MO.getReg(); 5310b57cec5SDimitry Andric if (!Reg) 5320b57cec5SDimitry Andric continue; 5330b57cec5SDimitry Andric Tracker.clobberRegister(Reg, *TRI); 5340b57cec5SDimitry Andric } 5350b57cec5SDimitry Andric 5360b57cec5SDimitry Andric Tracker.trackCopy(MI, *TRI); 5370b57cec5SDimitry Andric 5380b57cec5SDimitry Andric continue; 5390b57cec5SDimitry Andric } 5400b57cec5SDimitry Andric 5410b57cec5SDimitry Andric // Clobber any earlyclobber regs first. 5420b57cec5SDimitry Andric for (const MachineOperand &MO : MI->operands()) 5430b57cec5SDimitry Andric if (MO.isReg() && MO.isEarlyClobber()) { 544*8bcb0991SDimitry Andric Register Reg = MO.getReg(); 5450b57cec5SDimitry Andric // If we have a tied earlyclobber, that means it is also read by this 5460b57cec5SDimitry Andric // instruction, so we need to make sure we don't remove it as dead 5470b57cec5SDimitry Andric // later. 5480b57cec5SDimitry Andric if (MO.isTied()) 549*8bcb0991SDimitry Andric ReadRegister(Reg, *MI, RegularUse); 5500b57cec5SDimitry Andric Tracker.clobberRegister(Reg, *TRI); 5510b57cec5SDimitry Andric } 5520b57cec5SDimitry Andric 5530b57cec5SDimitry Andric forwardUses(*MI); 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric // Not a copy. 5560b57cec5SDimitry Andric SmallVector<unsigned, 2> Defs; 5570b57cec5SDimitry Andric const MachineOperand *RegMask = nullptr; 5580b57cec5SDimitry Andric for (const MachineOperand &MO : MI->operands()) { 5590b57cec5SDimitry Andric if (MO.isRegMask()) 5600b57cec5SDimitry Andric RegMask = &MO; 5610b57cec5SDimitry Andric if (!MO.isReg()) 5620b57cec5SDimitry Andric continue; 563*8bcb0991SDimitry Andric Register Reg = MO.getReg(); 5640b57cec5SDimitry Andric if (!Reg) 5650b57cec5SDimitry Andric continue; 5660b57cec5SDimitry Andric 567*8bcb0991SDimitry Andric assert(!Register::isVirtualRegister(Reg) && 5680b57cec5SDimitry Andric "MachineCopyPropagation should be run after register allocation!"); 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric if (MO.isDef() && !MO.isEarlyClobber()) { 5710b57cec5SDimitry Andric Defs.push_back(Reg); 5720b57cec5SDimitry Andric continue; 573*8bcb0991SDimitry Andric } else if (MO.readsReg()) 574*8bcb0991SDimitry Andric ReadRegister(Reg, *MI, MO.isDebug() ? DebugUse : RegularUse); 5750b57cec5SDimitry Andric } 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric // The instruction has a register mask operand which means that it clobbers 5780b57cec5SDimitry Andric // a large set of registers. Treat clobbered registers the same way as 5790b57cec5SDimitry Andric // defined registers. 5800b57cec5SDimitry Andric if (RegMask) { 5810b57cec5SDimitry Andric // Erase any MaybeDeadCopies whose destination register is clobbered. 5820b57cec5SDimitry Andric for (SmallSetVector<MachineInstr *, 8>::iterator DI = 5830b57cec5SDimitry Andric MaybeDeadCopies.begin(); 5840b57cec5SDimitry Andric DI != MaybeDeadCopies.end();) { 5850b57cec5SDimitry Andric MachineInstr *MaybeDead = *DI; 586*8bcb0991SDimitry Andric Register Reg = MaybeDead->getOperand(0).getReg(); 5870b57cec5SDimitry Andric assert(!MRI->isReserved(Reg)); 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric if (!RegMask->clobbersPhysReg(Reg)) { 5900b57cec5SDimitry Andric ++DI; 5910b57cec5SDimitry Andric continue; 5920b57cec5SDimitry Andric } 5930b57cec5SDimitry Andric 5940b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: "; 5950b57cec5SDimitry Andric MaybeDead->dump()); 5960b57cec5SDimitry Andric 5970b57cec5SDimitry Andric // Make sure we invalidate any entries in the copy maps before erasing 5980b57cec5SDimitry Andric // the instruction. 5990b57cec5SDimitry Andric Tracker.clobberRegister(Reg, *TRI); 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric // erase() will return the next valid iterator pointing to the next 6020b57cec5SDimitry Andric // element after the erased one. 6030b57cec5SDimitry Andric DI = MaybeDeadCopies.erase(DI); 6040b57cec5SDimitry Andric MaybeDead->eraseFromParent(); 6050b57cec5SDimitry Andric Changed = true; 6060b57cec5SDimitry Andric ++NumDeletes; 6070b57cec5SDimitry Andric } 6080b57cec5SDimitry Andric } 6090b57cec5SDimitry Andric 6100b57cec5SDimitry Andric // Any previous copy definition or reading the Defs is no longer available. 6110b57cec5SDimitry Andric for (unsigned Reg : Defs) 6120b57cec5SDimitry Andric Tracker.clobberRegister(Reg, *TRI); 6130b57cec5SDimitry Andric } 6140b57cec5SDimitry Andric 6150b57cec5SDimitry Andric // If MBB doesn't have successors, delete the copies whose defs are not used. 6160b57cec5SDimitry Andric // If MBB does have successors, then conservative assume the defs are live-out 6170b57cec5SDimitry Andric // since we don't want to trust live-in lists. 6180b57cec5SDimitry Andric if (MBB.succ_empty()) { 6190b57cec5SDimitry Andric for (MachineInstr *MaybeDead : MaybeDeadCopies) { 6200b57cec5SDimitry Andric LLVM_DEBUG(dbgs() << "MCP: Removing copy due to no live-out succ: "; 6210b57cec5SDimitry Andric MaybeDead->dump()); 6220b57cec5SDimitry Andric assert(!MRI->isReserved(MaybeDead->getOperand(0).getReg())); 6230b57cec5SDimitry Andric 624*8bcb0991SDimitry Andric // Update matching debug values, if any. 6250b57cec5SDimitry Andric assert(MaybeDead->isCopy()); 626*8bcb0991SDimitry Andric unsigned SrcReg = MaybeDead->getOperand(1).getReg(); 627*8bcb0991SDimitry Andric MRI->updateDbgUsersToReg(SrcReg, CopyDbgUsers[MaybeDead]); 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric MaybeDead->eraseFromParent(); 6300b57cec5SDimitry Andric Changed = true; 6310b57cec5SDimitry Andric ++NumDeletes; 6320b57cec5SDimitry Andric } 6330b57cec5SDimitry Andric } 6340b57cec5SDimitry Andric 6350b57cec5SDimitry Andric MaybeDeadCopies.clear(); 636*8bcb0991SDimitry Andric CopyDbgUsers.clear(); 6370b57cec5SDimitry Andric Tracker.clear(); 6380b57cec5SDimitry Andric } 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andric bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) { 6410b57cec5SDimitry Andric if (skipFunction(MF.getFunction())) 6420b57cec5SDimitry Andric return false; 6430b57cec5SDimitry Andric 6440b57cec5SDimitry Andric Changed = false; 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric TRI = MF.getSubtarget().getRegisterInfo(); 6470b57cec5SDimitry Andric TII = MF.getSubtarget().getInstrInfo(); 6480b57cec5SDimitry Andric MRI = &MF.getRegInfo(); 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric for (MachineBasicBlock &MBB : MF) 6510b57cec5SDimitry Andric CopyPropagateBlock(MBB); 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric return Changed; 6540b57cec5SDimitry Andric } 655