From 45b3ddc5a4919b72e3a15e55eea86d470728a43b Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Fri, 21 Sep 2018 00:51:04 +0000 Subject: [PATCH] [MachineCopyPropagation] Refactor copy tracking into a class. NFC This is a bit easier to follow than handling the copy and src maps directly in the pass, and will make upcoming changes to how this is done easier to follow. llvm-svn: 342703 --- llvm/lib/CodeGen/MachineCopyPropagation.cpp | 232 ++++++++++++++++------------ 1 file changed, 133 insertions(+), 99 deletions(-) diff --git a/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/llvm/lib/CodeGen/MachineCopyPropagation.cpp index 9f0a3ad..0e06ddf06 100644 --- a/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -74,9 +74,115 @@ DEBUG_COUNTER(FwdCounter, "machine-cp-fwd", namespace { -using RegList = SmallVector; -using SourceMap = DenseMap; -using Reg2MIMap = DenseMap; +class CopyTracker { + using RegList = SmallVector; + using SourceMap = DenseMap; + using Reg2MIMap = DenseMap; + + /// Def -> available copies map. + Reg2MIMap AvailCopyMap; + + /// Def -> copies map. + Reg2MIMap CopyMap; + + /// Src -> Def map + SourceMap SrcMap; + +public: + /// Mark all of the given registers and their subregisters as unavailable for + /// copying. + void markRegsUnavailable(const RegList &Regs, const TargetRegisterInfo &TRI) { + for (unsigned Reg : Regs) { + // Source of copy is no longer available for propagation. + for (MCSubRegIterator SR(Reg, &TRI, true); SR.isValid(); ++SR) + AvailCopyMap.erase(*SR); + } + } + + /// Remove any entry in the tracker's copy maps that is marked clobbered in \p + /// RegMask. The map will typically have a lot fewer entries than the regmask + /// clobbers, so this is more efficient than iterating the clobbered registers + /// and calling ClobberRegister() on them. + void removeClobberedRegs(const MachineOperand &RegMask, + const TargetRegisterInfo &TRI) { + auto RemoveFromMap = [&RegMask](Reg2MIMap &Map) { + for (Reg2MIMap::iterator I = Map.begin(), E = Map.end(), Next; I != E; + I = Next) { + Next = std::next(I); + if (RegMask.clobbersPhysReg(I->first)) + Map.erase(I); + } + }; + RemoveFromMap(AvailCopyMap); + RemoveFromMap(CopyMap); + + for (SourceMap::iterator I = SrcMap.begin(), E = SrcMap.end(), Next; I != E; + I = Next) { + Next = std::next(I); + if (RegMask.clobbersPhysReg(I->first)) { + markRegsUnavailable(I->second, TRI); + SrcMap.erase(I); + } + } + } + + /// Clobber a single register, removing it from the tracker's copy maps. + void clobberRegister(unsigned Reg, const TargetRegisterInfo &TRI) { + for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) { + CopyMap.erase(*AI); + AvailCopyMap.erase(*AI); + + SourceMap::iterator SI = SrcMap.find(*AI); + if (SI != SrcMap.end()) { + markRegsUnavailable(SI->second, TRI); + SrcMap.erase(SI); + } + } + } + + /// Add this copy's registers into the tracker's copy maps. + void trackCopy(MachineInstr *Copy, const TargetRegisterInfo &TRI) { + assert(Copy->isCopy() && "Tracking non-copy?"); + + unsigned Def = Copy->getOperand(0).getReg(); + unsigned Src = Copy->getOperand(1).getReg(); + + // Remember Def is defined by the copy. + for (MCSubRegIterator SR(Def, &TRI, /*IncludeSelf=*/true); SR.isValid(); + ++SR) { + CopyMap[*SR] = Copy; + AvailCopyMap[*SR] = Copy; + } + + // Remember source that's copied to Def. Once it's clobbered, then + // it's no longer available for copy propagation. + RegList &DestList = SrcMap[Src]; + if (!is_contained(DestList, Def)) + DestList.push_back(Def); + } + + bool hasAvailableCopies() { return !AvailCopyMap.empty(); } + + MachineInstr *findAvailCopy(unsigned Reg) { + auto CI = AvailCopyMap.find(Reg); + if (CI != AvailCopyMap.end()) + return CI->second; + return nullptr; + } + + MachineInstr *findCopy(unsigned Reg) { + auto CI = CopyMap.find(Reg); + if (CI != CopyMap.end()) + return CI->second; + return nullptr; + } + + void clear() { + AvailCopyMap.clear(); + CopyMap.clear(); + SrcMap.clear(); + } +}; class MachineCopyPropagation : public MachineFunctionPass { const TargetRegisterInfo *TRI; @@ -115,14 +221,7 @@ private: /// Candidates for deletion. SmallSetVector MaybeDeadCopies; - /// Def -> available copies map. - Reg2MIMap AvailCopyMap; - - /// Def -> copies map. - Reg2MIMap CopyMap; - - /// Src -> Def map - SourceMap SrcMap; + CopyTracker Tracker; bool Changed; }; @@ -136,54 +235,13 @@ char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID; INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE, "Machine Copy Propagation Pass", false, false) -/// Remove any entry in \p Map where the register is a subregister or equal to -/// a register contained in \p Regs. -static void removeRegsFromMap(Reg2MIMap &Map, const RegList &Regs, - const TargetRegisterInfo &TRI) { - for (unsigned Reg : Regs) { - // Source of copy is no longer available for propagation. - for (MCSubRegIterator SR(Reg, &TRI, true); SR.isValid(); ++SR) - Map.erase(*SR); - } -} - -/// Remove any entry in \p Map that is marked clobbered in \p RegMask. -/// The map will typically have a lot fewer entries than the regmask clobbers, -/// so this is more efficient than iterating the clobbered registers and calling -/// ClobberRegister() on them. -static void removeClobberedRegsFromMap(Reg2MIMap &Map, - const MachineOperand &RegMask) { - for (Reg2MIMap::iterator I = Map.begin(), E = Map.end(), Next; I != E; - I = Next) { - Next = std::next(I); - unsigned Reg = I->first; - if (RegMask.clobbersPhysReg(Reg)) - Map.erase(I); - } -} - -void MachineCopyPropagation::ClobberRegister(unsigned Reg) { - for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { - CopyMap.erase(*AI); - AvailCopyMap.erase(*AI); - - SourceMap::iterator SI = SrcMap.find(*AI); - if (SI != SrcMap.end()) { - removeRegsFromMap(AvailCopyMap, SI->second, *TRI); - SrcMap.erase(SI); - } - } -} - void MachineCopyPropagation::ReadRegister(unsigned Reg) { // If 'Reg' is defined by a copy, the copy is no longer a candidate // for elimination. for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) { - Reg2MIMap::iterator CI = CopyMap.find(*AI); - if (CI != CopyMap.end()) { - LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; - CI->second->dump()); - MaybeDeadCopies.remove(CI->second); + if (MachineInstr *Copy = Tracker.findCopy(*AI)) { + LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; Copy->dump()); + MaybeDeadCopies.remove(Copy); } } } @@ -219,15 +277,14 @@ bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src, return false; // Search for an existing copy. - Reg2MIMap::iterator CI = AvailCopyMap.find(Def); - if (CI == AvailCopyMap.end()) + MachineInstr *PrevCopy = Tracker.findAvailCopy(Def); + if (!PrevCopy) return false; // Check that the existing copy uses the correct sub registers. - MachineInstr &PrevCopy = *CI->second; - if (PrevCopy.getOperand(0).isDead()) + if (PrevCopy->getOperand(0).isDead()) return false; - if (!isNopCopy(PrevCopy, Src, Def, TRI)) + if (!isNopCopy(*PrevCopy, Src, Def, TRI)) return false; LLVM_DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; Copy.dump()); @@ -238,7 +295,7 @@ bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src, unsigned CopyDef = Copy.getOperand(0).getReg(); assert(CopyDef == Src || CopyDef == Def); for (MachineInstr &MI : - make_range(PrevCopy.getIterator(), Copy.getIterator())) + make_range(PrevCopy->getIterator(), Copy.getIterator())) MI.clearRegisterKills(CopyDef, TRI); Copy.eraseFromParent(); @@ -314,7 +371,7 @@ bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI, /// Look for available copies whose destination register is used by \p MI and /// replace the use in \p MI with the copy's source register. void MachineCopyPropagation::forwardUses(MachineInstr &MI) { - if (AvailCopyMap.empty()) + if (!Tracker.hasAvailableCopies()) return; // Look for non-tied explicit vreg uses that have an active COPY @@ -341,13 +398,12 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) { if (!MOUse.isRenamable()) continue; - auto CI = AvailCopyMap.find(MOUse.getReg()); - if (CI == AvailCopyMap.end()) + MachineInstr *Copy = Tracker.findAvailCopy(MOUse.getReg()); + if (!Copy) continue; - MachineInstr &Copy = *CI->second; - unsigned CopyDstReg = Copy.getOperand(0).getReg(); - const MachineOperand &CopySrc = Copy.getOperand(1); + unsigned CopyDstReg = Copy->getOperand(0).getReg(); + const MachineOperand &CopySrc = Copy->getOperand(1); unsigned CopySrcReg = CopySrc.getReg(); // FIXME: Don't handle partial uses of wider COPYs yet. @@ -362,7 +418,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) { if (MRI->isReserved(CopySrcReg) && !MRI->isConstantPhysReg(CopySrcReg)) continue; - if (!isForwardableRegClassCopy(Copy, MI, OpIdx)) + if (!isForwardableRegClassCopy(*Copy, MI, OpIdx)) continue; if (hasImplicitOverlap(MI, MOUse)) @@ -376,7 +432,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) { LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MOUse.getReg(), TRI) << "\n with " << printReg(CopySrcReg, TRI) - << "\n in " << MI << " from " << Copy); + << "\n in " << MI << " from " << *Copy); MOUse.setReg(CopySrcReg); if (!CopySrc.isRenamable()) @@ -386,7 +442,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) { // Clear kill markers that may have been invalidated. for (MachineInstr &KMI : - make_range(Copy.getIterator(), std::next(MI.getIterator()))) + make_range(Copy->getIterator(), std::next(MI.getIterator()))) KMI.clearRegisterKills(CopySrcReg, TRI); ++NumCopyForwards; @@ -459,28 +515,17 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { // %xmm2 = copy %xmm0 // ... // %xmm2 = copy %xmm9 - ClobberRegister(Def); + Tracker.clobberRegister(Def, *TRI); for (const MachineOperand &MO : MI->implicit_operands()) { if (!MO.isReg() || !MO.isDef()) continue; unsigned Reg = MO.getReg(); if (!Reg) continue; - ClobberRegister(Reg); - } - - // Remember Def is defined by the copy. - for (MCSubRegIterator SR(Def, TRI, /*IncludeSelf=*/true); SR.isValid(); - ++SR) { - CopyMap[*SR] = MI; - AvailCopyMap[*SR] = MI; + Tracker.clobberRegister(Reg, *TRI); } - // Remember source that's copied to Def. Once it's clobbered, then - // it's no longer available for copy propagation. - RegList &DestList = SrcMap[Src]; - if (!is_contained(DestList, Def)) - DestList.push_back(Def); + Tracker.trackCopy(MI, *TRI); continue; } @@ -494,7 +539,7 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { // later. if (MO.isTied()) ReadRegister(Reg); - ClobberRegister(Reg); + Tracker.clobberRegister(Reg, *TRI); } forwardUses(*MI); @@ -549,21 +594,12 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { ++NumDeletes; } - removeClobberedRegsFromMap(AvailCopyMap, *RegMask); - removeClobberedRegsFromMap(CopyMap, *RegMask); - for (SourceMap::iterator I = SrcMap.begin(), E = SrcMap.end(), Next; - I != E; I = Next) { - Next = std::next(I); - if (RegMask->clobbersPhysReg(I->first)) { - removeRegsFromMap(AvailCopyMap, I->second, *TRI); - SrcMap.erase(I); - } - } + Tracker.removeClobberedRegs(*RegMask, *TRI); } // Any previous copy definition or reading the Defs is no longer available. for (unsigned Reg : Defs) - ClobberRegister(Reg); + Tracker.clobberRegister(Reg, *TRI); } // If MBB doesn't have successors, delete the copies whose defs are not used. @@ -581,9 +617,7 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) { } MaybeDeadCopies.clear(); - AvailCopyMap.clear(); - CopyMap.clear(); - SrcMap.clear(); + Tracker.clear(); } bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) { -- 2.7.4