summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/CodeGen/DeadMachineInstructionElim.cpp30
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUTargetMachine.cpp9
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();
}
OpenPOWER on IntegriCloud