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