X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FCodeGen%2FDeadMachineInstructionElim.cpp;h=4832a5ee9ae0488f37cd2e08c297f8742ae2bf61;hb=2caf1b212e2db36c52f3a7c3e391ea2800802c60;hp=a3bba61e4a2307a15a19a09e1e744b3e6a2d3b72;hpb=d3ead4329eaa46937245f5cc8402e749af2a37dc;p=oota-llvm.git diff --git a/lib/CodeGen/DeadMachineInstructionElim.cpp b/lib/CodeGen/DeadMachineInstructionElim.cpp index a3bba61e4a2..4832a5ee9ae 100644 --- a/lib/CodeGen/DeadMachineInstructionElim.cpp +++ b/lib/CodeGen/DeadMachineInstructionElim.cpp @@ -16,6 +16,7 @@ #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Debug.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" using namespace llvm; @@ -25,9 +26,17 @@ namespace { public MachineFunctionPass { virtual bool runOnMachineFunction(MachineFunction &MF); + const TargetRegisterInfo *TRI; + const MachineRegisterInfo *MRI; + const TargetInstrInfo *TII; + BitVector LivePhysRegs; + public: static char ID; // Pass identification, replacement for typeid DeadMachineInstructionElim() : MachineFunctionPass(&ID) {} + + private: + bool isDead(MachineInstr *MI) const; }; } char DeadMachineInstructionElim::ID = 0; @@ -40,11 +49,38 @@ FunctionPass *llvm::createDeadMachineInstructionElimPass() { return new DeadMachineInstructionElim(); } +bool DeadMachineInstructionElim::isDead(MachineInstr *MI) const { + // Don't delete instructions with side effects. + bool SawStore = false; + if (!MI->isSafeToMove(TII, SawStore)) + return false; + + // Examine each operand. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + 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! + return false; + } + } + } + + // If there are no defs with uses, the instruction is dead. + return true; +} + bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { bool AnyChanges = false; - const MachineRegisterInfo &MRI = MF.getRegInfo(); - const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); - bool SawStore = true; + MRI = &MF.getRegInfo(); + TRI = MF.getTarget().getRegisterInfo(); + TII = MF.getTarget().getInstrInfo(); + + // Compute a bitvector to represent all non-allocatable physregs. + BitVector NonAllocatableRegs = TRI->getAllocatableSet(MF); + NonAllocatableRegs.flip(); // 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 @@ -52,48 +88,74 @@ bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { for (MachineFunction::reverse_iterator I = MF.rbegin(), E = MF.rend(); I != E; ++I) { MachineBasicBlock *MBB = &*I; + + // Start out assuming that all non-allocatable registers are live + // out of this block. + LivePhysRegs = NonAllocatableRegs; + + // Also add any explicit live-out physregs for this block. + if (!MBB->empty() && MBB->back().getDesc().isReturn()) + for (MachineRegisterInfo::liveout_iterator LOI = MRI->liveout_begin(), + LOE = MRI->liveout_end(); LOI != LOE; ++LOI) { + unsigned Reg = *LOI; + if (TargetRegisterInfo::isPhysicalRegister(Reg)) + LivePhysRegs.set(Reg); + } + + // Now scan the instructions and delete dead ones, tracking physreg + // liveness as we go. for (MachineBasicBlock::reverse_iterator MII = MBB->rbegin(), MIE = MBB->rend(); MII != MIE; ) { MachineInstr *MI = &*MII; - // Don't delete instructions with side effects. - if (MI->isSafeToMove(&TII, SawStore)) { - // Examine each operand. - bool AllDefsDead = true; - for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { - const MachineOperand &MO = MI->getOperand(i); - if (MO.isRegister() && MO.isDef()) { - unsigned Reg = MO.getReg(); - if (TargetRegisterInfo::isPhysicalRegister(Reg) || - !MRI.use_empty(Reg)) { - // This def has a use. Don't delete the instruction! - AllDefsDead = false; - break; - } + // If the instruction is dead, delete it! + if (isDead(MI)) { + DOUT << "DeadMachineInstructionElim: DELETING: " << *MI; + AnyChanges = true; + MI->eraseFromParent(); + MIE = MBB->rend(); + // MII is now pointing to the next instruction to process, + // so don't increment it. + continue; + } + + // Record the physreg defs. + for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { + const MachineOperand &MO = MI->getOperand(i); + if (MO.isReg() && MO.isDef()) { + unsigned Reg = MO.getReg(); + if (Reg != 0 && TargetRegisterInfo::isPhysicalRegister(Reg)) { + LivePhysRegs.reset(Reg); + // 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); } } - - // If there are no defs with uses, the instruction is dead. - if (AllDefsDead) { - // Clear out the operands to take the registers out of their - // use chains. - while (unsigned Num = MI->getNumOperands()) - MI->RemoveOperand(Num-1); - - // Delete the actual instruction. - AnyChanges = true; - MI->eraseFromParent(); - MIE = MBB->rend(); - // MII is now pointing to the next instruction to process, - // so don't increment it. - continue; + } + // Record the physreg uses, after the defs, in case a physreg is + // 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.isReg() && MO.isUse()) { + unsigned Reg = MO.getReg(); + if (Reg != 0 && TargetRegisterInfo::isPhysicalRegister(Reg)) { + LivePhysRegs.set(Reg); + for (const unsigned *AliasSet = TRI->getAliasSet(Reg); + *AliasSet; ++AliasSet) + LivePhysRegs.set(*AliasSet); + } } } + // We didn't delete the current instruction, so increment MII to // the next one. ++MII; } } + LivePhysRegs.clear(); return AnyChanges; }