diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:31:46 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2021-06-13 19:37:19 +0000 |
commit | e8d8bef961a50d4dc22501cde4fb9fb0be1b2532 (patch) | |
tree | 94f04805f47bb7c59ae29690d8952b6074fff602 /contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp | |
parent | bb130ff39747b94592cb26d71b7cb097b9a4ea6b (diff) | |
parent | b60736ec1405bb0a8dd40989f67ef4c93da068ab (diff) | |
download | src-e8d8bef961a50d4dc22501cde4fb9fb0be1b2532.tar.gz src-e8d8bef961a50d4dc22501cde4fb9fb0be1b2532.zip |
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp')
-rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp | 126 |
1 files changed, 73 insertions, 53 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp b/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp index 4c4839ca6522..d8659c1c7853 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/MachineCopyPropagation.cpp @@ -88,18 +88,18 @@ namespace { class CopyTracker { struct CopyInfo { MachineInstr *MI; - SmallVector<unsigned, 4> DefRegs; + SmallVector<MCRegister, 4> DefRegs; bool Avail; }; - DenseMap<unsigned, CopyInfo> Copies; + DenseMap<MCRegister, CopyInfo> Copies; public: /// Mark all of the given registers and their subregisters as unavailable for /// copying. - void markRegsUnavailable(ArrayRef<unsigned> Regs, + void markRegsUnavailable(ArrayRef<MCRegister> Regs, const TargetRegisterInfo &TRI) { - for (unsigned Reg : Regs) { + for (MCRegister Reg : Regs) { // Source of copy is no longer available for propagation. for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) { auto CI = Copies.find(*RUI); @@ -110,30 +110,30 @@ public: } /// Remove register from copy maps. - void invalidateRegister(unsigned Reg, const TargetRegisterInfo &TRI) { + void invalidateRegister(MCRegister Reg, const TargetRegisterInfo &TRI) { // 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. - SmallSet<unsigned, 8> RegsToInvalidate; + SmallSet<MCRegister, 8> RegsToInvalidate; RegsToInvalidate.insert(Reg); for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) { auto I = Copies.find(*RUI); if (I != Copies.end()) { if (MachineInstr *MI = I->second.MI) { - RegsToInvalidate.insert(MI->getOperand(0).getReg()); - RegsToInvalidate.insert(MI->getOperand(1).getReg()); + RegsToInvalidate.insert(MI->getOperand(0).getReg().asMCReg()); + RegsToInvalidate.insert(MI->getOperand(1).getReg().asMCReg()); } RegsToInvalidate.insert(I->second.DefRegs.begin(), I->second.DefRegs.end()); } } - for (unsigned InvalidReg : RegsToInvalidate) + for (MCRegister InvalidReg : RegsToInvalidate) for (MCRegUnitIterator RUI(InvalidReg, &TRI); RUI.isValid(); ++RUI) Copies.erase(*RUI); } /// Clobber a single register, removing it from the tracker's copy maps. - void clobberRegister(unsigned Reg, const TargetRegisterInfo &TRI) { + void clobberRegister(MCRegister Reg, const TargetRegisterInfo &TRI) { for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) { auto I = Copies.find(*RUI); if (I != Copies.end()) { @@ -143,7 +143,7 @@ public: // 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()}, TRI); + markRegsUnavailable({MI->getOperand(0).getReg().asMCReg()}, TRI); // Now we can erase the copy. Copies.erase(I); } @@ -154,8 +154,8 @@ public: void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI) { assert(MI->isCopy() && "Tracking non-copy?"); - Register Def = MI->getOperand(0).getReg(); - Register Src = MI->getOperand(1).getReg(); + MCRegister Def = MI->getOperand(0).getReg().asMCReg(); + MCRegister Src = MI->getOperand(1).getReg().asMCReg(); // Remember Def is defined by the copy. for (MCRegUnitIterator RUI(Def, &TRI); RUI.isValid(); ++RUI) @@ -175,8 +175,9 @@ public: return !Copies.empty(); } - MachineInstr *findCopyForUnit(unsigned RegUnit, const TargetRegisterInfo &TRI, - bool MustBeAvailable = false) { + MachineInstr *findCopyForUnit(MCRegister RegUnit, + const TargetRegisterInfo &TRI, + bool MustBeAvailable = false) { auto CI = Copies.find(RegUnit); if (CI == Copies.end()) return nullptr; @@ -185,8 +186,8 @@ public: return CI->second.MI; } - MachineInstr *findCopyDefViaUnit(unsigned RegUnit, - const TargetRegisterInfo &TRI) { + MachineInstr *findCopyDefViaUnit(MCRegister RegUnit, + const TargetRegisterInfo &TRI) { auto CI = Copies.find(RegUnit); if (CI == Copies.end()) return nullptr; @@ -196,7 +197,7 @@ public: return findCopyForUnit(*RUI, TRI, true); } - MachineInstr *findAvailBackwardCopy(MachineInstr &I, unsigned Reg, + MachineInstr *findAvailBackwardCopy(MachineInstr &I, MCRegister Reg, const TargetRegisterInfo &TRI) { MCRegUnitIterator RUI(Reg, &TRI); MachineInstr *AvailCopy = findCopyDefViaUnit(*RUI, TRI); @@ -217,7 +218,7 @@ public: return AvailCopy; } - MachineInstr *findAvailCopy(MachineInstr &DestCopy, unsigned Reg, + MachineInstr *findAvailCopy(MachineInstr &DestCopy, MCRegister Reg, const TargetRegisterInfo &TRI) { // We check the first RegUnit here, since we'll only be interested in the // copy if it copies the entire register anyway. @@ -274,12 +275,10 @@ public: private: typedef enum { DebugUse = false, RegularUse = true } DebugType; - void ClobberRegister(unsigned Reg); - void ReadRegister(unsigned Reg, MachineInstr &Reader, - DebugType DT); + void ReadRegister(MCRegister Reg, MachineInstr &Reader, DebugType DT); void ForwardCopyPropagateBlock(MachineBasicBlock &MBB); void BackwardCopyPropagateBlock(MachineBasicBlock &MBB); - bool eraseIfRedundant(MachineInstr &Copy, unsigned Src, unsigned Def); + bool eraseIfRedundant(MachineInstr &Copy, MCRegister Src, MCRegister Def); void forwardUses(MachineInstr &MI); void propagateDefs(MachineInstr &MI); bool isForwardableRegClassCopy(const MachineInstr &Copy, @@ -288,6 +287,8 @@ private: const MachineInstr &UseI, unsigned UseIdx); bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use); + bool hasOverlappingMultipleDef(const MachineInstr &MI, + const MachineOperand &MODef, Register Def); /// Candidates for deletion. SmallSetVector<MachineInstr *, 8> MaybeDeadCopies; @@ -309,7 +310,7 @@ char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID; INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE, "Machine Copy Propagation Pass", false, false) -void MachineCopyPropagation::ReadRegister(unsigned Reg, MachineInstr &Reader, +void MachineCopyPropagation::ReadRegister(MCRegister Reg, MachineInstr &Reader, DebugType DT) { // If 'Reg' is defined by a copy, the copy is no longer a candidate // for elimination. If a copy is "read" by a debug user, record the user @@ -332,10 +333,10 @@ void MachineCopyPropagation::ReadRegister(unsigned Reg, MachineInstr &Reader, /// PreviousCopy. e.g. /// isNopCopy("ecx = COPY eax", AX, CX) == true /// isNopCopy("ecx = COPY eax", AH, CL) == false -static bool isNopCopy(const MachineInstr &PreviousCopy, unsigned Src, - unsigned Def, const TargetRegisterInfo *TRI) { - Register PreviousSrc = PreviousCopy.getOperand(1).getReg(); - Register PreviousDef = PreviousCopy.getOperand(0).getReg(); +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(); if (Src == PreviousSrc && Def == PreviousDef) return true; if (!TRI->isSubRegister(PreviousSrc, Src)) @@ -347,8 +348,8 @@ static bool isNopCopy(const MachineInstr &PreviousCopy, unsigned Src, /// Remove instruction \p Copy if there exists a previous copy that copies the /// register \p Src to the register \p Def; This may happen indirectly by /// copying the super registers. -bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src, - unsigned Def) { +bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, + MCRegister Src, MCRegister Def) { // Avoid eliminating a copy from/to a reserved registers as we cannot predict // the value (Example: The sparc zero register is writable but stays zero). if (MRI->isReserved(Src) || MRI->isReserved(Def)) @@ -459,6 +460,21 @@ bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI, return false; } +/// For an MI that has multiple definitions, check whether \p MI has +/// a definition that overlaps with another of its definitions. +/// For example, on ARM: umull r9, r9, lr, r0 +/// The umull instruction is unpredictable unless RdHi and RdLo are different. +bool MachineCopyPropagation::hasOverlappingMultipleDef( + const MachineInstr &MI, const MachineOperand &MODef, Register Def) { + for (const MachineOperand &MIDef : MI.defs()) { + if ((&MIDef != &MODef) && MIDef.isReg() && + TRI->regsOverlap(Def, MIDef.getReg())) + return true; + } + + return false; +} + /// 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) { @@ -489,7 +505,8 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) { if (!MOUse.isRenamable()) continue; - MachineInstr *Copy = Tracker.findAvailCopy(MI, MOUse.getReg(), *TRI); + MachineInstr *Copy = + Tracker.findAvailCopy(MI, MOUse.getReg().asMCReg(), *TRI); if (!Copy) continue; @@ -561,13 +578,13 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { // Analyze copies (which don't overlap themselves). if (MI->isCopy() && !TRI->regsOverlap(MI->getOperand(0).getReg(), MI->getOperand(1).getReg())) { - Register Def = MI->getOperand(0).getReg(); - Register Src = MI->getOperand(1).getReg(); - - assert(!Register::isVirtualRegister(Def) && - !Register::isVirtualRegister(Src) && + 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 @@ -589,7 +606,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { forwardUses(*MI); // Src may have been changed by forwardUses() - Src = MI->getOperand(1).getReg(); + Src = MI->getOperand(1).getReg().asMCReg(); // If Src is defined by a previous copy, the previous copy cannot be // eliminated. @@ -597,7 +614,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { for (const MachineOperand &MO : MI->implicit_operands()) { if (!MO.isReg() || !MO.readsReg()) continue; - Register Reg = MO.getReg(); + MCRegister Reg = MO.getReg().asMCReg(); if (!Reg) continue; ReadRegister(Reg, *MI, RegularUse); @@ -620,7 +637,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { for (const MachineOperand &MO : MI->implicit_operands()) { if (!MO.isReg() || !MO.isDef()) continue; - Register Reg = MO.getReg(); + MCRegister Reg = MO.getReg().asMCReg(); if (!Reg) continue; Tracker.clobberRegister(Reg, *TRI); @@ -634,7 +651,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { // Clobber any earlyclobber regs first. for (const MachineOperand &MO : MI->operands()) if (MO.isReg() && MO.isEarlyClobber()) { - Register Reg = MO.getReg(); + MCRegister Reg = MO.getReg().asMCReg(); // If we have a tied earlyclobber, that means it is also read by this // instruction, so we need to make sure we don't remove it as dead // later. @@ -646,7 +663,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { forwardUses(*MI); // Not a copy. - SmallVector<unsigned, 2> Defs; + SmallVector<Register, 2> Defs; const MachineOperand *RegMask = nullptr; for (const MachineOperand &MO : MI->operands()) { if (MO.isRegMask()) @@ -657,14 +674,14 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { if (!Reg) continue; - assert(!Register::isVirtualRegister(Reg) && + assert(!Reg.isVirtual() && "MachineCopyPropagation should be run after register allocation!"); if (MO.isDef() && !MO.isEarlyClobber()) { - Defs.push_back(Reg); + Defs.push_back(Reg.asMCReg()); continue; } else if (MO.readsReg()) - ReadRegister(Reg, *MI, MO.isDebug() ? DebugUse : RegularUse); + ReadRegister(Reg.asMCReg(), *MI, MO.isDebug() ? DebugUse : RegularUse); } // The instruction has a register mask operand which means that it clobbers @@ -676,7 +693,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { MaybeDeadCopies.begin(); DI != MaybeDeadCopies.end();) { MachineInstr *MaybeDead = *DI; - Register Reg = MaybeDead->getOperand(0).getReg(); + MCRegister Reg = MaybeDead->getOperand(0).getReg().asMCReg(); assert(!MRI->isReserved(Reg)); if (!RegMask->clobbersPhysReg(Reg)) { @@ -701,7 +718,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { } // Any previous copy definition or reading the Defs is no longer available. - for (unsigned Reg : Defs) + for (MCRegister Reg : Defs) Tracker.clobberRegister(Reg, *TRI); } @@ -716,7 +733,7 @@ void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) { // Update matching debug values, if any. assert(MaybeDead->isCopy()); - unsigned SrcReg = MaybeDead->getOperand(1).getReg(); + Register SrcReg = MaybeDead->getOperand(1).getReg(); MRI->updateDbgUsersToReg(SrcReg, CopyDbgUsers[MaybeDead]); MaybeDead->eraseFromParent(); @@ -768,7 +785,7 @@ void MachineCopyPropagation::propagateDefs(MachineInstr &MI) { continue; MachineInstr *Copy = - Tracker.findAvailBackwardCopy(MI, MODef.getReg(), *TRI); + Tracker.findAvailBackwardCopy(MI, MODef.getReg().asMCReg(), *TRI); if (!Copy) continue; @@ -784,6 +801,9 @@ void MachineCopyPropagation::propagateDefs(MachineInstr &MI) { if (hasImplicitOverlap(MI, MODef)) continue; + if (hasOverlappingMultipleDef(MI, MODef, Def)) + continue; + LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MODef.getReg(), TRI) << "\n with " << printReg(Def, TRI) << "\n in " << MI << " from " << *Copy); @@ -813,8 +833,8 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock( !TRI->regsOverlap(MI->getOperand(0).getReg(), MI->getOperand(1).getReg())) { - Register Def = MI->getOperand(0).getReg(); - Register Src = 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. @@ -829,7 +849,7 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock( // Invalidate any earlyclobber regs first. for (const MachineOperand &MO : MI->operands()) if (MO.isReg() && MO.isEarlyClobber()) { - Register Reg = MO.getReg(); + MCRegister Reg = MO.getReg().asMCReg(); if (!Reg) continue; Tracker.invalidateRegister(Reg, *TRI); @@ -844,10 +864,10 @@ void MachineCopyPropagation::BackwardCopyPropagateBlock( continue; if (MO.isDef()) - Tracker.invalidateRegister(MO.getReg(), *TRI); + Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI); if (MO.readsReg()) - Tracker.invalidateRegister(MO.getReg(), *TRI); + Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI); } } |