1*9880d681SAndroid Build Coastguard Worker //===- MachineCopyPropagation.cpp - Machine Copy Propagation Pass ---------===//
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 copy propagation 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/DenseMap.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SetVector.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallVector.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Statistic.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunction.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineFunctionPass.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/CodeGen/MachineRegisterInfo.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/Pass.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/raw_ostream.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetInstrInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetRegisterInfo.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/Target/TargetSubtargetInfo.h"
28*9880d681SAndroid Build Coastguard Worker using namespace llvm;
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "codegen-cp"
31*9880d681SAndroid Build Coastguard Worker
32*9880d681SAndroid Build Coastguard Worker STATISTIC(NumDeletes, "Number of dead copies deleted");
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker namespace {
35*9880d681SAndroid Build Coastguard Worker typedef SmallVector<unsigned, 4> RegList;
36*9880d681SAndroid Build Coastguard Worker typedef DenseMap<unsigned, RegList> SourceMap;
37*9880d681SAndroid Build Coastguard Worker typedef DenseMap<unsigned, MachineInstr*> Reg2MIMap;
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker class MachineCopyPropagation : public MachineFunctionPass {
40*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo *TRI;
41*9880d681SAndroid Build Coastguard Worker const TargetInstrInfo *TII;
42*9880d681SAndroid Build Coastguard Worker const MachineRegisterInfo *MRI;
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker public:
45*9880d681SAndroid Build Coastguard Worker static char ID; // Pass identification, replacement for typeid
MachineCopyPropagation()46*9880d681SAndroid Build Coastguard Worker MachineCopyPropagation() : MachineFunctionPass(ID) {
47*9880d681SAndroid Build Coastguard Worker initializeMachineCopyPropagationPass(*PassRegistry::getPassRegistry());
48*9880d681SAndroid Build Coastguard Worker }
49*9880d681SAndroid Build Coastguard Worker
getAnalysisUsage(AnalysisUsage & AU) const50*9880d681SAndroid Build Coastguard Worker void getAnalysisUsage(AnalysisUsage &AU) const override {
51*9880d681SAndroid Build Coastguard Worker AU.setPreservesCFG();
52*9880d681SAndroid Build Coastguard Worker MachineFunctionPass::getAnalysisUsage(AU);
53*9880d681SAndroid Build Coastguard Worker }
54*9880d681SAndroid Build Coastguard Worker
55*9880d681SAndroid Build Coastguard Worker bool runOnMachineFunction(MachineFunction &MF) override;
56*9880d681SAndroid Build Coastguard Worker
getRequiredProperties() const57*9880d681SAndroid Build Coastguard Worker MachineFunctionProperties getRequiredProperties() const override {
58*9880d681SAndroid Build Coastguard Worker return MachineFunctionProperties().set(
59*9880d681SAndroid Build Coastguard Worker MachineFunctionProperties::Property::AllVRegsAllocated);
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
62*9880d681SAndroid Build Coastguard Worker private:
63*9880d681SAndroid Build Coastguard Worker void ClobberRegister(unsigned Reg);
64*9880d681SAndroid Build Coastguard Worker void CopyPropagateBlock(MachineBasicBlock &MBB);
65*9880d681SAndroid Build Coastguard Worker bool eraseIfRedundant(MachineInstr &Copy, unsigned Src, unsigned Def);
66*9880d681SAndroid Build Coastguard Worker
67*9880d681SAndroid Build Coastguard Worker /// Candidates for deletion.
68*9880d681SAndroid Build Coastguard Worker SmallSetVector<MachineInstr*, 8> MaybeDeadCopies;
69*9880d681SAndroid Build Coastguard Worker /// Def -> available copies map.
70*9880d681SAndroid Build Coastguard Worker Reg2MIMap AvailCopyMap;
71*9880d681SAndroid Build Coastguard Worker /// Def -> copies map.
72*9880d681SAndroid Build Coastguard Worker Reg2MIMap CopyMap;
73*9880d681SAndroid Build Coastguard Worker /// Src -> Def map
74*9880d681SAndroid Build Coastguard Worker SourceMap SrcMap;
75*9880d681SAndroid Build Coastguard Worker bool Changed;
76*9880d681SAndroid Build Coastguard Worker };
77*9880d681SAndroid Build Coastguard Worker }
78*9880d681SAndroid Build Coastguard Worker char MachineCopyPropagation::ID = 0;
79*9880d681SAndroid Build Coastguard Worker char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID;
80*9880d681SAndroid Build Coastguard Worker
81*9880d681SAndroid Build Coastguard Worker INITIALIZE_PASS(MachineCopyPropagation, "machine-cp",
82*9880d681SAndroid Build Coastguard Worker "Machine Copy Propagation Pass", false, false)
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker /// Remove any entry in \p Map where the register is a subregister or equal to
85*9880d681SAndroid Build Coastguard Worker /// a register contained in \p Regs.
removeRegsFromMap(Reg2MIMap & Map,const RegList & Regs,const TargetRegisterInfo & TRI)86*9880d681SAndroid Build Coastguard Worker static void removeRegsFromMap(Reg2MIMap &Map, const RegList &Regs,
87*9880d681SAndroid Build Coastguard Worker const TargetRegisterInfo &TRI) {
88*9880d681SAndroid Build Coastguard Worker for (unsigned Reg : Regs) {
89*9880d681SAndroid Build Coastguard Worker // Source of copy is no longer available for propagation.
90*9880d681SAndroid Build Coastguard Worker for (MCSubRegIterator SR(Reg, &TRI, true); SR.isValid(); ++SR)
91*9880d681SAndroid Build Coastguard Worker Map.erase(*SR);
92*9880d681SAndroid Build Coastguard Worker }
93*9880d681SAndroid Build Coastguard Worker }
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker /// Remove any entry in \p Map that is marked clobbered in \p RegMask.
96*9880d681SAndroid Build Coastguard Worker /// The map will typically have a lot fewer entries than the regmask clobbers,
97*9880d681SAndroid Build Coastguard Worker /// so this is more efficient than iterating the clobbered registers and calling
98*9880d681SAndroid Build Coastguard Worker /// ClobberRegister() on them.
removeClobberedRegsFromMap(Reg2MIMap & Map,const MachineOperand & RegMask)99*9880d681SAndroid Build Coastguard Worker static void removeClobberedRegsFromMap(Reg2MIMap &Map,
100*9880d681SAndroid Build Coastguard Worker const MachineOperand &RegMask) {
101*9880d681SAndroid Build Coastguard Worker for (Reg2MIMap::iterator I = Map.begin(), E = Map.end(), Next; I != E;
102*9880d681SAndroid Build Coastguard Worker I = Next) {
103*9880d681SAndroid Build Coastguard Worker Next = std::next(I);
104*9880d681SAndroid Build Coastguard Worker unsigned Reg = I->first;
105*9880d681SAndroid Build Coastguard Worker if (RegMask.clobbersPhysReg(Reg))
106*9880d681SAndroid Build Coastguard Worker Map.erase(I);
107*9880d681SAndroid Build Coastguard Worker }
108*9880d681SAndroid Build Coastguard Worker }
109*9880d681SAndroid Build Coastguard Worker
ClobberRegister(unsigned Reg)110*9880d681SAndroid Build Coastguard Worker void MachineCopyPropagation::ClobberRegister(unsigned Reg) {
111*9880d681SAndroid Build Coastguard Worker for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
112*9880d681SAndroid Build Coastguard Worker CopyMap.erase(*AI);
113*9880d681SAndroid Build Coastguard Worker AvailCopyMap.erase(*AI);
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker SourceMap::iterator SI = SrcMap.find(*AI);
116*9880d681SAndroid Build Coastguard Worker if (SI != SrcMap.end()) {
117*9880d681SAndroid Build Coastguard Worker removeRegsFromMap(AvailCopyMap, SI->second, *TRI);
118*9880d681SAndroid Build Coastguard Worker SrcMap.erase(SI);
119*9880d681SAndroid Build Coastguard Worker }
120*9880d681SAndroid Build Coastguard Worker }
121*9880d681SAndroid Build Coastguard Worker }
122*9880d681SAndroid Build Coastguard Worker
123*9880d681SAndroid Build Coastguard Worker /// Return true if \p PreviousCopy did copy register \p Src to register \p Def.
124*9880d681SAndroid Build Coastguard Worker /// This fact may have been obscured by sub register usage or may not be true at
125*9880d681SAndroid Build Coastguard Worker /// all even though Src and Def are subregisters of the registers used in
126*9880d681SAndroid Build Coastguard Worker /// PreviousCopy. e.g.
127*9880d681SAndroid Build Coastguard Worker /// isNopCopy("ecx = COPY eax", AX, CX) == true
128*9880d681SAndroid Build Coastguard Worker /// isNopCopy("ecx = COPY eax", AH, CL) == false
isNopCopy(const MachineInstr & PreviousCopy,unsigned Src,unsigned Def,const TargetRegisterInfo * TRI)129*9880d681SAndroid Build Coastguard Worker static bool isNopCopy(const MachineInstr &PreviousCopy, unsigned Src,
130*9880d681SAndroid Build Coastguard Worker unsigned Def, const TargetRegisterInfo *TRI) {
131*9880d681SAndroid Build Coastguard Worker unsigned PreviousSrc = PreviousCopy.getOperand(1).getReg();
132*9880d681SAndroid Build Coastguard Worker unsigned PreviousDef = PreviousCopy.getOperand(0).getReg();
133*9880d681SAndroid Build Coastguard Worker if (Src == PreviousSrc) {
134*9880d681SAndroid Build Coastguard Worker assert(Def == PreviousDef);
135*9880d681SAndroid Build Coastguard Worker return true;
136*9880d681SAndroid Build Coastguard Worker }
137*9880d681SAndroid Build Coastguard Worker if (!TRI->isSubRegister(PreviousSrc, Src))
138*9880d681SAndroid Build Coastguard Worker return false;
139*9880d681SAndroid Build Coastguard Worker unsigned SubIdx = TRI->getSubRegIndex(PreviousSrc, Src);
140*9880d681SAndroid Build Coastguard Worker return SubIdx == TRI->getSubRegIndex(PreviousDef, Def);
141*9880d681SAndroid Build Coastguard Worker }
142*9880d681SAndroid Build Coastguard Worker
143*9880d681SAndroid Build Coastguard Worker /// Remove instruction \p Copy if there exists a previous copy that copies the
144*9880d681SAndroid Build Coastguard Worker /// register \p Src to the register \p Def; This may happen indirectly by
145*9880d681SAndroid Build Coastguard Worker /// copying the super registers.
eraseIfRedundant(MachineInstr & Copy,unsigned Src,unsigned Def)146*9880d681SAndroid Build Coastguard Worker bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src,
147*9880d681SAndroid Build Coastguard Worker unsigned Def) {
148*9880d681SAndroid Build Coastguard Worker // Avoid eliminating a copy from/to a reserved registers as we cannot predict
149*9880d681SAndroid Build Coastguard Worker // the value (Example: The sparc zero register is writable but stays zero).
150*9880d681SAndroid Build Coastguard Worker if (MRI->isReserved(Src) || MRI->isReserved(Def))
151*9880d681SAndroid Build Coastguard Worker return false;
152*9880d681SAndroid Build Coastguard Worker
153*9880d681SAndroid Build Coastguard Worker // Search for an existing copy.
154*9880d681SAndroid Build Coastguard Worker Reg2MIMap::iterator CI = AvailCopyMap.find(Def);
155*9880d681SAndroid Build Coastguard Worker if (CI == AvailCopyMap.end())
156*9880d681SAndroid Build Coastguard Worker return false;
157*9880d681SAndroid Build Coastguard Worker
158*9880d681SAndroid Build Coastguard Worker // Check that the existing copy uses the correct sub registers.
159*9880d681SAndroid Build Coastguard Worker MachineInstr &PrevCopy = *CI->second;
160*9880d681SAndroid Build Coastguard Worker if (!isNopCopy(PrevCopy, Src, Def, TRI))
161*9880d681SAndroid Build Coastguard Worker return false;
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; Copy.dump());
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker // Copy was redundantly redefining either Src or Def. Remove earlier kill
166*9880d681SAndroid Build Coastguard Worker // flags between Copy and PrevCopy because the value will be reused now.
167*9880d681SAndroid Build Coastguard Worker assert(Copy.isCopy());
168*9880d681SAndroid Build Coastguard Worker unsigned CopyDef = Copy.getOperand(0).getReg();
169*9880d681SAndroid Build Coastguard Worker assert(CopyDef == Src || CopyDef == Def);
170*9880d681SAndroid Build Coastguard Worker for (MachineInstr &MI :
171*9880d681SAndroid Build Coastguard Worker make_range(PrevCopy.getIterator(), Copy.getIterator()))
172*9880d681SAndroid Build Coastguard Worker MI.clearRegisterKills(CopyDef, TRI);
173*9880d681SAndroid Build Coastguard Worker
174*9880d681SAndroid Build Coastguard Worker Copy.eraseFromParent();
175*9880d681SAndroid Build Coastguard Worker Changed = true;
176*9880d681SAndroid Build Coastguard Worker ++NumDeletes;
177*9880d681SAndroid Build Coastguard Worker return true;
178*9880d681SAndroid Build Coastguard Worker }
179*9880d681SAndroid Build Coastguard Worker
CopyPropagateBlock(MachineBasicBlock & MBB)180*9880d681SAndroid Build Coastguard Worker void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
181*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "MCP: CopyPropagateBlock " << MBB.getName() << "\n");
182*9880d681SAndroid Build Coastguard Worker
183*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ) {
184*9880d681SAndroid Build Coastguard Worker MachineInstr *MI = &*I;
185*9880d681SAndroid Build Coastguard Worker ++I;
186*9880d681SAndroid Build Coastguard Worker
187*9880d681SAndroid Build Coastguard Worker if (MI->isCopy()) {
188*9880d681SAndroid Build Coastguard Worker unsigned Def = MI->getOperand(0).getReg();
189*9880d681SAndroid Build Coastguard Worker unsigned Src = MI->getOperand(1).getReg();
190*9880d681SAndroid Build Coastguard Worker
191*9880d681SAndroid Build Coastguard Worker assert(!TargetRegisterInfo::isVirtualRegister(Def) &&
192*9880d681SAndroid Build Coastguard Worker !TargetRegisterInfo::isVirtualRegister(Src) &&
193*9880d681SAndroid Build Coastguard Worker "MachineCopyPropagation should be run after register allocation!");
194*9880d681SAndroid Build Coastguard Worker
195*9880d681SAndroid Build Coastguard Worker // The two copies cancel out and the source of the first copy
196*9880d681SAndroid Build Coastguard Worker // hasn't been overridden, eliminate the second one. e.g.
197*9880d681SAndroid Build Coastguard Worker // %ECX<def> = COPY %EAX
198*9880d681SAndroid Build Coastguard Worker // ... nothing clobbered EAX.
199*9880d681SAndroid Build Coastguard Worker // %EAX<def> = COPY %ECX
200*9880d681SAndroid Build Coastguard Worker // =>
201*9880d681SAndroid Build Coastguard Worker // %ECX<def> = COPY %EAX
202*9880d681SAndroid Build Coastguard Worker //
203*9880d681SAndroid Build Coastguard Worker // or
204*9880d681SAndroid Build Coastguard Worker //
205*9880d681SAndroid Build Coastguard Worker // %ECX<def> = COPY %EAX
206*9880d681SAndroid Build Coastguard Worker // ... nothing clobbered EAX.
207*9880d681SAndroid Build Coastguard Worker // %ECX<def> = COPY %EAX
208*9880d681SAndroid Build Coastguard Worker // =>
209*9880d681SAndroid Build Coastguard Worker // %ECX<def> = COPY %EAX
210*9880d681SAndroid Build Coastguard Worker if (eraseIfRedundant(*MI, Def, Src) || eraseIfRedundant(*MI, Src, Def))
211*9880d681SAndroid Build Coastguard Worker continue;
212*9880d681SAndroid Build Coastguard Worker
213*9880d681SAndroid Build Coastguard Worker // If Src is defined by a previous copy, the previous copy cannot be
214*9880d681SAndroid Build Coastguard Worker // eliminated.
215*9880d681SAndroid Build Coastguard Worker for (MCRegAliasIterator AI(Src, TRI, true); AI.isValid(); ++AI) {
216*9880d681SAndroid Build Coastguard Worker Reg2MIMap::iterator CI = CopyMap.find(*AI);
217*9880d681SAndroid Build Coastguard Worker if (CI != CopyMap.end()) {
218*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "MCP: Copy is no longer dead: "; CI->second->dump());
219*9880d681SAndroid Build Coastguard Worker MaybeDeadCopies.remove(CI->second);
220*9880d681SAndroid Build Coastguard Worker }
221*9880d681SAndroid Build Coastguard Worker }
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI->dump());
224*9880d681SAndroid Build Coastguard Worker
225*9880d681SAndroid Build Coastguard Worker // Copy is now a candidate for deletion.
226*9880d681SAndroid Build Coastguard Worker if (!MRI->isReserved(Def))
227*9880d681SAndroid Build Coastguard Worker MaybeDeadCopies.insert(MI);
228*9880d681SAndroid Build Coastguard Worker
229*9880d681SAndroid Build Coastguard Worker // If 'Def' is previously source of another copy, then this earlier copy's
230*9880d681SAndroid Build Coastguard Worker // source is no longer available. e.g.
231*9880d681SAndroid Build Coastguard Worker // %xmm9<def> = copy %xmm2
232*9880d681SAndroid Build Coastguard Worker // ...
233*9880d681SAndroid Build Coastguard Worker // %xmm2<def> = copy %xmm0
234*9880d681SAndroid Build Coastguard Worker // ...
235*9880d681SAndroid Build Coastguard Worker // %xmm2<def> = copy %xmm9
236*9880d681SAndroid Build Coastguard Worker ClobberRegister(Def);
237*9880d681SAndroid Build Coastguard Worker
238*9880d681SAndroid Build Coastguard Worker // Remember Def is defined by the copy.
239*9880d681SAndroid Build Coastguard Worker for (MCSubRegIterator SR(Def, TRI, /*IncludeSelf=*/true); SR.isValid();
240*9880d681SAndroid Build Coastguard Worker ++SR) {
241*9880d681SAndroid Build Coastguard Worker CopyMap[*SR] = MI;
242*9880d681SAndroid Build Coastguard Worker AvailCopyMap[*SR] = MI;
243*9880d681SAndroid Build Coastguard Worker }
244*9880d681SAndroid Build Coastguard Worker
245*9880d681SAndroid Build Coastguard Worker // Remember source that's copied to Def. Once it's clobbered, then
246*9880d681SAndroid Build Coastguard Worker // it's no longer available for copy propagation.
247*9880d681SAndroid Build Coastguard Worker RegList &DestList = SrcMap[Src];
248*9880d681SAndroid Build Coastguard Worker if (std::find(DestList.begin(), DestList.end(), Def) == DestList.end())
249*9880d681SAndroid Build Coastguard Worker DestList.push_back(Def);
250*9880d681SAndroid Build Coastguard Worker
251*9880d681SAndroid Build Coastguard Worker continue;
252*9880d681SAndroid Build Coastguard Worker }
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Worker // Not a copy.
255*9880d681SAndroid Build Coastguard Worker SmallVector<unsigned, 2> Defs;
256*9880d681SAndroid Build Coastguard Worker const MachineOperand *RegMask = nullptr;
257*9880d681SAndroid Build Coastguard Worker for (const MachineOperand &MO : MI->operands()) {
258*9880d681SAndroid Build Coastguard Worker if (MO.isRegMask())
259*9880d681SAndroid Build Coastguard Worker RegMask = &MO;
260*9880d681SAndroid Build Coastguard Worker if (!MO.isReg())
261*9880d681SAndroid Build Coastguard Worker continue;
262*9880d681SAndroid Build Coastguard Worker unsigned Reg = MO.getReg();
263*9880d681SAndroid Build Coastguard Worker if (!Reg)
264*9880d681SAndroid Build Coastguard Worker continue;
265*9880d681SAndroid Build Coastguard Worker
266*9880d681SAndroid Build Coastguard Worker assert(!TargetRegisterInfo::isVirtualRegister(Reg) &&
267*9880d681SAndroid Build Coastguard Worker "MachineCopyPropagation should be run after register allocation!");
268*9880d681SAndroid Build Coastguard Worker
269*9880d681SAndroid Build Coastguard Worker if (MO.isDef()) {
270*9880d681SAndroid Build Coastguard Worker Defs.push_back(Reg);
271*9880d681SAndroid Build Coastguard Worker continue;
272*9880d681SAndroid Build Coastguard Worker }
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Worker // If 'Reg' is defined by a copy, the copy is no longer a candidate
275*9880d681SAndroid Build Coastguard Worker // for elimination.
276*9880d681SAndroid Build Coastguard Worker for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
277*9880d681SAndroid Build Coastguard Worker Reg2MIMap::iterator CI = CopyMap.find(*AI);
278*9880d681SAndroid Build Coastguard Worker if (CI != CopyMap.end()) {
279*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "MCP: Copy is used - not dead: "; CI->second->dump());
280*9880d681SAndroid Build Coastguard Worker MaybeDeadCopies.remove(CI->second);
281*9880d681SAndroid Build Coastguard Worker }
282*9880d681SAndroid Build Coastguard Worker }
283*9880d681SAndroid Build Coastguard Worker // Treat undef use like defs for copy propagation but not for
284*9880d681SAndroid Build Coastguard Worker // dead copy. We would need to do a liveness check to be sure the copy
285*9880d681SAndroid Build Coastguard Worker // is dead for undef uses.
286*9880d681SAndroid Build Coastguard Worker // The backends are allowed to do whatever they want with undef value
287*9880d681SAndroid Build Coastguard Worker // and we cannot be sure this register will not be rewritten to break
288*9880d681SAndroid Build Coastguard Worker // some false dependencies for the hardware for instance.
289*9880d681SAndroid Build Coastguard Worker if (MO.isUndef())
290*9880d681SAndroid Build Coastguard Worker Defs.push_back(Reg);
291*9880d681SAndroid Build Coastguard Worker }
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker // The instruction has a register mask operand which means that it clobbers
294*9880d681SAndroid Build Coastguard Worker // a large set of registers. Treat clobbered registers the same way as
295*9880d681SAndroid Build Coastguard Worker // defined registers.
296*9880d681SAndroid Build Coastguard Worker if (RegMask) {
297*9880d681SAndroid Build Coastguard Worker // Erase any MaybeDeadCopies whose destination register is clobbered.
298*9880d681SAndroid Build Coastguard Worker for (SmallSetVector<MachineInstr *, 8>::iterator DI =
299*9880d681SAndroid Build Coastguard Worker MaybeDeadCopies.begin();
300*9880d681SAndroid Build Coastguard Worker DI != MaybeDeadCopies.end();) {
301*9880d681SAndroid Build Coastguard Worker MachineInstr *MaybeDead = *DI;
302*9880d681SAndroid Build Coastguard Worker unsigned Reg = MaybeDead->getOperand(0).getReg();
303*9880d681SAndroid Build Coastguard Worker assert(!MRI->isReserved(Reg));
304*9880d681SAndroid Build Coastguard Worker
305*9880d681SAndroid Build Coastguard Worker if (!RegMask->clobbersPhysReg(Reg)) {
306*9880d681SAndroid Build Coastguard Worker ++DI;
307*9880d681SAndroid Build Coastguard Worker continue;
308*9880d681SAndroid Build Coastguard Worker }
309*9880d681SAndroid Build Coastguard Worker
310*9880d681SAndroid Build Coastguard Worker DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: ";
311*9880d681SAndroid Build Coastguard Worker MaybeDead->dump());
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker // erase() will return the next valid iterator pointing to the next
314*9880d681SAndroid Build Coastguard Worker // element after the erased one.
315*9880d681SAndroid Build Coastguard Worker DI = MaybeDeadCopies.erase(DI);
316*9880d681SAndroid Build Coastguard Worker MaybeDead->eraseFromParent();
317*9880d681SAndroid Build Coastguard Worker Changed = true;
318*9880d681SAndroid Build Coastguard Worker ++NumDeletes;
319*9880d681SAndroid Build Coastguard Worker }
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker removeClobberedRegsFromMap(AvailCopyMap, *RegMask);
322*9880d681SAndroid Build Coastguard Worker removeClobberedRegsFromMap(CopyMap, *RegMask);
323*9880d681SAndroid Build Coastguard Worker for (SourceMap::iterator I = SrcMap.begin(), E = SrcMap.end(), Next;
324*9880d681SAndroid Build Coastguard Worker I != E; I = Next) {
325*9880d681SAndroid Build Coastguard Worker Next = std::next(I);
326*9880d681SAndroid Build Coastguard Worker if (RegMask->clobbersPhysReg(I->first)) {
327*9880d681SAndroid Build Coastguard Worker removeRegsFromMap(AvailCopyMap, I->second, *TRI);
328*9880d681SAndroid Build Coastguard Worker SrcMap.erase(I);
329*9880d681SAndroid Build Coastguard Worker }
330*9880d681SAndroid Build Coastguard Worker }
331*9880d681SAndroid Build Coastguard Worker }
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker // Any previous copy definition or reading the Defs is no longer available.
334*9880d681SAndroid Build Coastguard Worker for (unsigned Reg : Defs)
335*9880d681SAndroid Build Coastguard Worker ClobberRegister(Reg);
336*9880d681SAndroid Build Coastguard Worker }
337*9880d681SAndroid Build Coastguard Worker
338*9880d681SAndroid Build Coastguard Worker // If MBB doesn't have successors, delete the copies whose defs are not used.
339*9880d681SAndroid Build Coastguard Worker // If MBB does have successors, then conservative assume the defs are live-out
340*9880d681SAndroid Build Coastguard Worker // since we don't want to trust live-in lists.
341*9880d681SAndroid Build Coastguard Worker if (MBB.succ_empty()) {
342*9880d681SAndroid Build Coastguard Worker for (MachineInstr *MaybeDead : MaybeDeadCopies) {
343*9880d681SAndroid Build Coastguard Worker assert(!MRI->isReserved(MaybeDead->getOperand(0).getReg()));
344*9880d681SAndroid Build Coastguard Worker MaybeDead->eraseFromParent();
345*9880d681SAndroid Build Coastguard Worker Changed = true;
346*9880d681SAndroid Build Coastguard Worker ++NumDeletes;
347*9880d681SAndroid Build Coastguard Worker }
348*9880d681SAndroid Build Coastguard Worker }
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker MaybeDeadCopies.clear();
351*9880d681SAndroid Build Coastguard Worker AvailCopyMap.clear();
352*9880d681SAndroid Build Coastguard Worker CopyMap.clear();
353*9880d681SAndroid Build Coastguard Worker SrcMap.clear();
354*9880d681SAndroid Build Coastguard Worker }
355*9880d681SAndroid Build Coastguard Worker
runOnMachineFunction(MachineFunction & MF)356*9880d681SAndroid Build Coastguard Worker bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) {
357*9880d681SAndroid Build Coastguard Worker if (skipFunction(*MF.getFunction()))
358*9880d681SAndroid Build Coastguard Worker return false;
359*9880d681SAndroid Build Coastguard Worker
360*9880d681SAndroid Build Coastguard Worker Changed = false;
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker TRI = MF.getSubtarget().getRegisterInfo();
363*9880d681SAndroid Build Coastguard Worker TII = MF.getSubtarget().getInstrInfo();
364*9880d681SAndroid Build Coastguard Worker MRI = &MF.getRegInfo();
365*9880d681SAndroid Build Coastguard Worker
366*9880d681SAndroid Build Coastguard Worker for (MachineBasicBlock &MBB : MF)
367*9880d681SAndroid Build Coastguard Worker CopyPropagateBlock(MBB);
368*9880d681SAndroid Build Coastguard Worker
369*9880d681SAndroid Build Coastguard Worker return Changed;
370*9880d681SAndroid Build Coastguard Worker }
371*9880d681SAndroid Build Coastguard Worker
372