diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2022-07-04 19:20:19 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2023-02-08 19:02:26 +0000 |
commit | 81ad626541db97eb356e2c1d4a20eb2a26a766ab (patch) | |
tree | 311b6a8987c32b1e1dcbab65c54cfac3fdb56175 /contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp | |
parent | 5fff09660e06a66bed6482da9c70df328e16bbb6 (diff) | |
parent | 145449b1e420787bb99721a429341fa6be3adfb6 (diff) |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp | 426 |
1 files changed, 257 insertions, 169 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp index 57fbe4112e47..66f0eb83e57c 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -83,8 +83,24 @@ STATISTIC(NumCopyBackwardPropagated, "Number of copy defs backward propagated"); DEBUG_COUNTER(FwdCounter, "machine-cp-fwd", "Controls which register COPYs are forwarded"); +static cl::opt<bool> MCPUseCopyInstr("mcp-use-is-copy-instr", cl::init(false), + cl::Hidden); + namespace { +static Optional<DestSourcePair> isCopyInstr(const MachineInstr &MI, + const TargetInstrInfo &TII, + bool UseCopyInstr) { + if (UseCopyInstr) + return TII.isCopyInstr(MI); + + if (MI.isCopy()) + return Optional<DestSourcePair>( + DestSourcePair{MI.getOperand(0), MI.getOperand(1)}); + + return None; +} + class CopyTracker { struct CopyInfo { MachineInstr *MI; @@ -110,7 +126,8 @@ public: } /// Remove register from copy maps. - void invalidateRegister(MCRegister Reg, const TargetRegisterInfo &TRI) { + void invalidateRegister(MCRegister Reg, const TargetRegisterInfo &TRI, + const TargetInstrInfo &TII, bool UseCopyInstr) { // Since Reg might be a subreg of some registers, only invalidate Reg is not // enough. We have to find the COPY defines Reg or registers defined by Reg // and invalidate all of them. @@ -120,8 +137,13 @@ public: auto I = Copies.find(*RUI); if (I != Copies.end()) { if (MachineInstr *MI = I->second.MI) { - RegsToInvalidate.insert(MI->getOperand(0).getReg().asMCReg()); - RegsToInvalidate.insert(MI->getOperand(1).getReg().asMCReg()); + Optional<DestSourcePair> CopyOperands = + isCopyInstr(*MI, TII, UseCopyInstr); + assert(CopyOperands && "Expect copy"); + + RegsToInvalidate.insert( + CopyOperands->Destination->getReg().asMCReg()); + RegsToInvalidate.insert(CopyOperands->Source->getReg().asMCReg()); } RegsToInvalidate.insert(I->second.DefRegs.begin(), I->second.DefRegs.end()); @@ -133,7 +155,8 @@ public: } /// Clobber a single register, removing it from the tracker's copy maps. - void clobberRegister(MCRegister Reg, const TargetRegisterInfo &TRI) { + void clobberRegister(MCRegister Reg, const TargetRegisterInfo &TRI, + const TargetInstrInfo &TII, bool UseCopyInstr) { for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) { auto I = Copies.find(*RUI); if (I != Copies.end()) { @@ -142,8 +165,12 @@ public: markRegsUnavailable(I->second.DefRegs, TRI); // When we clobber the destination of a copy, we need to clobber the // whole register it defined. - if (MachineInstr *MI = I->second.MI) - markRegsUnavailable({MI->getOperand(0).getReg().asMCReg()}, TRI); + if (MachineInstr *MI = I->second.MI) { + Optional<DestSourcePair> CopyOperands = + isCopyInstr(*MI, TII, UseCopyInstr); + markRegsUnavailable({CopyOperands->Destination->getReg().asMCReg()}, + TRI); + } // Now we can erase the copy. Copies.erase(I); } @@ -151,11 +178,13 @@ public: } /// Add this copy's registers into the tracker's copy maps. - void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI) { - assert(MI->isCopy() && "Tracking non-copy?"); + void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI, + const TargetInstrInfo &TII, bool UseCopyInstr) { + Optional<DestSourcePair> CopyOperands = isCopyInstr(*MI, TII, UseCopyInstr); + assert(CopyOperands && "Tracking non-copy?"); - MCRegister Def = MI->getOperand(0).getReg().asMCReg(); - MCRegister Src = MI->getOperand(1).getReg().asMCReg(); + MCRegister Src = CopyOperands->Source->getReg().asMCReg(); + MCRegister Def = CopyOperands->Destination->getReg().asMCReg(); // Remember Def is defined by the copy. for (MCRegUnitIterator RUI(Def, &TRI); RUI.isValid(); ++RUI) @@ -198,15 +227,22 @@ public: } MachineInstr *findAvailBackwardCopy(MachineInstr &I, MCRegister Reg, - const TargetRegisterInfo &TRI) { + const TargetRegisterInfo &TRI, + const TargetInstrInfo &TII, + bool UseCopyInstr) { MCRegUnitIterator RUI(Reg, &TRI); MachineInstr *AvailCopy = findCopyDefViaUnit(*RUI, TRI); - if (!AvailCopy || - !TRI.isSubRegisterEq(AvailCopy->getOperand(1).getReg(), Reg)) + + if (!AvailCopy) + return nullptr; + + Optional<DestSourcePair> CopyOperands = + isCopyInstr(*AvailCopy, TII, UseCopyInstr); + Register AvailSrc = CopyOperands->Source->getReg(); + Register AvailDef = CopyOperands->Destination->getReg(); + if (!TRI.isSubRegisterEq(AvailSrc, Reg)) return nullptr; - Register AvailSrc = AvailCopy->getOperand(1).getReg(); - Register AvailDef = AvailCopy->getOperand(0).getReg(); for (const MachineInstr &MI : make_range(AvailCopy->getReverseIterator(), I.getReverseIterator())) for (const MachineOperand &MO : MI.operands()) @@ -219,20 +255,26 @@ public: } MachineInstr *findAvailCopy(MachineInstr &DestCopy, MCRegister Reg, - const TargetRegisterInfo &TRI) { + const TargetRegisterInfo &TRI, + const TargetInstrInfo &TII, bool UseCopyInstr) { // We check the first RegUnit here, since we'll only be interested in the // copy if it copies the entire register anyway. MCRegUnitIterator RUI(Reg, &TRI); MachineInstr *AvailCopy = findCopyForUnit(*RUI, TRI, /*MustBeAvailable=*/true); - if (!AvailCopy || - !TRI.isSubRegisterEq(AvailCopy->getOperand(0).getReg(), Reg)) + + if (!AvailCopy) + return nullptr; + + Optional<DestSourcePair> CopyOperands = + isCopyInstr(*AvailCopy, TII, UseCopyInstr); + Register AvailSrc = CopyOperands->Source->getReg(); + Register AvailDef = CopyOperands->Destination->getReg(); + if (!TRI.isSubRegisterEq(AvailDef, Reg)) return nullptr; // Check that the available copy isn't clobbered by any regmasks between // itself and the destination. - Register AvailSrc = AvailCopy->getOperand(1).getReg(); - Register AvailDef = AvailCopy->getOperand(0).getReg(); for (const MachineInstr &MI : make_range(AvailCopy->getIterator(), DestCopy.getIterator())) for (const MachineOperand &MO : MI.operands()) @@ -253,10 +295,14 @@ class MachineCopyPropagation : public MachineFunctionPass { const TargetInstrInfo *TII; const MachineRegisterInfo *MRI; + // Return true if this is a copy instruction and false otherwise. + bool UseCopyInstr; + public: static char ID; // Pass identification, replacement for typeid - MachineCopyPropagation() : MachineFunctionPass(ID) { + MachineCopyPropagation(bool CopyInstr = false) + : MachineFunctionPass(ID), UseCopyInstr(CopyInstr || MCPUseCopyInstr) { initializeMachineCopyPropagationPass(*PassRegistry::getPassRegistry()); } @@ -334,9 +380,13 @@ void MachineCopyPropagation::ReadRegister(MCRegister Reg, MachineInstr &Reader, /// isNopCopy("ecx = COPY eax", AX, CX) == true /// isNopCopy("ecx = COPY eax", AH, CL) == false static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src, - MCRegister Def, const TargetRegisterInfo *TRI) { - MCRegister PreviousSrc = PreviousCopy.getOperand(1).getReg().asMCReg(); - MCRegister PreviousDef = PreviousCopy.getOperand(0).getReg().asMCReg(); + MCRegister Def, const TargetRegisterInfo *TRI, + const TargetInstrInfo *TII, bool UseCopyInstr) { + + Optional<DestSourcePair> CopyOperands = + isCopyInstr(PreviousCopy, *TII, UseCopyInstr); + MCRegister PreviousSrc = CopyOperands->Source->getReg().asMCReg(); + MCRegister PreviousDef = CopyOperands->Destination->getReg().asMCReg(); if (Src == PreviousSrc && Def == PreviousDef) return true; if (!TRI->isSubRegister(PreviousSrc, Src)) @@ -356,22 +406,26 @@ bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, return false; // Search for an existing copy. - MachineInstr *PrevCopy = Tracker.findAvailCopy(Copy, Def, *TRI); + MachineInstr *PrevCopy = + Tracker.findAvailCopy(Copy, Def, *TRI, *TII, UseCopyInstr); if (!PrevCopy) return false; + auto PrevCopyOperands = isCopyInstr(*PrevCopy, *TII, UseCopyInstr); // Check that the existing copy uses the correct sub registers. - if (PrevCopy->getOperand(0).isDead()) + if (PrevCopyOperands->Destination->isDead()) return false; - if (!isNopCopy(*PrevCopy, Src, Def, TRI)) + if (!isNopCopy(*PrevCopy, Src, Def, TRI, TII, UseCopyInstr)) return false; LLVM_DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; Copy.dump()); // Copy was redundantly redefining either Src or Def. Remove earlier kill // flags between Copy and PrevCopy because the value will be reused now. - assert(Copy.isCopy()); - Register CopyDef = Copy.getOperand(0).getReg(); + Optional<DestSourcePair> CopyOperands = isCopyInstr(Copy, *TII, UseCopyInstr); + assert(CopyOperands); + + Register CopyDef = CopyOperands->Destination->getReg(); assert(CopyDef == Src || CopyDef == Def); for (MachineInstr &MI : make_range(PrevCopy->getIterator(), Copy.getIterator())) @@ -385,7 +439,9 @@ bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy( const MachineInstr &Copy, const MachineInstr &UseI, unsigned UseIdx) { - Register Def = Copy.getOperand(0).getReg(); + + Optional<DestSourcePair> CopyOperands = isCopyInstr(Copy, *TII, UseCopyInstr); + Register Def = CopyOperands->Destination->getReg(); if (const TargetRegisterClass *URC = UseI.getRegClassConstraint(UseIdx, TII, TRI)) @@ -403,7 +459,8 @@ bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy, const MachineInstr &UseI, unsigned UseIdx) { - Register CopySrcReg = Copy.getOperand(1).getReg(); + Optional<DestSourcePair> CopyOperands = isCopyInstr(Copy, *TII, UseCopyInstr); + Register CopySrcReg = CopyOperands->Source->getReg(); // If the new register meets the opcode register constraints, then allow // forwarding. @@ -411,34 +468,10 @@ bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy, UseI.getRegClassConstraint(UseIdx, TII, TRI)) return URC->contains(CopySrcReg); - if (!UseI.isCopy()) + auto UseICopyOperands = isCopyInstr(UseI, *TII, UseCopyInstr); + if (!UseICopyOperands) return false; - const TargetRegisterClass *CopySrcRC = - TRI->getMinimalPhysRegClass(CopySrcReg); - const TargetRegisterClass *UseDstRC = - TRI->getMinimalPhysRegClass(UseI.getOperand(0).getReg()); - const TargetRegisterClass *CrossCopyRC = TRI->getCrossCopyRegClass(CopySrcRC); - - // If cross copy register class is not the same as copy source register class - // then it is not possible to copy the register directly and requires a cross - // register class copy. Fowarding this copy without checking register class of - // UseDst may create additional cross register copies when expanding the copy - // instruction in later passes. - if (CopySrcRC != CrossCopyRC) { - const TargetRegisterClass *CopyDstRC = - TRI->getMinimalPhysRegClass(Copy.getOperand(0).getReg()); - - // Check if UseDstRC matches the necessary register class to copy from - // CopySrc's register class. If so then forwarding the copy will not - // introduce any cross-class copys. Else if CopyDstRC matches then keep the - // copy and do not forward. If neither UseDstRC or CopyDstRC matches then - // we may need a cross register copy later but we do not worry about it - // here. - if (UseDstRC != CrossCopyRC && CopyDstRC == CrossCopyRC) - return false; - } - /// COPYs don't have register class constraints, so if the user instruction /// is a COPY, we just try to avoid introducing additional cross-class /// COPYs. For example: @@ -455,12 +488,34 @@ bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy, /// /// so we have reduced the number of cross-class COPYs and potentially /// introduced a nop COPY that can be removed. - const TargetRegisterClass *SuperRC = UseDstRC; - for (TargetRegisterClass::sc_iterator SuperRCI = UseDstRC->getSuperClasses(); - SuperRC; SuperRC = *SuperRCI++) - if (SuperRC->contains(CopySrcReg)) - return true; + // Allow forwarding if src and dst belong to any common class, so long as they + // don't belong to any (possibly smaller) common class that requires copies to + // go via a different class. + Register UseDstReg = UseICopyOperands->Destination->getReg(); + bool Found = false; + bool IsCrossClass = false; + for (const TargetRegisterClass *RC : TRI->regclasses()) { + if (RC->contains(CopySrcReg) && RC->contains(UseDstReg)) { + Found = true; + if (TRI->getCrossCopyRegClass(RC) != RC) { + IsCrossClass = true; + break; + } + } + } + if (!Found) + return false; + if (!IsCrossClass) + return true; + // The forwarded copy would be cross-class. Only do this if the original copy + // was also cross-class. + Register CopyDstReg = CopyOperands->Destination->getReg(); + for (const TargetRegisterClass *RC : TRI->regclasses()) { + if (RC->contains(CopySrcReg) && RC->contains(CopyDstReg) && + TRI->getCrossCopyRegClass(RC) != RC) + return true; + } return false; } @@ -527,13 +582,15 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) { if (!MOUse.isRenamable()) continue; - MachineInstr *Copy = - Tracker.findAvailCopy(MI, MOUse.getReg().asMCReg(), *TRI); + MachineInstr *Copy = Tracker.findAvailCopy(MI, MOUse.getReg().asMCReg(), + *TRI, *TII, UseCopyInstr); if (!Copy) continue; - Register CopyDstReg = Copy->getOperand(0).getReg(); - const MachineOperand &CopySrc = Copy->getOperand(1); + Optional<DestSourcePair> CopyOperands = + isCopyInstr(*Copy, *TII, UseCopyInstr); + Register CopyDstReg = CopyOperands->Destination->getReg(); + const MachineOperand &CopySrc = *CopyOperands->Source; Register CopySrcReg = CopySrc.getReg(); // FIXME: Don't handle partial uses of wider COPYs yet. @@ -557,7 +614,8 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) { // Check that the instruction is not a copy that partially overwrites the // original copy source that we are about to use. The tracker mechanism // cannot cope with that. - if (MI.isCopy() && MI.modifiesRegister(CopySrcReg, TRI) && + if (isCopyInstr(MI, *TII, UseCopyInstr) && + MI.modifiesRegister(CopySrcReg, TRI) && !MI.definesRegister(CopySrcReg)) { LLVM_DEBUG(dbgs() << "MCP: Copy source overlap with dest in " << MI); continue; @@ -596,76 +654,82 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { for (MachineInstr &MI : llvm::make_early_inc_range(MBB)) { // Analyze copies (which don't overlap themselves). - if (MI.isCopy() && !TRI->regsOverlap(MI.getOperand(0).getReg(), - MI.getOperand(1).getReg())) { - assert(MI.getOperand(0).getReg().isPhysical() && - MI.getOperand(1).getReg().isPhysical() && - "MachineCopyPropagation should be run after register allocation!"); - - MCRegister Def = MI.getOperand(0).getReg().asMCReg(); - MCRegister Src = MI.getOperand(1).getReg().asMCReg(); - - // The two copies cancel out and the source of the first copy - // hasn't been overridden, eliminate the second one. e.g. - // %ecx = COPY %eax - // ... nothing clobbered eax. - // %eax = COPY %ecx - // => - // %ecx = COPY %eax - // - // or - // - // %ecx = COPY %eax - // ... nothing clobbered eax. - // %ecx = COPY %eax - // => - // %ecx = COPY %eax - if (eraseIfRedundant(MI, Def, Src) || eraseIfRedundant(MI, Src, Def)) - continue; + Optional<DestSourcePair> CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr); + if (CopyOperands) { + + Register RegSrc = CopyOperands->Source->getReg(); + Register RegDef = CopyOperands->Destination->getReg(); + + if (!TRI->regsOverlap(RegDef, RegSrc)) { + assert(RegDef.isPhysical() && RegSrc.isPhysical() && + "MachineCopyPropagation should be run after register allocation!"); + + MCRegister Def = RegDef.asMCReg(); + MCRegister Src = RegSrc.asMCReg(); + + // The two copies cancel out and the source of the first copy + // hasn't been overridden, eliminate the second one. e.g. + // %ecx = COPY %eax + // ... nothing clobbered eax. + // %eax = COPY %ecx + // => + // %ecx = COPY %eax + // + // or + // + // %ecx = COPY %eax + // ... nothing clobbered eax. + // %ecx = COPY %eax + // => + // %ecx = COPY %eax + if (eraseIfRedundant(MI, Def, Src) || eraseIfRedundant(MI, Src, Def)) + continue; - forwardUses(MI); + forwardUses(MI); + + // Src may have been changed by forwardUses() + CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr); + Src = CopyOperands->Source->getReg().asMCReg(); + + // If Src is defined by a previous copy, the previous copy cannot be + // eliminated. + ReadRegister(Src, MI, RegularUse); + for (const MachineOperand &MO : MI.implicit_operands()) { + if (!MO.isReg() || !MO.readsReg()) + continue; + MCRegister Reg = MO.getReg().asMCReg(); + if (!Reg) + continue; + ReadRegister(Reg, MI, RegularUse); + } - // Src may have been changed by forwardUses() - Src = MI.getOperand(1).getReg().asMCReg(); + LLVM_DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI.dump()); + + // Copy is now a candidate for deletion. + if (!MRI->isReserved(Def)) + MaybeDeadCopies.insert(&MI); + + // If 'Def' is previously source of another copy, then this earlier copy's + // source is no longer available. e.g. + // %xmm9 = copy %xmm2 + // ... + // %xmm2 = copy %xmm0 + // ... + // %xmm2 = copy %xmm9 + Tracker.clobberRegister(Def, *TRI, *TII, UseCopyInstr); + for (const MachineOperand &MO : MI.implicit_operands()) { + if (!MO.isReg() || !MO.isDef()) + continue; + MCRegister Reg = MO.getReg().asMCReg(); + if (!Reg) + continue; + Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr); + } - // If Src is defined by a previous copy, the previous copy cannot be - // eliminated. - ReadRegister(Src, MI, RegularUse); - for (const MachineOperand &MO : MI.implicit_operands()) { - if (!MO.isReg() || !MO.readsReg()) - continue; - MCRegister Reg = MO.getReg().asMCReg(); - if (!Reg) - continue; - ReadRegister(Reg, MI, RegularUse); - } + Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr); - LLVM_DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI.dump()); - - // Copy is now a candidate for deletion. - if (!MRI->isReserved(Def)) - MaybeDeadCopies.insert(&MI); - - // If 'Def' is previously source of another copy, then this earlier copy's - // source is no longer available. e.g. - // %xmm9 = copy %xmm2 - // ... - // %xmm2 = copy %xmm0 - // ... - // %xmm2 = copy %xmm9 - Tracker.clobberRegister(Def, *TRI); - for (const MachineOperand &MO : MI.implicit_operands()) { - if (!MO.isReg() || !MO.isDef()) - continue; - MCRegister Reg = MO.getReg().asMCReg(); - if (!Reg) - continue; - Tracker.clobberRegister(Reg, *TRI); + continue; } - - Tracker.trackCopy(&MI, *TRI); - - continue; } // Clobber any earlyclobber regs first. @@ -677,7 +741,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { // later. if (MO.isTied()) ReadRegister(Reg, MI, RegularUse); - Tracker.clobberRegister(Reg, *TRI); + Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr); } forwardUses(MI); @@ -713,7 +777,9 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { MaybeDeadCopies.begin(); DI != MaybeDeadCopies.end();) { MachineInstr *MaybeDead = *DI; - MCRegister Reg = MaybeDead->getOperand(0).getReg().asMCReg(); + Optional<DestSourcePair> CopyOperands = + isCopyInstr(*MaybeDead, *TII, UseCopyInstr); + MCRegister Reg = CopyOperands->Destination->getReg().asMCReg(); assert(!MRI->isReserved(Reg)); if (!RegMask->clobbersPhysReg(Reg)) { @@ -726,7 +792,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { // Make sure we invalidate any entries in the copy maps before erasing // the instruction. - Tracker.clobberRegister(Reg, *TRI); + Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr); // erase() will return the next valid iterator pointing to the next // element after the erased one. @@ -739,7 +805,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { // Any previous copy definition or reading the Defs is no longer available. for (MCRegister Reg : Defs) - Tracker.clobberRegister(Reg, *TRI); + Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr); } // If MBB doesn't have successors, delete the copies whose defs are not used. @@ -749,12 +815,16 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { for (MachineInstr *MaybeDead : MaybeDeadCopies) { LLVM_DEBUG(dbgs() << "MCP: Removing copy due to no live-out succ: "; MaybeDead->dump()); - assert(!MRI->isReserved(MaybeDead->getOperand(0).getReg())); + + Optional<DestSourcePair> CopyOperands = + isCopyInstr(*MaybeDead, *TII, UseCopyInstr); + assert(CopyOperands); + + Register SrcReg = CopyOperands->Source->getReg(); + Register DestReg = CopyOperands->Destination->getReg(); + assert(!MRI->isReserved(DestReg)); // Update matching debug values, if any. - assert(MaybeDead->isCopy()); - Register SrcReg = MaybeDead->getOperand(1).getReg(); - Register DestReg = MaybeDead->getOperand(0).getReg(); SmallVector<MachineInstr *> MaybeDeadDbgUsers( CopyDbgUsers[MaybeDead].begin(), CopyDbgUsers[MaybeDead].end()); MRI->updateDbgUsersToReg(DestReg.asMCReg(), SrcReg.asMCReg(), @@ -772,10 +842,14 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { } static bool isBackwardPropagatableCopy(MachineInstr &MI, - const MachineRegisterInfo &MRI) { - assert(MI.isCopy() && "MI is expected to be a COPY"); - Register Def = MI.getOperand(0).getReg(); - Register Src = MI.getOperand(1).getReg(); + const MachineRegisterInfo &MRI, + const TargetInstrInfo &TII, + bool UseCopyInstr) { + Optional<DestSourcePair> CopyOperands = isCopyInstr(MI, TII, UseCopyInstr); + assert(CopyOperands && "MI is expected to be a COPY"); + + Register Def = CopyOperands->Destination->getReg(); + Register Src = CopyOperands->Source->getReg(); if (!Def || !Src) return false; @@ -783,7 +857,7 @@ static bool isBackwardPropagatableCopy(MachineInstr &MI, if (MRI.isReserved(Def) || MRI.isReserved(Src)) return false; - return MI.getOperand(1).isRenamable() && MI.getOperand(1).isKill(); + return CopyOperands->Source->isRenamable() && CopyOperands->Source->isKill(); } void MachineCopyPropagation::propagateDefs(MachineInstr &MI) { @@ -808,13 +882,15 @@ void MachineCopyPropagation::propagateDefs(MachineInstr &MI) { if (!MODef.isRenamable()) continue; - MachineInstr *Copy = - Tracker.findAvailBackwardCopy(MI, MODef.getReg().asMCReg(), *TRI); + MachineInstr *Copy = Tracker.findAvailBackwardCopy( + MI, MODef.getReg().asMCReg(), *TRI, *TII, UseCopyInstr); if (!Copy) continue; - Register Def = Copy->getOperand(0).getReg(); - Register Src = Copy->getOperand(1).getReg(); + Optional<DestSourcePair> CopyOperands = + isCopyInstr(*Copy, *TII, UseCopyInstr); + Register Def = CopyOperands->Destination->getReg(); + Register Src = CopyOperands->Source->getReg(); if (MODef.getReg() != Src) continue; @@ -833,7 +909,7 @@ void MachineCopyPropagation::propagateDefs(MachineInstr &MI) { << MI << " from " << *Copy); MODef.setReg(Def); - MODef.setIsRenamable(Copy->getOperand(0).isRenamable()); + MODef.setIsRenamable(CopyOperands->Destination->isRenamable()); LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n"); MaybeDeadCopies.insert(Copy); @@ -849,20 +925,23 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock( for (MachineInstr &MI : llvm::make_early_inc_range(llvm::reverse(MBB))) { // Ignore non-trivial COPYs. - if (MI.isCopy() && MI.getNumOperands() == 2 && - !TRI->regsOverlap(MI.getOperand(0).getReg(), - MI.getOperand(1).getReg())) { - - MCRegister Def = MI.getOperand(0).getReg().asMCReg(); - MCRegister Src = MI.getOperand(1).getReg().asMCReg(); - - // Unlike forward cp, we don't invoke propagateDefs here, - // just let forward cp do COPY-to-COPY propagation. - if (isBackwardPropagatableCopy(MI, *MRI)) { - Tracker.invalidateRegister(Src, *TRI); - Tracker.invalidateRegister(Def, *TRI); - Tracker.trackCopy(&MI, *TRI); - continue; + Optional<DestSourcePair> CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr); + if (CopyOperands && MI.getNumOperands() == 2) { + Register DefReg = CopyOperands->Destination->getReg(); + Register SrcReg = CopyOperands->Source->getReg(); + + if (!TRI->regsOverlap(DefReg, SrcReg)) { + MCRegister Def = DefReg.asMCReg(); + MCRegister Src = SrcReg.asMCReg(); + + // Unlike forward cp, we don't invoke propagateDefs here, + // just let forward cp do COPY-to-COPY propagation. + if (isBackwardPropagatableCopy(MI, *MRI, *TII, UseCopyInstr)) { + Tracker.invalidateRegister(Src, *TRI, *TII, UseCopyInstr); + Tracker.invalidateRegister(Def, *TRI, *TII, UseCopyInstr); + Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr); + continue; + } } } @@ -872,7 +951,7 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock( MCRegister Reg = MO.getReg().asMCReg(); if (!Reg) continue; - Tracker.invalidateRegister(Reg, *TRI); + Tracker.invalidateRegister(Reg, *TRI, *TII, UseCopyInstr); } propagateDefs(MI); @@ -884,7 +963,8 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock( continue; if (MO.isDef()) - Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI); + Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII, + UseCopyInstr); if (MO.readsReg()) { if (MO.isDebug()) { @@ -898,7 +978,8 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock( } } } else { - Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI); + Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII, + UseCopyInstr); } } } @@ -906,8 +987,10 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock( for (auto *Copy : MaybeDeadCopies) { - Register Src = Copy->getOperand(1).getReg(); - Register Def = Copy->getOperand(0).getReg(); + Optional<DestSourcePair> CopyOperands = + isCopyInstr(*Copy, *TII, UseCopyInstr); + Register Src = CopyOperands->Source->getReg(); + Register Def = CopyOperands->Destination->getReg(); SmallVector<MachineInstr *> MaybeDeadDbgUsers(CopyDbgUsers[Copy].begin(), CopyDbgUsers[Copy].end()); @@ -938,3 +1021,8 @@ bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) { return Changed; } + +MachineFunctionPass * +llvm::createMachineCopyPropagationPass(bool UseCopyInstr = false) { + return new MachineCopyPropagation(UseCopyInstr); +} |