diff --git a/llvm/include/llvm/CodeGen/DeadMachineInstructionElim.h b/llvm/include/llvm/CodeGen/DeadMachineInstructionElim.h index 56cfa1e087181..22243515e93d9 100644 --- a/llvm/include/llvm/CodeGen/DeadMachineInstructionElim.h +++ b/llvm/include/llvm/CodeGen/DeadMachineInstructionElim.h @@ -9,10 +9,30 @@ #ifndef LLVM_CODEGEN_DEADMACHINEINSTRUCTIONELIM_H #define LLVM_CODEGEN_DEADMACHINEINSTRUCTIONELIM_H +#include "llvm/CodeGen/LiveRegUnits.h" #include "llvm/CodeGen/MachinePassManager.h" namespace llvm { +class DeadMachineInstructionInfo { +private: + const MachineRegisterInfo *MRI = nullptr; + +public: + /// Check whether \p MI is dead. If \p LivePhysRegs is provided, it is assumed + /// to be at the position of MI and will be used to check the Liveness of + /// physical register defs. If \p LivePhysRegs is not provided, this will + /// pessimistically assume any PhysReg def is live. + bool isDead(const MachineInstr *MI, + LiveRegUnits *LivePhysRegs = nullptr) const; + + /// Do a function walk over \p MF and delete any dead MachineInstrs. Uses + /// LivePhysRegs to track liveness of PhysRegs. + bool eliminateDeadMI(MachineFunction &MF); + + DeadMachineInstructionInfo(const MachineRegisterInfo *MRI) : MRI(MRI) {} +}; + class DeadMachineInstructionElimPass : public PassInfoMixin { public: diff --git a/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp b/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp index 2f17c04487de7..974d0706d75ff 100644 --- a/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp +++ b/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp @@ -13,7 +13,6 @@ #include "llvm/CodeGen/DeadMachineInstructionElim.h" #include "llvm/ADT/PostOrderIterator.h" #include "llvm/ADT/Statistic.h" -#include "llvm/CodeGen/LiveRegUnits.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/TargetSubtargetInfo.h" @@ -32,14 +31,9 @@ namespace { class DeadMachineInstructionElimImpl { const MachineRegisterInfo *MRI = nullptr; const TargetInstrInfo *TII = nullptr; - LiveRegUnits LivePhysRegs; public: bool runImpl(MachineFunction &MF); - -private: - bool isDead(const MachineInstr *MI) const; - bool eliminateDeadMI(MachineFunction &MF); }; class DeadMachineInstructionElim : public MachineFunctionPass { @@ -79,7 +73,21 @@ char &llvm::DeadMachineInstructionElimID = DeadMachineInstructionElim::ID; INITIALIZE_PASS(DeadMachineInstructionElim, DEBUG_TYPE, "Remove dead machine instructions", false, false) -bool DeadMachineInstructionElimImpl::isDead(const MachineInstr *MI) const { +bool DeadMachineInstructionElimImpl::runImpl(MachineFunction &MF) { + MRI = &MF.getRegInfo(); + + const TargetSubtargetInfo &ST = MF.getSubtarget(); + TII = ST.getInstrInfo(); + DeadMachineInstructionInfo DMII(MRI); + + bool AnyChanges = DMII.eliminateDeadMI(MF); + while (AnyChanges && DMII.eliminateDeadMI(MF)) + ; + return AnyChanges; +} + +bool DeadMachineInstructionInfo::isDead(const MachineInstr *MI, + LiveRegUnits *LivePhysRegs) const { // Instructions without side-effects are dead iff they only define dead regs. // This function is hot and this loop returns early in the common case, // so only perform additional checks before this if absolutely necessary. @@ -87,7 +95,8 @@ bool DeadMachineInstructionElimImpl::isDead(const MachineInstr *MI) const { Register Reg = MO.getReg(); if (Reg.isPhysical()) { // Don't delete live physreg defs, or any reserved register defs. - if (!LivePhysRegs.available(Reg) || MRI->isReserved(Reg)) + if (!LivePhysRegs || !LivePhysRegs->available(Reg) || + MRI->isReserved(Reg)) return false; } else { if (MO.isDead()) { @@ -120,22 +129,12 @@ bool DeadMachineInstructionElimImpl::isDead(const MachineInstr *MI) const { return MI->wouldBeTriviallyDead(); } -bool DeadMachineInstructionElimImpl::runImpl(MachineFunction &MF) { - MRI = &MF.getRegInfo(); - - const TargetSubtargetInfo &ST = MF.getSubtarget(); - TII = ST.getInstrInfo(); - LivePhysRegs.init(*ST.getRegisterInfo()); - - bool AnyChanges = eliminateDeadMI(MF); - while (AnyChanges && eliminateDeadMI(MF)) - ; - return AnyChanges; -} - -bool DeadMachineInstructionElimImpl::eliminateDeadMI(MachineFunction &MF) { +bool DeadMachineInstructionInfo::eliminateDeadMI(MachineFunction &MF) { bool AnyChanges = false; + const TargetSubtargetInfo &ST = MF.getSubtarget(); + LiveRegUnits LivePhysRegs; + LivePhysRegs.init(*ST.getRegisterInfo()); // Loop over all instructions in all blocks, from bottom to top, so that it's // more likely that chains of dependent but ultimately dead instructions will // be cleaned up. @@ -146,7 +145,7 @@ bool DeadMachineInstructionElimImpl::eliminateDeadMI(MachineFunction &MF) { // liveness as we go. for (MachineInstr &MI : make_early_inc_range(reverse(*MBB))) { // If the instruction is dead, delete it! - if (isDead(&MI)) { + if (isDead(&MI, &LivePhysRegs)) { LLVM_DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << MI); // It is possible that some DBG_VALUE instructions refer to this // instruction. They will be deleted in the live debug variable @@ -156,11 +155,8 @@ bool DeadMachineInstructionElimImpl::eliminateDeadMI(MachineFunction &MF) { ++NumDeletes; continue; } - LivePhysRegs.stepBackward(MI); } } - - LivePhysRegs.clear(); return AnyChanges; }