X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FDeadMachineInstructionElim.cpp;h=fdc1d9142140b06a9aab44ff99e89a6effd539bc;hb=bcb8c6d09ee426e0f774e3412912f6ae9e5f78dd;hp=718b6e2a5aac0aae11649f47669a96d8f6ae2443;hpb=723ac3720f6d983e0ed01504964fde1aa63951ff;p=oota-llvm.git diff --git a/lib/CodeGen/DeadMachineInstructionElim.cpp b/lib/CodeGen/DeadMachineInstructionElim.cpp index 718b6e2a5aa..fdc1d914214 100644 --- a/lib/CodeGen/DeadMachineInstructionElim.cpp +++ b/lib/CodeGen/DeadMachineInstructionElim.cpp @@ -11,19 +11,22 @@ // //===----------------------------------------------------------------------===// +#define DEBUG_TYPE "codegen-dce" #include "llvm/CodeGen/Passes.h" #include "llvm/Pass.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineRegisterInfo.h" -#include "llvm/Support/Compiler.h" #include "llvm/Support/Debug.h" +#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/ADT/Statistic.h" using namespace llvm; +STATISTIC(NumDeletes, "Number of dead instructions deleted"); + namespace { - class VISIBILITY_HIDDEN DeadMachineInstructionElim : - public MachineFunctionPass { + class DeadMachineInstructionElim : public MachineFunctionPass { virtual bool runOnMachineFunction(MachineFunction &MF); const TargetRegisterInfo *TRI; @@ -33,36 +36,43 @@ namespace { public: static char ID; // Pass identification, replacement for typeid - DeadMachineInstructionElim() : MachineFunctionPass(&ID) {} + DeadMachineInstructionElim() : MachineFunctionPass(ID) { + initializeDeadMachineInstructionElimPass(*PassRegistry::getPassRegistry()); + } private: - bool isDead(MachineInstr *MI) const; + bool isDead(const MachineInstr *MI) const; }; } char DeadMachineInstructionElim::ID = 0; -static RegisterPass -Y("dead-mi-elimination", - "Remove dead machine instructions"); +INITIALIZE_PASS(DeadMachineInstructionElim, "dead-mi-elimination", + "Remove dead machine instructions", false, false) FunctionPass *llvm::createDeadMachineInstructionElimPass() { return new DeadMachineInstructionElim(); } -bool DeadMachineInstructionElim::isDead(MachineInstr *MI) const { +bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const { + // Technically speaking inline asm without side effects and no defs can still + // be deleted. But there is so much bad inline asm code out there, we should + // let them be. + if (MI->isInlineAsm()) + return false; + // Don't delete instructions with side effects. bool SawStore = false; - if (!MI->isSafeToMove(TII, SawStore)) + if (!MI->isSafeToMove(TII, 0, SawStore) && !MI->isPHI()) return false; // Examine each operand. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (MO.isRegister() && MO.isDef()) { + if (MO.isReg() && MO.isDef()) { unsigned Reg = MO.getReg(); if (TargetRegisterInfo::isPhysicalRegister(Reg) ? - LivePhysRegs[Reg] : !MRI->use_empty(Reg)) { - // This def has a use. Don't delete the instruction! + LivePhysRegs[Reg] : !MRI->use_nodbg_empty(Reg)) { + // This def has a non-debug use. Don't delete the instruction! return false; } } @@ -78,9 +88,8 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { TRI = MF.getTarget().getRegisterInfo(); TII = MF.getTarget().getInstrInfo(); - // Compute a bitvector to represent all non-allocatable physregs. - BitVector NonAllocatableRegs = TRI->getAllocatableSet(MF); - NonAllocatableRegs.flip(); + // Treat reserved registers as always live. + BitVector ReservedRegs = TRI->getReservedRegs(MF); // 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 @@ -89,9 +98,8 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { I != E; ++I) { MachineBasicBlock *MBB = &*I; - // Start out assuming that all non-allocatable registers are live - // out of this block. - LivePhysRegs = NonAllocatableRegs; + // Start out assuming that reserved registers are live out of this block. + LivePhysRegs = ReservedRegs; // Also add any explicit live-out physregs for this block. if (!MBB->empty() && MBB->back().getDesc().isReturn()) @@ -102,6 +110,10 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { LivePhysRegs.set(Reg); } + // FIXME: Add live-ins from sucessors to LivePhysRegs. Normally, physregs + // are not live across blocks, but some targets (x86) can have flags live + // out of a block. + // Now scan the instructions and delete dead ones, tracking physreg // liveness as we go. for (MachineBasicBlock::reverse_iterator MII = MBB->rbegin(), @@ -110,9 +122,32 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { // If the instruction is dead, delete it! if (isDead(MI)) { - DOUT << "DeadMachineInstructionElim: DELETING: " << *MI; + DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << *MI); + // It is possible that some DBG_VALUE instructions refer to this + // instruction. Examine each def operand for such references; + // if found, mark the DBG_VALUE as undef (but don't delete it). + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (!MO.isReg() || !MO.isDef()) + continue; + unsigned Reg = MO.getReg(); + if (!TargetRegisterInfo::isVirtualRegister(Reg)) + continue; + MachineRegisterInfo::use_iterator nextI; + for (MachineRegisterInfo::use_iterator I = MRI->use_begin(Reg), + E = MRI->use_end(); I!=E; I=nextI) { + nextI = llvm::next(I); // I is invalidated by the setReg + MachineOperand& Use = I.getOperand(); + MachineInstr *UseMI = Use.getParent(); + if (UseMI==MI) + continue; + assert(Use.isDebug()); + UseMI->getOperand(0).setReg(0U); + } + } AnyChanges = true; MI->eraseFromParent(); + ++NumDeletes; MIE = MBB->rend(); // MII is now pointing to the next instruction to process, // so don't increment it. @@ -122,13 +157,16 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { // Record the physreg defs. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (MO.isRegister() && MO.isDef()) { + if (MO.isReg() && MO.isDef()) { unsigned Reg = MO.getReg(); - if (Reg != 0 && TargetRegisterInfo::isPhysicalRegister(Reg)) { + if (TargetRegisterInfo::isPhysicalRegister(Reg)) { LivePhysRegs.reset(Reg); - for (const unsigned *AliasSet = TRI->getAliasSet(Reg); - *AliasSet; ++AliasSet) - LivePhysRegs.reset(*AliasSet); + // Check the subreg set, not the alias set, because a def + // of a super-register may still be partially live after + // this def. + for (const unsigned *SubRegs = TRI->getSubRegisters(Reg); + *SubRegs; ++SubRegs) + LivePhysRegs.reset(*SubRegs); } } } @@ -136,9 +174,9 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { // both defined and used in the same instruction. for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { const MachineOperand &MO = MI->getOperand(i); - if (MO.isRegister() && MO.isUse()) { + if (MO.isReg() && MO.isUse()) { unsigned Reg = MO.getReg(); - if (Reg != 0 && TargetRegisterInfo::isPhysicalRegister(Reg)) { + if (TargetRegisterInfo::isPhysicalRegister(Reg)) { LivePhysRegs.set(Reg); for (const unsigned *AliasSet = TRI->getAliasSet(Reg); *AliasSet; ++AliasSet)