1f22ef01cSRoman Divacky //===- DeadMachineInstructionElim.cpp - Remove dead machine instructions --===//
2f22ef01cSRoman Divacky //
3f22ef01cSRoman Divacky //                     The LLVM Compiler Infrastructure
4f22ef01cSRoman Divacky //
5f22ef01cSRoman Divacky // This file is distributed under the University of Illinois Open Source
6f22ef01cSRoman Divacky // License. See LICENSE.TXT for details.
7f22ef01cSRoman Divacky //
8f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
9f22ef01cSRoman Divacky //
10f22ef01cSRoman Divacky // This is an extremely simple MachineInstr-level dead-code-elimination pass.
11f22ef01cSRoman Divacky //
12f22ef01cSRoman Divacky //===----------------------------------------------------------------------===//
13f22ef01cSRoman Divacky 
14139f7f9bSDimitry Andric #include "llvm/ADT/Statistic.h"
15f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineFunctionPass.h"
16f22ef01cSRoman Divacky #include "llvm/CodeGen/MachineRegisterInfo.h"
17db17bf38SDimitry Andric #include "llvm/CodeGen/Passes.h"
182cab237bSDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
19139f7f9bSDimitry Andric #include "llvm/Pass.h"
20f22ef01cSRoman Divacky #include "llvm/Support/Debug.h"
21f22ef01cSRoman Divacky #include "llvm/Support/raw_ostream.h"
2239d628a0SDimitry Andric 
23f22ef01cSRoman Divacky using namespace llvm;
24f22ef01cSRoman Divacky 
25302affcbSDimitry Andric #define DEBUG_TYPE "dead-mi-elimination"
2691bc56edSDimitry Andric 
27f22ef01cSRoman Divacky STATISTIC(NumDeletes,          "Number of dead instructions deleted");
28f22ef01cSRoman Divacky 
29f22ef01cSRoman Divacky namespace {
30f22ef01cSRoman Divacky   class DeadMachineInstructionElim : public MachineFunctionPass {
3191bc56edSDimitry Andric     bool runOnMachineFunction(MachineFunction &MF) override;
32f22ef01cSRoman Divacky 
33f22ef01cSRoman Divacky     const TargetRegisterInfo *TRI;
34f22ef01cSRoman Divacky     const MachineRegisterInfo *MRI;
35f22ef01cSRoman Divacky     const TargetInstrInfo *TII;
36f22ef01cSRoman Divacky     BitVector LivePhysRegs;
37f22ef01cSRoman Divacky 
38f22ef01cSRoman Divacky   public:
39f22ef01cSRoman Divacky     static char ID; // Pass identification, replacement for typeid
DeadMachineInstructionElim()402754fe60SDimitry Andric     DeadMachineInstructionElim() : MachineFunctionPass(ID) {
412754fe60SDimitry Andric      initializeDeadMachineInstructionElimPass(*PassRegistry::getPassRegistry());
422754fe60SDimitry Andric     }
43f22ef01cSRoman Divacky 
getAnalysisUsage(AnalysisUsage & AU) const443ca95b02SDimitry Andric     void getAnalysisUsage(AnalysisUsage &AU) const override {
453ca95b02SDimitry Andric       AU.setPreservesCFG();
463ca95b02SDimitry Andric       MachineFunctionPass::getAnalysisUsage(AU);
473ca95b02SDimitry Andric     }
483ca95b02SDimitry Andric 
49f22ef01cSRoman Divacky   private:
50f22ef01cSRoman Divacky     bool isDead(const MachineInstr *MI) const;
51f22ef01cSRoman Divacky   };
523dac3a9bSDimitry Andric }
53f22ef01cSRoman Divacky char DeadMachineInstructionElim::ID = 0;
54dff0c46cSDimitry Andric char &llvm::DeadMachineInstructionElimID = DeadMachineInstructionElim::ID;
55f22ef01cSRoman Divacky 
56302affcbSDimitry Andric INITIALIZE_PASS(DeadMachineInstructionElim, DEBUG_TYPE,
572754fe60SDimitry Andric                 "Remove dead machine instructions", false, false)
58f22ef01cSRoman Divacky 
isDead(const MachineInstr * MI) const59f22ef01cSRoman Divacky bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const {
602754fe60SDimitry Andric   // Technically speaking inline asm without side effects and no defs can still
612754fe60SDimitry Andric   // be deleted. But there is so much bad inline asm code out there, we should
622754fe60SDimitry Andric   // let them be.
632754fe60SDimitry Andric   if (MI->isInlineAsm())
642754fe60SDimitry Andric     return false;
652754fe60SDimitry Andric 
6639d628a0SDimitry Andric   // Don't delete frame allocation labels.
67875ed548SDimitry Andric   if (MI->getOpcode() == TargetOpcode::LOCAL_ESCAPE)
6839d628a0SDimitry Andric     return false;
6939d628a0SDimitry Andric 
70f22ef01cSRoman Divacky   // Don't delete instructions with side effects.
71f22ef01cSRoman Divacky   bool SawStore = false;
72ff0cc061SDimitry Andric   if (!MI->isSafeToMove(nullptr, SawStore) && !MI->isPHI())
73f22ef01cSRoman Divacky     return false;
74f22ef01cSRoman Divacky 
75f22ef01cSRoman Divacky   // Examine each operand.
76f22ef01cSRoman Divacky   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
77f22ef01cSRoman Divacky     const MachineOperand &MO = MI->getOperand(i);
78f22ef01cSRoman Divacky     if (MO.isReg() && MO.isDef()) {
79f22ef01cSRoman Divacky       unsigned Reg = MO.getReg();
80dff0c46cSDimitry Andric       if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
81dff0c46cSDimitry Andric         // Don't delete live physreg defs, or any reserved register defs.
823861d79fSDimitry Andric         if (LivePhysRegs.test(Reg) || MRI->isReserved(Reg))
83dff0c46cSDimitry Andric           return false;
84dff0c46cSDimitry Andric       } else {
85dff0c46cSDimitry Andric         if (!MRI->use_nodbg_empty(Reg))
86f22ef01cSRoman Divacky           // This def has a non-debug use. Don't delete the instruction!
87f22ef01cSRoman Divacky           return false;
88f22ef01cSRoman Divacky       }
89f22ef01cSRoman Divacky     }
90f22ef01cSRoman Divacky   }
91f22ef01cSRoman Divacky 
92f22ef01cSRoman Divacky   // If there are no defs with uses, the instruction is dead.
93f22ef01cSRoman Divacky   return true;
94f22ef01cSRoman Divacky }
95f22ef01cSRoman Divacky 
runOnMachineFunction(MachineFunction & MF)96f22ef01cSRoman Divacky bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
972cab237bSDimitry Andric   if (skipFunction(MF.getFunction()))
9891bc56edSDimitry Andric     return false;
9991bc56edSDimitry Andric 
100f22ef01cSRoman Divacky   bool AnyChanges = false;
101f22ef01cSRoman Divacky   MRI = &MF.getRegInfo();
10239d628a0SDimitry Andric   TRI = MF.getSubtarget().getRegisterInfo();
10339d628a0SDimitry Andric   TII = MF.getSubtarget().getInstrInfo();
104f22ef01cSRoman Divacky 
105f22ef01cSRoman Divacky   // Loop over all instructions in all blocks, from bottom to top, so that it's
106f22ef01cSRoman Divacky   // more likely that chains of dependent but ultimately dead instructions will
107f22ef01cSRoman Divacky   // be cleaned up.
1087d523365SDimitry Andric   for (MachineBasicBlock &MBB : make_range(MF.rbegin(), MF.rend())) {
109e580952dSDimitry Andric     // Start out assuming that reserved registers are live out of this block.
1103861d79fSDimitry Andric     LivePhysRegs = MRI->getReservedRegs();
111f22ef01cSRoman Divacky 
1127a7e6055SDimitry Andric     // Add live-ins from successors to LivePhysRegs. Normally, physregs are not
11317a519f9SDimitry Andric     // live across blocks, but some targets (x86) can have flags live out of a
11417a519f9SDimitry Andric     // block.
1157d523365SDimitry Andric     for (MachineBasicBlock::succ_iterator S = MBB.succ_begin(),
1167d523365SDimitry Andric            E = MBB.succ_end(); S != E; S++)
1177d523365SDimitry Andric       for (const auto &LI : (*S)->liveins())
1187d523365SDimitry Andric         LivePhysRegs.set(LI.PhysReg);
119e580952dSDimitry Andric 
120f22ef01cSRoman Divacky     // Now scan the instructions and delete dead ones, tracking physreg
121f22ef01cSRoman Divacky     // liveness as we go.
1227d523365SDimitry Andric     for (MachineBasicBlock::reverse_iterator MII = MBB.rbegin(),
1237d523365SDimitry Andric          MIE = MBB.rend(); MII != MIE; ) {
124d88c1a5aSDimitry Andric       MachineInstr *MI = &*MII++;
125f22ef01cSRoman Divacky 
126f22ef01cSRoman Divacky       // If the instruction is dead, delete it!
127f22ef01cSRoman Divacky       if (isDead(MI)) {
128*4ba319b5SDimitry Andric         LLVM_DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << *MI);
129f22ef01cSRoman Divacky         // It is possible that some DBG_VALUE instructions refer to this
13039d628a0SDimitry Andric         // instruction.  They get marked as undef and will be deleted
13139d628a0SDimitry Andric         // in the live debug variable analysis.
13239d628a0SDimitry Andric         MI->eraseFromParentAndMarkDBGValuesForRemoval();
133f22ef01cSRoman Divacky         AnyChanges = true;
134f22ef01cSRoman Divacky         ++NumDeletes;
135f22ef01cSRoman Divacky         continue;
136f22ef01cSRoman Divacky       }
137f22ef01cSRoman Divacky 
138f22ef01cSRoman Divacky       // Record the physreg defs.
139f22ef01cSRoman Divacky       for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
140f22ef01cSRoman Divacky         const MachineOperand &MO = MI->getOperand(i);
141f22ef01cSRoman Divacky         if (MO.isReg() && MO.isDef()) {
142f22ef01cSRoman Divacky           unsigned Reg = MO.getReg();
1432754fe60SDimitry Andric           if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
144f22ef01cSRoman Divacky             // Check the subreg set, not the alias set, because a def
145f22ef01cSRoman Divacky             // of a super-register may still be partially live after
146f22ef01cSRoman Divacky             // this def.
147f785676fSDimitry Andric             for (MCSubRegIterator SR(Reg, TRI,/*IncludeSelf=*/true);
148f785676fSDimitry Andric                  SR.isValid(); ++SR)
1497ae0e2c9SDimitry Andric               LivePhysRegs.reset(*SR);
150f22ef01cSRoman Divacky           }
151dff0c46cSDimitry Andric         } else if (MO.isRegMask()) {
152dff0c46cSDimitry Andric           // Register mask of preserved registers. All clobbers are dead.
153dff0c46cSDimitry Andric           LivePhysRegs.clearBitsNotInMask(MO.getRegMask());
154f22ef01cSRoman Divacky         }
155f22ef01cSRoman Divacky       }
156f22ef01cSRoman Divacky       // Record the physreg uses, after the defs, in case a physreg is
157f22ef01cSRoman Divacky       // both defined and used in the same instruction.
158f22ef01cSRoman Divacky       for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
159f22ef01cSRoman Divacky         const MachineOperand &MO = MI->getOperand(i);
160f22ef01cSRoman Divacky         if (MO.isReg() && MO.isUse()) {
161f22ef01cSRoman Divacky           unsigned Reg = MO.getReg();
1622754fe60SDimitry Andric           if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
1637ae0e2c9SDimitry Andric             for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
1647ae0e2c9SDimitry Andric               LivePhysRegs.set(*AI);
165f22ef01cSRoman Divacky           }
166f22ef01cSRoman Divacky         }
167f22ef01cSRoman Divacky       }
168f22ef01cSRoman Divacky     }
169f22ef01cSRoman Divacky   }
170f22ef01cSRoman Divacky 
171f22ef01cSRoman Divacky   LivePhysRegs.clear();
172f22ef01cSRoman Divacky   return AnyChanges;
173f22ef01cSRoman Divacky }
174