blob: e2d7827c5a2f5204a1449f5fc80623b93b7b53f8 [file] [log] [blame]
Evan Cheng00b1a3c2012-01-07 03:02:36 +00001//===- MachineCopyPropagation.cpp - Machine Copy Propagation Pass ---------===//
2//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Evan Cheng00b1a3c2012-01-07 03:02:36 +00006//
7//===----------------------------------------------------------------------===//
8//
Geoff Berryfabedba2017-10-03 16:59:13 +00009// This is an extremely simple MachineInstr-level copy propagation pass.
Evan Cheng00b1a3c2012-01-07 03:02:36 +000010//
Geoff Berrya2b90112018-02-27 16:59:10 +000011// This pass forwards the source of COPYs to the users of their destinations
12// when doing so is legal. For example:
13//
14// %reg1 = COPY %reg0
15// ...
16// ... = OP %reg1
17//
18// If
19// - %reg0 has not been clobbered by the time of the use of %reg1
20// - the register class constraints are satisfied
21// - the COPY def is the only value that reaches OP
22// then this pass replaces the above with:
23//
24// %reg1 = COPY %reg0
25// ...
26// ... = OP %reg0
27//
28// This pass also removes some redundant COPYs. For example:
29//
30// %R1 = COPY %R0
31// ... // No clobber of %R1
32// %R0 = COPY %R1 <<< Removed
33//
34// or
35//
36// %R1 = COPY %R0
37// ... // No clobber of %R0
38// %R1 = COPY %R0 <<< Removed
39//
Kai Luob200c512019-12-05 14:01:00 +080040// or
41//
42// $R0 = OP ...
43// ... // No read/clobber of $R0 and $R1
44// $R1 = COPY $R0 // $R0 is killed
45// Replace $R0 with $R1 and remove the COPY
46// $R1 = OP ...
47// ...
48//
Evan Cheng00b1a3c2012-01-07 03:02:36 +000049//===----------------------------------------------------------------------===//
50
Evan Cheng00b1a3c2012-01-07 03:02:36 +000051#include "llvm/ADT/DenseMap.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000052#include "llvm/ADT/STLExtras.h"
Evan Cheng00b1a3c2012-01-07 03:02:36 +000053#include "llvm/ADT/SetVector.h"
Roman Lebedev17f76542020-06-12 19:08:01 +030054#include "llvm/ADT/SmallSet.h"
Evan Cheng00b1a3c2012-01-07 03:02:36 +000055#include "llvm/ADT/SmallVector.h"
56#include "llvm/ADT/Statistic.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000057#include "llvm/ADT/iterator_range.h"
58#include "llvm/CodeGen/MachineBasicBlock.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000059#include "llvm/CodeGen/MachineFunction.h"
60#include "llvm/CodeGen/MachineFunctionPass.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000061#include "llvm/CodeGen/MachineInstr.h"
62#include "llvm/CodeGen/MachineOperand.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000063#include "llvm/CodeGen/MachineRegisterInfo.h"
Geoff Berrya2b90112018-02-27 16:59:10 +000064#include "llvm/CodeGen/TargetInstrInfo.h"
David Blaikieb3bde2e2017-11-17 01:07:10 +000065#include "llvm/CodeGen/TargetRegisterInfo.h"
66#include "llvm/CodeGen/TargetSubtargetInfo.h"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080067#include "llvm/InitializePasses.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000068#include "llvm/MC/MCRegisterInfo.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000069#include "llvm/Pass.h"
70#include "llvm/Support/Debug.h"
Geoff Berrya2b90112018-02-27 16:59:10 +000071#include "llvm/Support/DebugCounter.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000072#include "llvm/Support/raw_ostream.h"
Eugene Zelenko900b6332017-08-29 22:32:07 +000073#include <cassert>
74#include <iterator>
75
Evan Cheng00b1a3c2012-01-07 03:02:36 +000076using namespace llvm;
77
Matthias Braun1527baa2017-05-25 21:26:32 +000078#define DEBUG_TYPE "machine-cp"
Chandler Carruth1b9dde02014-04-22 02:02:50 +000079
Evan Cheng00b1a3c2012-01-07 03:02:36 +000080STATISTIC(NumDeletes, "Number of dead copies deleted");
Geoff Berrya2b90112018-02-27 16:59:10 +000081STATISTIC(NumCopyForwards, "Number of copy uses forwarded");
Kai Luocd2a73a2019-12-30 16:31:41 +080082STATISTIC(NumCopyBackwardPropagated, "Number of copy defs backward propagated");
Geoff Berrya2b90112018-02-27 16:59:10 +000083DEBUG_COUNTER(FwdCounter, "machine-cp-fwd",
84 "Controls which register COPYs are forwarded");
Evan Cheng00b1a3c2012-01-07 03:02:36 +000085
86namespace {
Eugene Zelenko900b6332017-08-29 22:32:07 +000087
Justin Bogner45b3ddc2018-09-21 00:51:04 +000088class CopyTracker {
Justin Bogner912adfb2018-10-22 19:51:31 +000089 struct CopyInfo {
90 MachineInstr *MI;
91 SmallVector<unsigned, 4> DefRegs;
92 bool Avail;
93 };
Justin Bogner45b3ddc2018-09-21 00:51:04 +000094
Justin Bogner912adfb2018-10-22 19:51:31 +000095 DenseMap<unsigned, CopyInfo> Copies;
Justin Bogner45b3ddc2018-09-21 00:51:04 +000096
97public:
98 /// Mark all of the given registers and their subregisters as unavailable for
99 /// copying.
Justin Bogner912adfb2018-10-22 19:51:31 +0000100 void markRegsUnavailable(ArrayRef<unsigned> Regs,
101 const TargetRegisterInfo &TRI) {
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000102 for (unsigned Reg : Regs) {
103 // Source of copy is no longer available for propagation.
Justin Bogner912adfb2018-10-22 19:51:31 +0000104 for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
105 auto CI = Copies.find(*RUI);
106 if (CI != Copies.end())
107 CI->second.Avail = false;
108 }
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000109 }
110 }
111
Kai Luob200c512019-12-05 14:01:00 +0800112 /// Remove register from copy maps.
113 void invalidateRegister(unsigned Reg, const TargetRegisterInfo &TRI) {
114 // Since Reg might be a subreg of some registers, only invalidate Reg is not
115 // enough. We have to find the COPY defines Reg or registers defined by Reg
116 // and invalidate all of them.
Roman Lebedev17f76542020-06-12 19:08:01 +0300117 SmallSet<unsigned, 8> RegsToInvalidate;
118 RegsToInvalidate.insert(Reg);
Kai Luob200c512019-12-05 14:01:00 +0800119 for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
120 auto I = Copies.find(*RUI);
121 if (I != Copies.end()) {
122 if (MachineInstr *MI = I->second.MI) {
123 RegsToInvalidate.insert(MI->getOperand(0).getReg());
124 RegsToInvalidate.insert(MI->getOperand(1).getReg());
125 }
126 RegsToInvalidate.insert(I->second.DefRegs.begin(),
127 I->second.DefRegs.end());
128 }
129 }
130 for (unsigned InvalidReg : RegsToInvalidate)
131 for (MCRegUnitIterator RUI(InvalidReg, &TRI); RUI.isValid(); ++RUI)
132 Copies.erase(*RUI);
133 }
134
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000135 /// Clobber a single register, removing it from the tracker's copy maps.
136 void clobberRegister(unsigned Reg, const TargetRegisterInfo &TRI) {
Justin Bogner912adfb2018-10-22 19:51:31 +0000137 for (MCRegUnitIterator RUI(Reg, &TRI); RUI.isValid(); ++RUI) {
138 auto I = Copies.find(*RUI);
139 if (I != Copies.end()) {
140 // When we clobber the source of a copy, we need to clobber everything
141 // it defined.
142 markRegsUnavailable(I->second.DefRegs, TRI);
143 // When we clobber the destination of a copy, we need to clobber the
144 // whole register it defined.
145 if (MachineInstr *MI = I->second.MI)
146 markRegsUnavailable({MI->getOperand(0).getReg()}, TRI);
147 // Now we can erase the copy.
148 Copies.erase(I);
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000149 }
150 }
151 }
152
153 /// Add this copy's registers into the tracker's copy maps.
Justin Bogner912adfb2018-10-22 19:51:31 +0000154 void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI) {
155 assert(MI->isCopy() && "Tracking non-copy?");
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000156
Daniel Sanders0c476112019-08-15 19:22:08 +0000157 Register Def = MI->getOperand(0).getReg();
158 Register Src = MI->getOperand(1).getReg();
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000159
160 // Remember Def is defined by the copy.
Justin Bogner912adfb2018-10-22 19:51:31 +0000161 for (MCRegUnitIterator RUI(Def, &TRI); RUI.isValid(); ++RUI)
162 Copies[*RUI] = {MI, {}, true};
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000163
164 // Remember source that's copied to Def. Once it's clobbered, then
165 // it's no longer available for copy propagation.
Justin Bogner912adfb2018-10-22 19:51:31 +0000166 for (MCRegUnitIterator RUI(Src, &TRI); RUI.isValid(); ++RUI) {
167 auto I = Copies.insert({*RUI, {nullptr, {}, false}});
168 auto &Copy = I.first->second;
169 if (!is_contained(Copy.DefRegs, Def))
170 Copy.DefRegs.push_back(Def);
171 }
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000172 }
173
Justin Bogner912adfb2018-10-22 19:51:31 +0000174 bool hasAnyCopies() {
175 return !Copies.empty();
176 }
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000177
Justin Bogner912adfb2018-10-22 19:51:31 +0000178 MachineInstr *findCopyForUnit(unsigned RegUnit, const TargetRegisterInfo &TRI,
179 bool MustBeAvailable = false) {
180 auto CI = Copies.find(RegUnit);
181 if (CI == Copies.end())
Justin Bognerdb02d3d2018-09-25 04:45:25 +0000182 return nullptr;
Justin Bogner912adfb2018-10-22 19:51:31 +0000183 if (MustBeAvailable && !CI->second.Avail)
184 return nullptr;
185 return CI->second.MI;
186 }
187
Kai Luob200c512019-12-05 14:01:00 +0800188 MachineInstr *findCopyDefViaUnit(unsigned RegUnit,
189 const TargetRegisterInfo &TRI) {
190 auto CI = Copies.find(RegUnit);
191 if (CI == Copies.end())
192 return nullptr;
193 if (CI->second.DefRegs.size() != 1)
194 return nullptr;
195 MCRegUnitIterator RUI(CI->second.DefRegs[0], &TRI);
196 return findCopyForUnit(*RUI, TRI, true);
197 }
198
199 MachineInstr *findAvailBackwardCopy(MachineInstr &I, unsigned Reg,
200 const TargetRegisterInfo &TRI) {
201 MCRegUnitIterator RUI(Reg, &TRI);
202 MachineInstr *AvailCopy = findCopyDefViaUnit(*RUI, TRI);
203 if (!AvailCopy ||
204 !TRI.isSubRegisterEq(AvailCopy->getOperand(1).getReg(), Reg))
205 return nullptr;
206
207 Register AvailSrc = AvailCopy->getOperand(1).getReg();
208 Register AvailDef = AvailCopy->getOperand(0).getReg();
209 for (const MachineInstr &MI :
210 make_range(AvailCopy->getReverseIterator(), I.getReverseIterator()))
211 for (const MachineOperand &MO : MI.operands())
212 if (MO.isRegMask())
213 // FIXME: Shall we simultaneously invalidate AvailSrc or AvailDef?
214 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
215 return nullptr;
216
217 return AvailCopy;
218 }
219
Justin Bogner912adfb2018-10-22 19:51:31 +0000220 MachineInstr *findAvailCopy(MachineInstr &DestCopy, unsigned Reg,
221 const TargetRegisterInfo &TRI) {
222 // We check the first RegUnit here, since we'll only be interested in the
223 // copy if it copies the entire register anyway.
224 MCRegUnitIterator RUI(Reg, &TRI);
225 MachineInstr *AvailCopy =
226 findCopyForUnit(*RUI, TRI, /*MustBeAvailable=*/true);
227 if (!AvailCopy ||
228 !TRI.isSubRegisterEq(AvailCopy->getOperand(0).getReg(), Reg))
229 return nullptr;
Justin Bognerdb02d3d2018-09-25 04:45:25 +0000230
231 // Check that the available copy isn't clobbered by any regmasks between
232 // itself and the destination.
Daniel Sanders0c476112019-08-15 19:22:08 +0000233 Register AvailSrc = AvailCopy->getOperand(1).getReg();
234 Register AvailDef = AvailCopy->getOperand(0).getReg();
Justin Bognerdb02d3d2018-09-25 04:45:25 +0000235 for (const MachineInstr &MI :
Justin Bogner912adfb2018-10-22 19:51:31 +0000236 make_range(AvailCopy->getIterator(), DestCopy.getIterator()))
Justin Bognerdb02d3d2018-09-25 04:45:25 +0000237 for (const MachineOperand &MO : MI.operands())
238 if (MO.isRegMask())
239 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
240 return nullptr;
241
Justin Bogner912adfb2018-10-22 19:51:31 +0000242 return AvailCopy;
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000243 }
244
245 void clear() {
Justin Bogner912adfb2018-10-22 19:51:31 +0000246 Copies.clear();
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000247 }
248};
Matthias Braune39ff702016-02-26 03:18:50 +0000249
Justin Bogner927b75d2018-09-21 00:08:33 +0000250class MachineCopyPropagation : public MachineFunctionPass {
251 const TargetRegisterInfo *TRI;
252 const TargetInstrInfo *TII;
253 const MachineRegisterInfo *MRI;
Andrew Trick9e761992012-02-08 21:22:43 +0000254
Justin Bogner927b75d2018-09-21 00:08:33 +0000255public:
256 static char ID; // Pass identification, replacement for typeid
Eugene Zelenko900b6332017-08-29 22:32:07 +0000257
Justin Bogner927b75d2018-09-21 00:08:33 +0000258 MachineCopyPropagation() : MachineFunctionPass(ID) {
259 initializeMachineCopyPropagationPass(*PassRegistry::getPassRegistry());
260 }
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000261
Justin Bogner927b75d2018-09-21 00:08:33 +0000262 void getAnalysisUsage(AnalysisUsage &AU) const override {
263 AU.setPreservesCFG();
264 MachineFunctionPass::getAnalysisUsage(AU);
265 }
Matt Arsenault8f4d43a2016-06-02 00:04:26 +0000266
Justin Bogner927b75d2018-09-21 00:08:33 +0000267 bool runOnMachineFunction(MachineFunction &MF) override;
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000268
Justin Bogner927b75d2018-09-21 00:08:33 +0000269 MachineFunctionProperties getRequiredProperties() const override {
270 return MachineFunctionProperties().set(
271 MachineFunctionProperties::Property::NoVRegs);
272 }
Derek Schuffad154c82016-03-28 17:05:30 +0000273
Justin Bogner927b75d2018-09-21 00:08:33 +0000274private:
Jeremy Morse90c27942019-08-14 12:20:02 +0000275 typedef enum { DebugUse = false, RegularUse = true } DebugType;
276
Justin Bogner927b75d2018-09-21 00:08:33 +0000277 void ClobberRegister(unsigned Reg);
Jeremy Morse90c27942019-08-14 12:20:02 +0000278 void ReadRegister(unsigned Reg, MachineInstr &Reader,
279 DebugType DT);
Kai Luob200c512019-12-05 14:01:00 +0800280 void ForwardCopyPropagateBlock(MachineBasicBlock &MBB);
281 void BackwardCopyPropagateBlock(MachineBasicBlock &MBB);
Justin Bogner927b75d2018-09-21 00:08:33 +0000282 bool eraseIfRedundant(MachineInstr &Copy, unsigned Src, unsigned Def);
283 void forwardUses(MachineInstr &MI);
Kai Luob200c512019-12-05 14:01:00 +0800284 void propagateDefs(MachineInstr &MI);
Justin Bogner927b75d2018-09-21 00:08:33 +0000285 bool isForwardableRegClassCopy(const MachineInstr &Copy,
286 const MachineInstr &UseI, unsigned UseIdx);
Kai Luob200c512019-12-05 14:01:00 +0800287 bool isBackwardPropagatableRegClassCopy(const MachineInstr &Copy,
288 const MachineInstr &UseI,
289 unsigned UseIdx);
Justin Bogner927b75d2018-09-21 00:08:33 +0000290 bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use);
Simon Wallis6a05c6b2020-07-29 16:17:47 +0100291 bool hasOverlappingMultipleDef(const MachineInstr &MI,
292 const MachineOperand &MODef, Register Def);
Matthias Braunbd18d752016-02-20 03:56:39 +0000293
Justin Bogner927b75d2018-09-21 00:08:33 +0000294 /// Candidates for deletion.
295 SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
Eugene Zelenko900b6332017-08-29 22:32:07 +0000296
Jeremy Morse90c27942019-08-14 12:20:02 +0000297 /// Multimap tracking debug users in current BB
298 DenseMap<MachineInstr*, SmallVector<MachineInstr*, 2>> CopyDbgUsers;
299
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000300 CopyTracker Tracker;
Eugene Zelenko900b6332017-08-29 22:32:07 +0000301
Justin Bogner927b75d2018-09-21 00:08:33 +0000302 bool Changed;
303};
Eugene Zelenko900b6332017-08-29 22:32:07 +0000304
305} // end anonymous namespace
306
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000307char MachineCopyPropagation::ID = 0;
Eugene Zelenko900b6332017-08-29 22:32:07 +0000308
Andrew Trick1fa5bcb2012-02-08 21:23:13 +0000309char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID;
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000310
Matthias Braun1527baa2017-05-25 21:26:32 +0000311INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE,
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000312 "Machine Copy Propagation Pass", false, false)
313
Jeremy Morse90c27942019-08-14 12:20:02 +0000314void MachineCopyPropagation::ReadRegister(unsigned Reg, MachineInstr &Reader,
315 DebugType DT) {
Matthias Braun82e7f4d2017-02-04 02:27:20 +0000316 // If 'Reg' is defined by a copy, the copy is no longer a candidate
Jeremy Morse90c27942019-08-14 12:20:02 +0000317 // for elimination. If a copy is "read" by a debug user, record the user
318 // for propagation.
Justin Bogner912adfb2018-10-22 19:51:31 +0000319 for (MCRegUnitIterator RUI(Reg, TRI); RUI.isValid(); ++RUI) {
320 if (MachineInstr *Copy = Tracker.findCopyForUnit(*RUI, *TRI)) {
Jeremy Morse90c27942019-08-14 12:20:02 +0000321 if (DT == RegularUse) {
322 LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; Copy->dump());
323 MaybeDeadCopies.remove(Copy);
324 } else {
325 CopyDbgUsers[Copy].push_back(&Reader);
326 }
Matthias Braun82e7f4d2017-02-04 02:27:20 +0000327 }
328 }
329}
330
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000331/// Return true if \p PreviousCopy did copy register \p Src to register \p Def.
332/// This fact may have been obscured by sub register usage or may not be true at
333/// all even though Src and Def are subregisters of the registers used in
334/// PreviousCopy. e.g.
335/// isNopCopy("ecx = COPY eax", AX, CX) == true
336/// isNopCopy("ecx = COPY eax", AH, CL) == false
337static bool isNopCopy(const MachineInstr &PreviousCopy, unsigned Src,
338 unsigned Def, const TargetRegisterInfo *TRI) {
Daniel Sanders0c476112019-08-15 19:22:08 +0000339 Register PreviousSrc = PreviousCopy.getOperand(1).getReg();
340 Register PreviousDef = PreviousCopy.getOperand(0).getReg();
Craig Topper4783e2c2020-09-01 12:14:32 -0700341 if (Src == PreviousSrc && Def == PreviousDef)
Evan Cheng63618f92012-02-20 23:28:17 +0000342 return true;
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000343 if (!TRI->isSubRegister(PreviousSrc, Src))
344 return false;
345 unsigned SubIdx = TRI->getSubRegIndex(PreviousSrc, Src);
346 return SubIdx == TRI->getSubRegIndex(PreviousDef, Def);
347}
Evan Cheng63618f92012-02-20 23:28:17 +0000348
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000349/// Remove instruction \p Copy if there exists a previous copy that copies the
350/// register \p Src to the register \p Def; This may happen indirectly by
351/// copying the super registers.
352bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src,
353 unsigned Def) {
354 // Avoid eliminating a copy from/to a reserved registers as we cannot predict
355 // the value (Example: The sparc zero register is writable but stays zero).
356 if (MRI->isReserved(Src) || MRI->isReserved(Def))
357 return false;
358
359 // Search for an existing copy.
Justin Bogner912adfb2018-10-22 19:51:31 +0000360 MachineInstr *PrevCopy = Tracker.findAvailCopy(Copy, Def, *TRI);
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000361 if (!PrevCopy)
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000362 return false;
363
364 // Check that the existing copy uses the correct sub registers.
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000365 if (PrevCopy->getOperand(0).isDead())
Alexander Timofeev28da0672017-11-10 12:21:10 +0000366 return false;
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000367 if (!isNopCopy(*PrevCopy, Src, Def, TRI))
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000368 return false;
369
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000370 LLVM_DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; Copy.dump());
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000371
372 // Copy was redundantly redefining either Src or Def. Remove earlier kill
373 // flags between Copy and PrevCopy because the value will be reused now.
374 assert(Copy.isCopy());
Daniel Sanders0c476112019-08-15 19:22:08 +0000375 Register CopyDef = Copy.getOperand(0).getReg();
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000376 assert(CopyDef == Src || CopyDef == Def);
377 for (MachineInstr &MI :
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000378 make_range(PrevCopy->getIterator(), Copy.getIterator()))
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000379 MI.clearRegisterKills(CopyDef, TRI);
380
381 Copy.eraseFromParent();
382 Changed = true;
383 ++NumDeletes;
384 return true;
Evan Cheng63618f92012-02-20 23:28:17 +0000385}
386
Kai Luob200c512019-12-05 14:01:00 +0800387bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy(
388 const MachineInstr &Copy, const MachineInstr &UseI, unsigned UseIdx) {
389 Register Def = Copy.getOperand(0).getReg();
390
391 if (const TargetRegisterClass *URC =
392 UseI.getRegClassConstraint(UseIdx, TII, TRI))
393 return URC->contains(Def);
394
395 // We don't process further if UseI is a COPY, since forward copy propagation
396 // should handle that.
397 return false;
398}
399
Geoff Berrya2b90112018-02-27 16:59:10 +0000400/// Decide whether we should forward the source of \param Copy to its use in
401/// \param UseI based on the physical register class constraints of the opcode
402/// and avoiding introducing more cross-class COPYs.
403bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy,
404 const MachineInstr &UseI,
405 unsigned UseIdx) {
406
Daniel Sanders0c476112019-08-15 19:22:08 +0000407 Register CopySrcReg = Copy.getOperand(1).getReg();
Geoff Berrya2b90112018-02-27 16:59:10 +0000408
409 // If the new register meets the opcode register constraints, then allow
410 // forwarding.
411 if (const TargetRegisterClass *URC =
412 UseI.getRegClassConstraint(UseIdx, TII, TRI))
413 return URC->contains(CopySrcReg);
414
415 if (!UseI.isCopy())
416 return false;
417
418 /// COPYs don't have register class constraints, so if the user instruction
419 /// is a COPY, we just try to avoid introducing additional cross-class
420 /// COPYs. For example:
421 ///
422 /// RegClassA = COPY RegClassB // Copy parameter
423 /// ...
424 /// RegClassB = COPY RegClassA // UseI parameter
425 ///
426 /// which after forwarding becomes
427 ///
428 /// RegClassA = COPY RegClassB
429 /// ...
430 /// RegClassB = COPY RegClassB
431 ///
432 /// so we have reduced the number of cross-class COPYs and potentially
433 /// introduced a nop COPY that can be removed.
434 const TargetRegisterClass *UseDstRC =
435 TRI->getMinimalPhysRegClass(UseI.getOperand(0).getReg());
436
437 const TargetRegisterClass *SuperRC = UseDstRC;
438 for (TargetRegisterClass::sc_iterator SuperRCI = UseDstRC->getSuperClasses();
439 SuperRC; SuperRC = *SuperRCI++)
440 if (SuperRC->contains(CopySrcReg))
441 return true;
442
443 return false;
444}
445
446/// Check that \p MI does not have implicit uses that overlap with it's \p Use
447/// operand (the register being replaced), since these can sometimes be
448/// implicitly tied to other operands. For example, on AMDGPU:
449///
450/// V_MOVRELS_B32_e32 %VGPR2, %M0<imp-use>, %EXEC<imp-use>, %VGPR2_VGPR3_VGPR4_VGPR5<imp-use>
451///
452/// the %VGPR2 is implicitly tied to the larger reg operand, but we have no
453/// way of knowing we need to update the latter when updating the former.
454bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI,
455 const MachineOperand &Use) {
456 for (const MachineOperand &MIUse : MI.uses())
457 if (&MIUse != &Use && MIUse.isReg() && MIUse.isImplicit() &&
458 MIUse.isUse() && TRI->regsOverlap(Use.getReg(), MIUse.getReg()))
459 return true;
460
461 return false;
462}
463
Simon Wallis6a05c6b2020-07-29 16:17:47 +0100464/// For an MI that has multiple definitions, check whether \p MI has
465/// a definition that overlaps with another of its definitions.
466/// For example, on ARM: umull r9, r9, lr, r0
467/// The umull instruction is unpredictable unless RdHi and RdLo are different.
468bool MachineCopyPropagation::hasOverlappingMultipleDef(
469 const MachineInstr &MI, const MachineOperand &MODef, Register Def) {
470 for (const MachineOperand &MIDef : MI.defs()) {
471 if ((&MIDef != &MODef) && MIDef.isReg() &&
472 TRI->regsOverlap(Def, MIDef.getReg()))
473 return true;
474 }
475
476 return false;
477}
478
Geoff Berrya2b90112018-02-27 16:59:10 +0000479/// Look for available copies whose destination register is used by \p MI and
480/// replace the use in \p MI with the copy's source register.
481void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
Justin Bogner912adfb2018-10-22 19:51:31 +0000482 if (!Tracker.hasAnyCopies())
Geoff Berrya2b90112018-02-27 16:59:10 +0000483 return;
484
485 // Look for non-tied explicit vreg uses that have an active COPY
486 // instruction that defines the physical register allocated to them.
487 // Replace the vreg with the source of the active COPY.
488 for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx < OpEnd;
489 ++OpIdx) {
490 MachineOperand &MOUse = MI.getOperand(OpIdx);
491 // Don't forward into undef use operands since doing so can cause problems
492 // with the machine verifier, since it doesn't treat undef reads as reads,
493 // so we can end up with a live range that ends on an undef read, leading to
494 // an error that the live range doesn't end on a read of the live range
495 // register.
496 if (!MOUse.isReg() || MOUse.isTied() || MOUse.isUndef() || MOUse.isDef() ||
497 MOUse.isImplicit())
498 continue;
499
500 if (!MOUse.getReg())
501 continue;
502
503 // Check that the register is marked 'renamable' so we know it is safe to
504 // rename it without violating any constraints that aren't expressed in the
505 // IR (e.g. ABI or opcode requirements).
506 if (!MOUse.isRenamable())
507 continue;
508
Justin Bogner912adfb2018-10-22 19:51:31 +0000509 MachineInstr *Copy = Tracker.findAvailCopy(MI, MOUse.getReg(), *TRI);
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000510 if (!Copy)
Geoff Berrya2b90112018-02-27 16:59:10 +0000511 continue;
512
Daniel Sanders0c476112019-08-15 19:22:08 +0000513 Register CopyDstReg = Copy->getOperand(0).getReg();
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000514 const MachineOperand &CopySrc = Copy->getOperand(1);
Daniel Sanders0c476112019-08-15 19:22:08 +0000515 Register CopySrcReg = CopySrc.getReg();
Geoff Berrya2b90112018-02-27 16:59:10 +0000516
517 // FIXME: Don't handle partial uses of wider COPYs yet.
518 if (MOUse.getReg() != CopyDstReg) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000519 LLVM_DEBUG(
520 dbgs() << "MCP: FIXME! Not forwarding COPY to sub-register use:\n "
521 << MI);
Geoff Berrya2b90112018-02-27 16:59:10 +0000522 continue;
523 }
524
525 // Don't forward COPYs of reserved regs unless they are constant.
526 if (MRI->isReserved(CopySrcReg) && !MRI->isConstantPhysReg(CopySrcReg))
527 continue;
528
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000529 if (!isForwardableRegClassCopy(*Copy, MI, OpIdx))
Geoff Berrya2b90112018-02-27 16:59:10 +0000530 continue;
531
532 if (hasImplicitOverlap(MI, MOUse))
533 continue;
534
Tim Renouf07ebd742019-11-11 11:06:09 +0000535 // Check that the instruction is not a copy that partially overwrites the
536 // original copy source that we are about to use. The tracker mechanism
537 // cannot cope with that.
538 if (MI.isCopy() && MI.modifiesRegister(CopySrcReg, TRI) &&
539 !MI.definesRegister(CopySrcReg)) {
540 LLVM_DEBUG(dbgs() << "MCP: Copy source overlap with dest in " << MI);
541 continue;
542 }
543
Geoff Berrya2b90112018-02-27 16:59:10 +0000544 if (!DebugCounter::shouldExecute(FwdCounter)) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000545 LLVM_DEBUG(dbgs() << "MCP: Skipping forwarding due to debug counter:\n "
546 << MI);
Geoff Berrya2b90112018-02-27 16:59:10 +0000547 continue;
548 }
549
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000550 LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MOUse.getReg(), TRI)
551 << "\n with " << printReg(CopySrcReg, TRI)
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000552 << "\n in " << MI << " from " << *Copy);
Geoff Berrya2b90112018-02-27 16:59:10 +0000553
554 MOUse.setReg(CopySrcReg);
555 if (!CopySrc.isRenamable())
556 MOUse.setIsRenamable(false);
557
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000558 LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
Geoff Berrya2b90112018-02-27 16:59:10 +0000559
560 // Clear kill markers that may have been invalidated.
561 for (MachineInstr &KMI :
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000562 make_range(Copy->getIterator(), std::next(MI.getIterator())))
Geoff Berrya2b90112018-02-27 16:59:10 +0000563 KMI.clearRegisterKills(CopySrcReg, TRI);
564
565 ++NumCopyForwards;
566 Changed = true;
567 }
568}
569
Kai Luob200c512019-12-05 14:01:00 +0800570void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
571 LLVM_DEBUG(dbgs() << "MCP: ForwardCopyPropagateBlock " << MBB.getName()
572 << "\n");
James Molloyd787d3e2014-01-22 09:12:27 +0000573
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000574 for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end(); I != E; ) {
575 MachineInstr *MI = &*I;
576 ++I;
577
Eli Friedman208fe672018-03-30 00:56:03 +0000578 // Analyze copies (which don't overlap themselves).
579 if (MI->isCopy() && !TRI->regsOverlap(MI->getOperand(0).getReg(),
580 MI->getOperand(1).getReg())) {
Daniel Sanders0c476112019-08-15 19:22:08 +0000581 Register Def = MI->getOperand(0).getReg();
582 Register Src = MI->getOperand(1).getReg();
Geoff Berryfabedba2017-10-03 16:59:13 +0000583
Daniel Sanders2bea69b2019-08-01 23:27:28 +0000584 assert(!Register::isVirtualRegister(Def) &&
585 !Register::isVirtualRegister(Src) &&
Geoff Berryfabedba2017-10-03 16:59:13 +0000586 "MachineCopyPropagation should be run after register allocation!");
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000587
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000588 // The two copies cancel out and the source of the first copy
589 // hasn't been overridden, eliminate the second one. e.g.
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000590 // %ecx = COPY %eax
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000591 // ... nothing clobbered eax.
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000592 // %eax = COPY %ecx
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000593 // =>
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000594 // %ecx = COPY %eax
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000595 //
596 // or
597 //
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000598 // %ecx = COPY %eax
Francis Visoiu Mistrih9d7bb0c2017-11-28 17:15:09 +0000599 // ... nothing clobbered eax.
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000600 // %ecx = COPY %eax
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000601 // =>
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000602 // %ecx = COPY %eax
Geoff Berryfabedba2017-10-03 16:59:13 +0000603 if (eraseIfRedundant(*MI, Def, Src) || eraseIfRedundant(*MI, Src, Def))
604 continue;
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000605
Geoff Berrya2b90112018-02-27 16:59:10 +0000606 forwardUses(*MI);
607
608 // Src may have been changed by forwardUses()
609 Src = MI->getOperand(1).getReg();
610
Jun Bum Lim59df5e82016-02-03 15:56:27 +0000611 // If Src is defined by a previous copy, the previous copy cannot be
612 // eliminated.
Jeremy Morse90c27942019-08-14 12:20:02 +0000613 ReadRegister(Src, *MI, RegularUse);
Matthias Braun82e7f4d2017-02-04 02:27:20 +0000614 for (const MachineOperand &MO : MI->implicit_operands()) {
615 if (!MO.isReg() || !MO.readsReg())
616 continue;
Daniel Sanders0c476112019-08-15 19:22:08 +0000617 Register Reg = MO.getReg();
Matthias Braun82e7f4d2017-02-04 02:27:20 +0000618 if (!Reg)
619 continue;
Jeremy Morse90c27942019-08-14 12:20:02 +0000620 ReadRegister(Reg, *MI, RegularUse);
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000621 }
622
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000623 LLVM_DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI->dump());
James Molloyd787d3e2014-01-22 09:12:27 +0000624
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000625 // Copy is now a candidate for deletion.
Geoff Berryfabedba2017-10-03 16:59:13 +0000626 if (!MRI->isReserved(Def))
Matthias Braun273575d2016-02-20 03:56:36 +0000627 MaybeDeadCopies.insert(MI);
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000628
Jun Bum Lim59df5e82016-02-03 15:56:27 +0000629 // If 'Def' is previously source of another copy, then this earlier copy's
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000630 // source is no longer available. e.g.
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000631 // %xmm9 = copy %xmm2
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000632 // ...
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000633 // %xmm2 = copy %xmm0
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000634 // ...
Francis Visoiu Mistriha8a83d12017-12-07 10:40:31 +0000635 // %xmm2 = copy %xmm9
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000636 Tracker.clobberRegister(Def, *TRI);
Matthias Braun82e7f4d2017-02-04 02:27:20 +0000637 for (const MachineOperand &MO : MI->implicit_operands()) {
638 if (!MO.isReg() || !MO.isDef())
639 continue;
Daniel Sanders0c476112019-08-15 19:22:08 +0000640 Register Reg = MO.getReg();
Matthias Braun82e7f4d2017-02-04 02:27:20 +0000641 if (!Reg)
642 continue;
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000643 Tracker.clobberRegister(Reg, *TRI);
Matthias Braun82e7f4d2017-02-04 02:27:20 +0000644 }
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000645
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000646 Tracker.trackCopy(MI, *TRI);
Alexander Timofeev9dff31c2017-10-16 16:57:37 +0000647
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000648 continue;
649 }
650
Geoff Berrya2b90112018-02-27 16:59:10 +0000651 // Clobber any earlyclobber regs first.
652 for (const MachineOperand &MO : MI->operands())
653 if (MO.isReg() && MO.isEarlyClobber()) {
Daniel Sanders0c476112019-08-15 19:22:08 +0000654 Register Reg = MO.getReg();
Geoff Berrya2b90112018-02-27 16:59:10 +0000655 // If we have a tied earlyclobber, that means it is also read by this
656 // instruction, so we need to make sure we don't remove it as dead
657 // later.
658 if (MO.isTied())
Jeremy Morse90c27942019-08-14 12:20:02 +0000659 ReadRegister(Reg, *MI, RegularUse);
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000660 Tracker.clobberRegister(Reg, *TRI);
Geoff Berrya2b90112018-02-27 16:59:10 +0000661 }
662
663 forwardUses(*MI);
664
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000665 // Not a copy.
666 SmallVector<unsigned, 2> Defs;
Matthias Braun273575d2016-02-20 03:56:36 +0000667 const MachineOperand *RegMask = nullptr;
668 for (const MachineOperand &MO : MI->operands()) {
Jakob Stoklund Olesen8610a592012-02-08 22:37:35 +0000669 if (MO.isRegMask())
Matthias Braun273575d2016-02-20 03:56:36 +0000670 RegMask = &MO;
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000671 if (!MO.isReg())
672 continue;
Daniel Sanders0c476112019-08-15 19:22:08 +0000673 Register Reg = MO.getReg();
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000674 if (!Reg)
675 continue;
676
Daniel Sanders2bea69b2019-08-01 23:27:28 +0000677 assert(!Register::isVirtualRegister(Reg) &&
Geoff Berryfabedba2017-10-03 16:59:13 +0000678 "MachineCopyPropagation should be run after register allocation!");
679
Geoff Berrya2b90112018-02-27 16:59:10 +0000680 if (MO.isDef() && !MO.isEarlyClobber()) {
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000681 Defs.push_back(Reg);
682 continue;
Jeremy Morse90c27942019-08-14 12:20:02 +0000683 } else if (MO.readsReg())
684 ReadRegister(Reg, *MI, MO.isDebug() ? DebugUse : RegularUse);
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000685 }
686
Jakob Stoklund Olesen8610a592012-02-08 22:37:35 +0000687 // The instruction has a register mask operand which means that it clobbers
Matthias Braune39ff702016-02-26 03:18:50 +0000688 // a large set of registers. Treat clobbered registers the same way as
689 // defined registers.
Matthias Braun273575d2016-02-20 03:56:36 +0000690 if (RegMask) {
Jakob Stoklund Olesen938b4d22012-02-09 00:19:08 +0000691 // Erase any MaybeDeadCopies whose destination register is clobbered.
Jun Bum Lim36c53fe2016-03-25 21:15:35 +0000692 for (SmallSetVector<MachineInstr *, 8>::iterator DI =
693 MaybeDeadCopies.begin();
694 DI != MaybeDeadCopies.end();) {
695 MachineInstr *MaybeDead = *DI;
Daniel Sanders0c476112019-08-15 19:22:08 +0000696 Register Reg = MaybeDead->getOperand(0).getReg();
Matthias Braun273575d2016-02-20 03:56:36 +0000697 assert(!MRI->isReserved(Reg));
Jun Bum Lim36c53fe2016-03-25 21:15:35 +0000698
699 if (!RegMask->clobbersPhysReg(Reg)) {
700 ++DI;
Jakob Stoklund Olesen938b4d22012-02-09 00:19:08 +0000701 continue;
Jun Bum Lim36c53fe2016-03-25 21:15:35 +0000702 }
703
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000704 LLVM_DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: ";
705 MaybeDead->dump());
Jun Bum Lim36c53fe2016-03-25 21:15:35 +0000706
Justin Bognerdb02d3d2018-09-25 04:45:25 +0000707 // Make sure we invalidate any entries in the copy maps before erasing
708 // the instruction.
709 Tracker.clobberRegister(Reg, *TRI);
710
Jun Bum Lim36c53fe2016-03-25 21:15:35 +0000711 // erase() will return the next valid iterator pointing to the next
712 // element after the erased one.
713 DI = MaybeDeadCopies.erase(DI);
Matthias Braun273575d2016-02-20 03:56:36 +0000714 MaybeDead->eraseFromParent();
Jakob Stoklund Olesen938b4d22012-02-09 00:19:08 +0000715 Changed = true;
716 ++NumDeletes;
717 }
Jakob Stoklund Olesen8610a592012-02-08 22:37:35 +0000718 }
719
Matthias Braune39ff702016-02-26 03:18:50 +0000720 // Any previous copy definition or reading the Defs is no longer available.
Matthias Braun9dcd65f2016-02-26 03:18:55 +0000721 for (unsigned Reg : Defs)
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000722 Tracker.clobberRegister(Reg, *TRI);
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000723 }
724
725 // If MBB doesn't have successors, delete the copies whose defs are not used.
726 // If MBB does have successors, then conservative assume the defs are live-out
727 // since we don't want to trust live-in lists.
728 if (MBB.succ_empty()) {
Matthias Braun273575d2016-02-20 03:56:36 +0000729 for (MachineInstr *MaybeDead : MaybeDeadCopies) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000730 LLVM_DEBUG(dbgs() << "MCP: Removing copy due to no live-out succ: ";
731 MaybeDead->dump());
Matthias Braun273575d2016-02-20 03:56:36 +0000732 assert(!MRI->isReserved(MaybeDead->getOperand(0).getReg()));
Carlos Alberto Enciso81d8ef22018-10-01 08:14:44 +0000733
Jeremy Morse90c27942019-08-14 12:20:02 +0000734 // Update matching debug values, if any.
Carlos Alberto Enciso81d8ef22018-10-01 08:14:44 +0000735 assert(MaybeDead->isCopy());
Jeremy Morse90c27942019-08-14 12:20:02 +0000736 unsigned SrcReg = MaybeDead->getOperand(1).getReg();
737 MRI->updateDbgUsersToReg(SrcReg, CopyDbgUsers[MaybeDead]);
Carlos Alberto Enciso81d8ef22018-10-01 08:14:44 +0000738
Matthias Braun273575d2016-02-20 03:56:36 +0000739 MaybeDead->eraseFromParent();
740 Changed = true;
741 ++NumDeletes;
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000742 }
743 }
744
Matthias Braunbd18d752016-02-20 03:56:39 +0000745 MaybeDeadCopies.clear();
Jeremy Morse90c27942019-08-14 12:20:02 +0000746 CopyDbgUsers.clear();
Justin Bogner45b3ddc2018-09-21 00:51:04 +0000747 Tracker.clear();
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000748}
749
Kai Luob200c512019-12-05 14:01:00 +0800750static bool isBackwardPropagatableCopy(MachineInstr &MI,
751 const MachineRegisterInfo &MRI) {
752 assert(MI.isCopy() && "MI is expected to be a COPY");
753 Register Def = MI.getOperand(0).getReg();
754 Register Src = MI.getOperand(1).getReg();
755
756 if (!Def || !Src)
757 return false;
758
759 if (MRI.isReserved(Def) || MRI.isReserved(Src))
760 return false;
761
762 return MI.getOperand(1).isRenamable() && MI.getOperand(1).isKill();
763}
764
765void MachineCopyPropagation::propagateDefs(MachineInstr &MI) {
766 if (!Tracker.hasAnyCopies())
767 return;
768
769 for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx != OpEnd;
770 ++OpIdx) {
771 MachineOperand &MODef = MI.getOperand(OpIdx);
772
773 if (!MODef.isReg() || MODef.isUse())
774 continue;
775
776 // Ignore non-trivial cases.
777 if (MODef.isTied() || MODef.isUndef() || MODef.isImplicit())
778 continue;
779
780 if (!MODef.getReg())
781 continue;
782
783 // We only handle if the register comes from a vreg.
784 if (!MODef.isRenamable())
785 continue;
786
787 MachineInstr *Copy =
788 Tracker.findAvailBackwardCopy(MI, MODef.getReg(), *TRI);
789 if (!Copy)
790 continue;
791
792 Register Def = Copy->getOperand(0).getReg();
793 Register Src = Copy->getOperand(1).getReg();
794
795 if (MODef.getReg() != Src)
796 continue;
797
798 if (!isBackwardPropagatableRegClassCopy(*Copy, MI, OpIdx))
799 continue;
800
801 if (hasImplicitOverlap(MI, MODef))
802 continue;
803
Simon Wallis6a05c6b2020-07-29 16:17:47 +0100804 if (hasOverlappingMultipleDef(MI, MODef, Def))
805 continue;
806
Kai Luob200c512019-12-05 14:01:00 +0800807 LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MODef.getReg(), TRI)
808 << "\n with " << printReg(Def, TRI) << "\n in "
809 << MI << " from " << *Copy);
810
811 MODef.setReg(Def);
812 MODef.setIsRenamable(Copy->getOperand(0).isRenamable());
813
814 LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
815 MaybeDeadCopies.insert(Copy);
816 Changed = true;
Kai Luocd2a73a2019-12-30 16:31:41 +0800817 ++NumCopyBackwardPropagated;
Kai Luob200c512019-12-05 14:01:00 +0800818 }
819}
820
821void MachineCopyPropagation::BackwardCopyPropagateBlock(
822 MachineBasicBlock &MBB) {
823 LLVM_DEBUG(dbgs() << "MCP: BackwardCopyPropagateBlock " << MBB.getName()
824 << "\n");
825
826 for (MachineBasicBlock::reverse_iterator I = MBB.rbegin(), E = MBB.rend();
827 I != E;) {
828 MachineInstr *MI = &*I;
829 ++I;
830
831 // Ignore non-trivial COPYs.
832 if (MI->isCopy() && MI->getNumOperands() == 2 &&
833 !TRI->regsOverlap(MI->getOperand(0).getReg(),
834 MI->getOperand(1).getReg())) {
835
836 Register Def = MI->getOperand(0).getReg();
837 Register Src = MI->getOperand(1).getReg();
838
839 // Unlike forward cp, we don't invoke propagateDefs here,
840 // just let forward cp do COPY-to-COPY propagation.
841 if (isBackwardPropagatableCopy(*MI, *MRI)) {
842 Tracker.invalidateRegister(Src, *TRI);
843 Tracker.invalidateRegister(Def, *TRI);
844 Tracker.trackCopy(MI, *TRI);
845 continue;
846 }
847 }
848
849 // Invalidate any earlyclobber regs first.
850 for (const MachineOperand &MO : MI->operands())
851 if (MO.isReg() && MO.isEarlyClobber()) {
852 Register Reg = MO.getReg();
853 if (!Reg)
854 continue;
855 Tracker.invalidateRegister(Reg, *TRI);
856 }
857
858 propagateDefs(*MI);
859 for (const MachineOperand &MO : MI->operands()) {
860 if (!MO.isReg())
861 continue;
862
863 if (!MO.getReg())
864 continue;
865
866 if (MO.isDef())
867 Tracker.invalidateRegister(MO.getReg(), *TRI);
868
869 if (MO.readsReg())
870 Tracker.invalidateRegister(MO.getReg(), *TRI);
871 }
872 }
873
Kai Luocd2a73a2019-12-30 16:31:41 +0800874 for (auto *Copy : MaybeDeadCopies) {
Kai Luob200c512019-12-05 14:01:00 +0800875 Copy->eraseFromParent();
Kai Luocd2a73a2019-12-30 16:31:41 +0800876 ++NumDeletes;
877 }
Kai Luob200c512019-12-05 14:01:00 +0800878
879 MaybeDeadCopies.clear();
880 CopyDbgUsers.clear();
881 Tracker.clear();
882}
883
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000884bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) {
Matthias Braunf1caa282017-12-15 22:22:58 +0000885 if (skipFunction(MF.getFunction()))
Paul Robinson7c99ec52014-03-31 17:43:35 +0000886 return false;
887
Matthias Braunbd18d752016-02-20 03:56:39 +0000888 Changed = false;
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000889
Eric Christopherfc6de422014-08-05 02:39:49 +0000890 TRI = MF.getSubtarget().getRegisterInfo();
891 TII = MF.getSubtarget().getInstrInfo();
Jakob Stoklund Olesenc30a9af2012-10-15 21:57:41 +0000892 MRI = &MF.getRegInfo();
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000893
Kai Luob200c512019-12-05 14:01:00 +0800894 for (MachineBasicBlock &MBB : MF) {
895 BackwardCopyPropagateBlock(MBB);
896 ForwardCopyPropagateBlock(MBB);
897 }
Evan Cheng00b1a3c2012-01-07 03:02:36 +0000898
899 return Changed;
900}