diff options
| author | Stanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com> | 2019-04-05 20:11:32 +0000 |
|---|---|---|
| committer | Stanislav Mekhanoshin <Stanislav.Mekhanoshin@amd.com> | 2019-04-05 20:11:32 +0000 |
| commit | c8f78f8dd344ceaac9c2c6f195365eb7d31f7ff0 (patch) | |
| tree | 6557db4dba68d7132bdd3303c3c51039c8e6b4ed /llvm/lib | |
| parent | d2225d067a8c13c310059cacaf2aa264cf6471a7 (diff) | |
| download | bcm5719-llvm-c8f78f8dd344ceaac9c2c6f195365eb7d31f7ff0.tar.gz bcm5719-llvm-c8f78f8dd344ceaac9c2c6f195365eb7d31f7ff0.zip | |
[AMDGPU] Add MachineDCE pass after RenameIndependentSubregs
Detect dead lanes can create some dead defs. Then RenameIndependentSubregs
will break a REG_SEQUENCE which may use these dead defs. At this point
a dead instruction can be removed but we do not run a DCE anymore.
MachineDCE was only running before live variable analysis. The patch
adds a mean to preserve LiveIntervals and SlotIndexes in case it works
past this.
Differential Revision: https://reviews.llvm.org/D59626
llvm-svn: 357805
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/CodeGen/DeadMachineInstructionElim.cpp | 30 | ||||
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp | 9 |
2 files changed, 37 insertions, 2 deletions
diff --git a/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp b/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp index 049ce706330..f1de7b3cc6a 100644 --- a/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp +++ b/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp @@ -10,7 +10,9 @@ // //===----------------------------------------------------------------------===// +#include "llvm/ADT/DenseSet.h" #include "llvm/ADT/Statistic.h" +#include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/Passes.h" @@ -32,6 +34,7 @@ namespace { const TargetRegisterInfo *TRI; const MachineRegisterInfo *MRI; const TargetInstrInfo *TII; + LiveIntervals *LIS; BitVector LivePhysRegs; public: @@ -41,7 +44,7 @@ namespace { } void getAnalysisUsage(AnalysisUsage &AU) const override { - AU.setPreservesCFG(); + AU.setPreservesAll(); MachineFunctionPass::getAnalysisUsage(AU); } @@ -78,9 +81,15 @@ bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const { unsigned Reg = MO.getReg(); if (TargetRegisterInfo::isPhysicalRegister(Reg)) { // Don't delete live physreg defs, or any reserved register defs. - if (LivePhysRegs.test(Reg) || MRI->isReserved(Reg)) + // Do not remove physreg defs if we have LIS as we may be unable + // to accurately recompute its liveness. + if (LivePhysRegs.test(Reg) || MRI->isReserved(Reg) || LIS) return false; } else { + // An instruction can also use its def in case if it is a tied operand. + // TODO: Technically we can also remove it if def dominates the use. + // This can happen when two instructions define different subregs + // of the same register. for (const MachineInstr &Use : MRI->use_nodbg_instructions(Reg)) { if (&Use != MI) // This def has a non-debug use. Don't delete the instruction! @@ -102,6 +111,8 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { MRI = &MF.getRegInfo(); TRI = MF.getSubtarget().getRegisterInfo(); TII = MF.getSubtarget().getInstrInfo(); + LIS = getAnalysisIfAvailable<LiveIntervals>(); + DenseSet<unsigned> RecalcRegs; // 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 @@ -127,6 +138,14 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { // If the instruction is dead, delete it! if (isDead(MI)) { LLVM_DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << *MI); + if (LIS) { + for (const MachineOperand &MO : MI->operands()) { + if (MO.isReg() && TRI->isVirtualRegister(MO.getReg())) + RecalcRegs.insert(MO.getReg()); + } + LIS->RemoveMachineInstrFromMaps(*MI); + } + // It is possible that some DBG_VALUE instructions refer to this // instruction. They get marked as undef and will be deleted // in the live debug variable analysis. @@ -170,5 +189,12 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { } LivePhysRegs.clear(); + + for (auto Reg : RecalcRegs) { + LIS->removeInterval(Reg); + if (!MRI->reg_empty(Reg)) + LIS->createAndComputeVirtRegInterval(Reg); + } + return AnyChanges; } diff --git a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp index 84fa5918447..3bfeea197bd 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp @@ -163,6 +163,12 @@ static cl::opt<bool> EnableSIModeRegisterPass( cl::init(true), cl::Hidden); +// Option is used in lit tests to prevent deadcoding of patterns inspected. +static cl::opt<bool> +EnableDCEInRA("amdgpu-dce-in-ra", + cl::init(true), cl::Hidden, + cl::desc("Enable machine DCE inside regalloc")); + extern "C" void LLVMInitializeAMDGPUTarget() { // Register the target RegisterTargetMachine<R600TargetMachine> X(getTheAMDGPUTarget()); @@ -901,6 +907,9 @@ void GCNPassConfig::addOptimizedRegAlloc() { // This must be run just after RegisterCoalescing. insertPass(&RegisterCoalescerID, &SIPreAllocateWWMRegsID, false); + if (EnableDCEInRA) + insertPass(&RenameIndependentSubregsID, &DeadMachineInstructionElimID); + TargetPassConfig::addOptimizedRegAlloc(); } |

