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