From d3ead4329eaa46937245f5cc8402e749af2a37dc Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 17 Sep 2008 00:43:24 +0000 Subject: [PATCH] Add a new MachineInstr-level DCE pass. It is very simple, and is intended to be used with fast-isel. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@56268 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../llvm/CodeGen/LinkAllCodegenComponents.h | 2 + include/llvm/CodeGen/Passes.h | 5 + lib/CodeGen/DeadMachineInstructionElim.cpp | 99 +++++++++++++++++++ 3 files changed, 106 insertions(+) create mode 100644 lib/CodeGen/DeadMachineInstructionElim.cpp diff --git a/include/llvm/CodeGen/LinkAllCodegenComponents.h b/include/llvm/CodeGen/LinkAllCodegenComponents.h index 9ee22d4926b..ac2e9a4b9a4 100644 --- a/include/llvm/CodeGen/LinkAllCodegenComponents.h +++ b/include/llvm/CodeGen/LinkAllCodegenComponents.h @@ -29,6 +29,8 @@ namespace { if (std::getenv("bar") != (char*) -1) return; + (void) llvm::createDeadMachineInstructionElimPass(); + (void) llvm::createSimpleRegisterAllocator(); (void) llvm::createLocalRegisterAllocator(); (void) llvm::createBigBlockRegisterAllocator(); diff --git a/include/llvm/CodeGen/Passes.h b/include/llvm/CodeGen/Passes.h index ff1f505902e..a7cb578ca6e 100644 --- a/include/llvm/CodeGen/Passes.h +++ b/include/llvm/CodeGen/Passes.h @@ -75,6 +75,11 @@ namespace llvm { /// machine basic blocks. extern const PassInfo *const UnreachableMachineBlockElimID; + /// DeadMachineInstructionElim pass - This pass removes dead machine + /// instructions. + /// + FunctionPass *createDeadMachineInstructionElimPass(); + /// Creates a register allocator as the user specified on the command line. /// FunctionPass *createRegisterAllocator(); diff --git a/lib/CodeGen/DeadMachineInstructionElim.cpp b/lib/CodeGen/DeadMachineInstructionElim.cpp new file mode 100644 index 00000000000..a3bba61e4a2 --- /dev/null +++ b/lib/CodeGen/DeadMachineInstructionElim.cpp @@ -0,0 +1,99 @@ +//===- DeadMachineInstructionElim.cpp - Remove dead machine instructions --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is an extremely simple MachineInstr-level dead-code-elimination pass. +// +//===----------------------------------------------------------------------===// + +#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/Target/TargetInstrInfo.h" +#include "llvm/Target/TargetMachine.h" +using namespace llvm; + +namespace { + class VISIBILITY_HIDDEN DeadMachineInstructionElim : + public MachineFunctionPass { + virtual bool runOnMachineFunction(MachineFunction &MF); + + public: + static char ID; // Pass identification, replacement for typeid + DeadMachineInstructionElim() : MachineFunctionPass(&ID) {} + }; +} +char DeadMachineInstructionElim::ID = 0; + +static RegisterPass +Y("dead-mi-elimination", + "Remove dead machine instructions"); + +FunctionPass *llvm::createDeadMachineInstructionElimPass() { + return new DeadMachineInstructionElim(); +} + +bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) { + bool AnyChanges = false; + const MachineRegisterInfo &MRI = MF.getRegInfo(); + const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); + bool SawStore = true; + + // 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. + for (MachineFunction::reverse_iterator I = MF.rbegin(), E = MF.rend(); + I != E; ++I) { + MachineBasicBlock *MBB = &*I; + 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 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; + } + } + // We didn't delete the current instruction, so increment MII to + // the next one. + ++MII; + } + } + + return AnyChanges; +} -- 2.34.1