xref: /freebsd/contrib/llvm-project/llvm/lib/CodeGen/DeadMachineInstructionElim.cpp (revision 0b57cec536236d46e3dba9bd041533462f33dbb7)
1*0b57cec5SDimitry Andric //===- DeadMachineInstructionElim.cpp - Remove dead machine instructions --===//
2*0b57cec5SDimitry Andric //
3*0b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric //
7*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8*0b57cec5SDimitry Andric //
9*0b57cec5SDimitry Andric // This is an extremely simple MachineInstr-level dead-code-elimination pass.
10*0b57cec5SDimitry Andric //
11*0b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
12*0b57cec5SDimitry Andric 
13*0b57cec5SDimitry Andric #include "llvm/ADT/Statistic.h"
14*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
15*0b57cec5SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h"
16*0b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h"
17*0b57cec5SDimitry Andric #include "llvm/CodeGen/TargetSubtargetInfo.h"
18*0b57cec5SDimitry Andric #include "llvm/Pass.h"
19*0b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
20*0b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
21*0b57cec5SDimitry Andric 
22*0b57cec5SDimitry Andric using namespace llvm;
23*0b57cec5SDimitry Andric 
24*0b57cec5SDimitry Andric #define DEBUG_TYPE "dead-mi-elimination"
25*0b57cec5SDimitry Andric 
26*0b57cec5SDimitry Andric STATISTIC(NumDeletes,          "Number of dead instructions deleted");
27*0b57cec5SDimitry Andric 
28*0b57cec5SDimitry Andric namespace {
29*0b57cec5SDimitry Andric   class DeadMachineInstructionElim : public MachineFunctionPass {
30*0b57cec5SDimitry Andric     bool runOnMachineFunction(MachineFunction &MF) override;
31*0b57cec5SDimitry Andric 
32*0b57cec5SDimitry Andric     const TargetRegisterInfo *TRI;
33*0b57cec5SDimitry Andric     const MachineRegisterInfo *MRI;
34*0b57cec5SDimitry Andric     const TargetInstrInfo *TII;
35*0b57cec5SDimitry Andric     BitVector LivePhysRegs;
36*0b57cec5SDimitry Andric 
37*0b57cec5SDimitry Andric   public:
38*0b57cec5SDimitry Andric     static char ID; // Pass identification, replacement for typeid
39*0b57cec5SDimitry Andric     DeadMachineInstructionElim() : MachineFunctionPass(ID) {
40*0b57cec5SDimitry Andric      initializeDeadMachineInstructionElimPass(*PassRegistry::getPassRegistry());
41*0b57cec5SDimitry Andric     }
42*0b57cec5SDimitry Andric 
43*0b57cec5SDimitry Andric     void getAnalysisUsage(AnalysisUsage &AU) const override {
44*0b57cec5SDimitry Andric       AU.setPreservesCFG();
45*0b57cec5SDimitry Andric       MachineFunctionPass::getAnalysisUsage(AU);
46*0b57cec5SDimitry Andric     }
47*0b57cec5SDimitry Andric 
48*0b57cec5SDimitry Andric   private:
49*0b57cec5SDimitry Andric     bool isDead(const MachineInstr *MI) const;
50*0b57cec5SDimitry Andric   };
51*0b57cec5SDimitry Andric }
52*0b57cec5SDimitry Andric char DeadMachineInstructionElim::ID = 0;
53*0b57cec5SDimitry Andric char &llvm::DeadMachineInstructionElimID = DeadMachineInstructionElim::ID;
54*0b57cec5SDimitry Andric 
55*0b57cec5SDimitry Andric INITIALIZE_PASS(DeadMachineInstructionElim, DEBUG_TYPE,
56*0b57cec5SDimitry Andric                 "Remove dead machine instructions", false, false)
57*0b57cec5SDimitry Andric 
58*0b57cec5SDimitry Andric bool DeadMachineInstructionElim::isDead(const MachineInstr *MI) const {
59*0b57cec5SDimitry Andric   // Technically speaking inline asm without side effects and no defs can still
60*0b57cec5SDimitry Andric   // be deleted. But there is so much bad inline asm code out there, we should
61*0b57cec5SDimitry Andric   // let them be.
62*0b57cec5SDimitry Andric   if (MI->isInlineAsm())
63*0b57cec5SDimitry Andric     return false;
64*0b57cec5SDimitry Andric 
65*0b57cec5SDimitry Andric   // Don't delete frame allocation labels.
66*0b57cec5SDimitry Andric   if (MI->getOpcode() == TargetOpcode::LOCAL_ESCAPE)
67*0b57cec5SDimitry Andric     return false;
68*0b57cec5SDimitry Andric 
69*0b57cec5SDimitry Andric   // Don't delete instructions with side effects.
70*0b57cec5SDimitry Andric   bool SawStore = false;
71*0b57cec5SDimitry Andric   if (!MI->isSafeToMove(nullptr, SawStore) && !MI->isPHI())
72*0b57cec5SDimitry Andric     return false;
73*0b57cec5SDimitry Andric 
74*0b57cec5SDimitry Andric   // Examine each operand.
75*0b57cec5SDimitry Andric   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
76*0b57cec5SDimitry Andric     const MachineOperand &MO = MI->getOperand(i);
77*0b57cec5SDimitry Andric     if (MO.isReg() && MO.isDef()) {
78*0b57cec5SDimitry Andric       unsigned Reg = MO.getReg();
79*0b57cec5SDimitry Andric       if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
80*0b57cec5SDimitry Andric         // Don't delete live physreg defs, or any reserved register defs.
81*0b57cec5SDimitry Andric         if (LivePhysRegs.test(Reg) || MRI->isReserved(Reg))
82*0b57cec5SDimitry Andric           return false;
83*0b57cec5SDimitry Andric       } else {
84*0b57cec5SDimitry Andric         for (const MachineInstr &Use : MRI->use_nodbg_instructions(Reg)) {
85*0b57cec5SDimitry Andric           if (&Use != MI)
86*0b57cec5SDimitry Andric             // This def has a non-debug use. Don't delete the instruction!
87*0b57cec5SDimitry Andric             return false;
88*0b57cec5SDimitry Andric         }
89*0b57cec5SDimitry Andric       }
90*0b57cec5SDimitry Andric     }
91*0b57cec5SDimitry Andric   }
92*0b57cec5SDimitry Andric 
93*0b57cec5SDimitry Andric   // If there are no defs with uses, the instruction is dead.
94*0b57cec5SDimitry Andric   return true;
95*0b57cec5SDimitry Andric }
96*0b57cec5SDimitry Andric 
97*0b57cec5SDimitry Andric bool DeadMachineInstructionElim::runOnMachineFunction(MachineFunction &MF) {
98*0b57cec5SDimitry Andric   if (skipFunction(MF.getFunction()))
99*0b57cec5SDimitry Andric     return false;
100*0b57cec5SDimitry Andric 
101*0b57cec5SDimitry Andric   bool AnyChanges = false;
102*0b57cec5SDimitry Andric   MRI = &MF.getRegInfo();
103*0b57cec5SDimitry Andric   TRI = MF.getSubtarget().getRegisterInfo();
104*0b57cec5SDimitry Andric   TII = MF.getSubtarget().getInstrInfo();
105*0b57cec5SDimitry Andric 
106*0b57cec5SDimitry Andric   // Loop over all instructions in all blocks, from bottom to top, so that it's
107*0b57cec5SDimitry Andric   // more likely that chains of dependent but ultimately dead instructions will
108*0b57cec5SDimitry Andric   // be cleaned up.
109*0b57cec5SDimitry Andric   for (MachineBasicBlock &MBB : make_range(MF.rbegin(), MF.rend())) {
110*0b57cec5SDimitry Andric     // Start out assuming that reserved registers are live out of this block.
111*0b57cec5SDimitry Andric     LivePhysRegs = MRI->getReservedRegs();
112*0b57cec5SDimitry Andric 
113*0b57cec5SDimitry Andric     // Add live-ins from successors to LivePhysRegs. Normally, physregs are not
114*0b57cec5SDimitry Andric     // live across blocks, but some targets (x86) can have flags live out of a
115*0b57cec5SDimitry Andric     // block.
116*0b57cec5SDimitry Andric     for (MachineBasicBlock::succ_iterator S = MBB.succ_begin(),
117*0b57cec5SDimitry Andric            E = MBB.succ_end(); S != E; S++)
118*0b57cec5SDimitry Andric       for (const auto &LI : (*S)->liveins())
119*0b57cec5SDimitry Andric         LivePhysRegs.set(LI.PhysReg);
120*0b57cec5SDimitry Andric 
121*0b57cec5SDimitry Andric     // Now scan the instructions and delete dead ones, tracking physreg
122*0b57cec5SDimitry Andric     // liveness as we go.
123*0b57cec5SDimitry Andric     for (MachineBasicBlock::reverse_iterator MII = MBB.rbegin(),
124*0b57cec5SDimitry Andric          MIE = MBB.rend(); MII != MIE; ) {
125*0b57cec5SDimitry Andric       MachineInstr *MI = &*MII++;
126*0b57cec5SDimitry Andric 
127*0b57cec5SDimitry Andric       // If the instruction is dead, delete it!
128*0b57cec5SDimitry Andric       if (isDead(MI)) {
129*0b57cec5SDimitry Andric         LLVM_DEBUG(dbgs() << "DeadMachineInstructionElim: DELETING: " << *MI);
130*0b57cec5SDimitry Andric         // It is possible that some DBG_VALUE instructions refer to this
131*0b57cec5SDimitry Andric         // instruction.  They get marked as undef and will be deleted
132*0b57cec5SDimitry Andric         // in the live debug variable analysis.
133*0b57cec5SDimitry Andric         MI->eraseFromParentAndMarkDBGValuesForRemoval();
134*0b57cec5SDimitry Andric         AnyChanges = true;
135*0b57cec5SDimitry Andric         ++NumDeletes;
136*0b57cec5SDimitry Andric         continue;
137*0b57cec5SDimitry Andric       }
138*0b57cec5SDimitry Andric 
139*0b57cec5SDimitry Andric       // Record the physreg defs.
140*0b57cec5SDimitry Andric       for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
141*0b57cec5SDimitry Andric         const MachineOperand &MO = MI->getOperand(i);
142*0b57cec5SDimitry Andric         if (MO.isReg() && MO.isDef()) {
143*0b57cec5SDimitry Andric           unsigned Reg = MO.getReg();
144*0b57cec5SDimitry Andric           if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
145*0b57cec5SDimitry Andric             // Check the subreg set, not the alias set, because a def
146*0b57cec5SDimitry Andric             // of a super-register may still be partially live after
147*0b57cec5SDimitry Andric             // this def.
148*0b57cec5SDimitry Andric             for (MCSubRegIterator SR(Reg, TRI,/*IncludeSelf=*/true);
149*0b57cec5SDimitry Andric                  SR.isValid(); ++SR)
150*0b57cec5SDimitry Andric               LivePhysRegs.reset(*SR);
151*0b57cec5SDimitry Andric           }
152*0b57cec5SDimitry Andric         } else if (MO.isRegMask()) {
153*0b57cec5SDimitry Andric           // Register mask of preserved registers. All clobbers are dead.
154*0b57cec5SDimitry Andric           LivePhysRegs.clearBitsNotInMask(MO.getRegMask());
155*0b57cec5SDimitry Andric         }
156*0b57cec5SDimitry Andric       }
157*0b57cec5SDimitry Andric       // Record the physreg uses, after the defs, in case a physreg is
158*0b57cec5SDimitry Andric       // both defined and used in the same instruction.
159*0b57cec5SDimitry Andric       for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
160*0b57cec5SDimitry Andric         const MachineOperand &MO = MI->getOperand(i);
161*0b57cec5SDimitry Andric         if (MO.isReg() && MO.isUse()) {
162*0b57cec5SDimitry Andric           unsigned Reg = MO.getReg();
163*0b57cec5SDimitry Andric           if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
164*0b57cec5SDimitry Andric             for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
165*0b57cec5SDimitry Andric               LivePhysRegs.set(*AI);
166*0b57cec5SDimitry Andric           }
167*0b57cec5SDimitry Andric         }
168*0b57cec5SDimitry Andric       }
169*0b57cec5SDimitry Andric     }
170*0b57cec5SDimitry Andric   }
171*0b57cec5SDimitry Andric 
172*0b57cec5SDimitry Andric   LivePhysRegs.clear();
173*0b57cec5SDimitry Andric   return AnyChanges;
174*0b57cec5SDimitry Andric }
175