LLVM 19.0.0git
MachineCopyPropagation.cpp
Go to the documentation of this file.
1//===- MachineCopyPropagation.cpp - Machine Copy Propagation Pass ---------===//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8//
9// This is an extremely simple MachineInstr-level copy propagation pass.
10//
11// 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//
40// 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//
49//===----------------------------------------------------------------------===//
50
51#include "llvm/ADT/DenseMap.h"
52#include "llvm/ADT/STLExtras.h"
53#include "llvm/ADT/SetVector.h"
54#include "llvm/ADT/SmallSet.h"
56#include "llvm/ADT/Statistic.h"
69#include "llvm/Pass.h"
70#include "llvm/Support/Debug.h"
73#include <cassert>
74#include <iterator>
75
76using namespace llvm;
77
78#define DEBUG_TYPE "machine-cp"
79
80STATISTIC(NumDeletes, "Number of dead copies deleted");
81STATISTIC(NumCopyForwards, "Number of copy uses forwarded");
82STATISTIC(NumCopyBackwardPropagated, "Number of copy defs backward propagated");
83STATISTIC(SpillageChainsLength, "Length of spillage chains");
84STATISTIC(NumSpillageChains, "Number of spillage chains");
85DEBUG_COUNTER(FwdCounter, "machine-cp-fwd",
86 "Controls which register COPYs are forwarded");
87
88static cl::opt<bool> MCPUseCopyInstr("mcp-use-is-copy-instr", cl::init(false),
91 EnableSpillageCopyElimination("enable-spill-copy-elim", cl::Hidden);
92
93namespace {
94
95static std::optional<DestSourcePair> isCopyInstr(const MachineInstr &MI,
96 const TargetInstrInfo &TII,
97 bool UseCopyInstr) {
98 if (UseCopyInstr)
99 return TII.isCopyInstr(MI);
100
101 if (MI.isCopy())
102 return std::optional<DestSourcePair>(
103 DestSourcePair{MI.getOperand(0), MI.getOperand(1)});
104
105 return std::nullopt;
106}
107
108class CopyTracker {
109 struct CopyInfo {
110 MachineInstr *MI, *LastSeenUseInCopy;
112 bool Avail;
113 };
114
116
117public:
118 /// Mark all of the given registers and their subregisters as unavailable for
119 /// copying.
120 void markRegsUnavailable(ArrayRef<MCRegister> Regs,
121 const TargetRegisterInfo &TRI) {
122 for (MCRegister Reg : Regs) {
123 // Source of copy is no longer available for propagation.
124 for (MCRegUnit Unit : TRI.regunits(Reg)) {
125 auto CI = Copies.find(Unit);
126 if (CI != Copies.end())
127 CI->second.Avail = false;
128 }
129 }
130 }
131
132 /// Remove register from copy maps.
133 void invalidateRegister(MCRegister Reg, const TargetRegisterInfo &TRI,
134 const TargetInstrInfo &TII, bool UseCopyInstr) {
135 // Since Reg might be a subreg of some registers, only invalidate Reg is not
136 // enough. We have to find the COPY defines Reg or registers defined by Reg
137 // and invalidate all of them. Similarly, we must invalidate all of the
138 // the subregisters used in the source of the COPY.
139 SmallSet<MCRegUnit, 8> RegUnitsToInvalidate;
140 auto InvalidateCopy = [&](MachineInstr *MI) {
141 std::optional<DestSourcePair> CopyOperands =
142 isCopyInstr(*MI, TII, UseCopyInstr);
143 assert(CopyOperands && "Expect copy");
144
145 auto Dest = TRI.regunits(CopyOperands->Destination->getReg().asMCReg());
146 auto Src = TRI.regunits(CopyOperands->Source->getReg().asMCReg());
147 RegUnitsToInvalidate.insert(Dest.begin(), Dest.end());
148 RegUnitsToInvalidate.insert(Src.begin(), Src.end());
149 };
150
151 for (MCRegUnit Unit : TRI.regunits(Reg)) {
152 auto I = Copies.find(Unit);
153 if (I != Copies.end()) {
154 if (MachineInstr *MI = I->second.MI)
155 InvalidateCopy(MI);
156 if (MachineInstr *MI = I->second.LastSeenUseInCopy)
157 InvalidateCopy(MI);
158 }
159 }
160 for (MCRegUnit Unit : RegUnitsToInvalidate)
161 Copies.erase(Unit);
162 }
163
164 /// Clobber a single register, removing it from the tracker's copy maps.
165 void clobberRegister(MCRegister Reg, const TargetRegisterInfo &TRI,
166 const TargetInstrInfo &TII, bool UseCopyInstr) {
167 for (MCRegUnit Unit : TRI.regunits(Reg)) {
168 auto I = Copies.find(Unit);
169 if (I != Copies.end()) {
170 // When we clobber the source of a copy, we need to clobber everything
171 // it defined.
172 markRegsUnavailable(I->second.DefRegs, TRI);
173 // When we clobber the destination of a copy, we need to clobber the
174 // whole register it defined.
175 if (MachineInstr *MI = I->second.MI) {
176 std::optional<DestSourcePair> CopyOperands =
177 isCopyInstr(*MI, TII, UseCopyInstr);
178
179 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
180 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
181
182 markRegsUnavailable(Def, TRI);
183
184 // Since we clobber the destination of a copy, the semantic of Src's
185 // "DefRegs" to contain Def is no longer effectual. We will also need
186 // to remove the record from the copy maps that indicates Src defined
187 // Def. Failing to do so might cause the target to miss some
188 // opportunities to further eliminate redundant copy instructions.
189 // Consider the following sequence during the
190 // ForwardCopyPropagateBlock procedure:
191 // L1: r0 = COPY r9 <- TrackMI
192 // L2: r0 = COPY r8 <- TrackMI (Remove r9 defined r0 from tracker)
193 // L3: use r0 <- Remove L2 from MaybeDeadCopies
194 // L4: early-clobber r9 <- Clobber r9 (L2 is still valid in tracker)
195 // L5: r0 = COPY r8 <- Remove NopCopy
196 for (MCRegUnit SrcUnit : TRI.regunits(Src)) {
197 auto SrcCopy = Copies.find(SrcUnit);
198 if (SrcCopy != Copies.end() && SrcCopy->second.LastSeenUseInCopy) {
199 // If SrcCopy defines multiple values, we only need
200 // to erase the record for Def in DefRegs.
201 for (auto itr = SrcCopy->second.DefRegs.begin();
202 itr != SrcCopy->second.DefRegs.end(); itr++) {
203 if (*itr == Def) {
204 SrcCopy->second.DefRegs.erase(itr);
205 // If DefReg becomes empty after removal, we can remove the
206 // SrcCopy from the tracker's copy maps. We only remove those
207 // entries solely record the Def is defined by Src. If an
208 // entry also contains the definition record of other Def'
209 // registers, it cannot be cleared.
210 if (SrcCopy->second.DefRegs.empty() && !SrcCopy->second.MI) {
211 Copies.erase(SrcCopy);
212 }
213 break;
214 }
215 }
216 }
217 }
218 }
219 // Now we can erase the copy.
220 Copies.erase(I);
221 }
222 }
223 }
224
225 /// Add this copy's registers into the tracker's copy maps.
226 void trackCopy(MachineInstr *MI, const TargetRegisterInfo &TRI,
227 const TargetInstrInfo &TII, bool UseCopyInstr) {
228 std::optional<DestSourcePair> CopyOperands =
229 isCopyInstr(*MI, TII, UseCopyInstr);
230 assert(CopyOperands && "Tracking non-copy?");
231
232 MCRegister Src = CopyOperands->Source->getReg().asMCReg();
233 MCRegister Def = CopyOperands->Destination->getReg().asMCReg();
234
235 // Remember Def is defined by the copy.
236 for (MCRegUnit Unit : TRI.regunits(Def))
237 Copies[Unit] = {MI, nullptr, {}, true};
238
239 // Remember source that's copied to Def. Once it's clobbered, then
240 // it's no longer available for copy propagation.
241 for (MCRegUnit Unit : TRI.regunits(Src)) {
242 auto I = Copies.insert({Unit, {nullptr, nullptr, {}, false}});
243 auto &Copy = I.first->second;
244 if (!is_contained(Copy.DefRegs, Def))
245 Copy.DefRegs.push_back(Def);
246 Copy.LastSeenUseInCopy = MI;
247 }
248 }
249
250 bool hasAnyCopies() {
251 return !Copies.empty();
252 }
253
254 MachineInstr *findCopyForUnit(MCRegister RegUnit,
255 const TargetRegisterInfo &TRI,
256 bool MustBeAvailable = false) {
257 auto CI = Copies.find(RegUnit);
258 if (CI == Copies.end())
259 return nullptr;
260 if (MustBeAvailable && !CI->second.Avail)
261 return nullptr;
262 return CI->second.MI;
263 }
264
265 MachineInstr *findCopyDefViaUnit(MCRegister RegUnit,
266 const TargetRegisterInfo &TRI) {
267 auto CI = Copies.find(RegUnit);
268 if (CI == Copies.end())
269 return nullptr;
270 if (CI->second.DefRegs.size() != 1)
271 return nullptr;
272 MCRegUnit RU = *TRI.regunits(CI->second.DefRegs[0]).begin();
273 return findCopyForUnit(RU, TRI, true);
274 }
275
276 MachineInstr *findAvailBackwardCopy(MachineInstr &I, MCRegister Reg,
277 const TargetRegisterInfo &TRI,
278 const TargetInstrInfo &TII,
279 bool UseCopyInstr) {
280 MCRegUnit RU = *TRI.regunits(Reg).begin();
281 MachineInstr *AvailCopy = findCopyDefViaUnit(RU, TRI);
282
283 if (!AvailCopy)
284 return nullptr;
285
286 std::optional<DestSourcePair> CopyOperands =
287 isCopyInstr(*AvailCopy, TII, UseCopyInstr);
288 Register AvailSrc = CopyOperands->Source->getReg();
289 Register AvailDef = CopyOperands->Destination->getReg();
290 if (!TRI.isSubRegisterEq(AvailSrc, Reg))
291 return nullptr;
292
293 for (const MachineInstr &MI :
294 make_range(AvailCopy->getReverseIterator(), I.getReverseIterator()))
295 for (const MachineOperand &MO : MI.operands())
296 if (MO.isRegMask())
297 // FIXME: Shall we simultaneously invalidate AvailSrc or AvailDef?
298 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
299 return nullptr;
300
301 return AvailCopy;
302 }
303
304 MachineInstr *findAvailCopy(MachineInstr &DestCopy, MCRegister Reg,
305 const TargetRegisterInfo &TRI,
306 const TargetInstrInfo &TII, bool UseCopyInstr) {
307 // We check the first RegUnit here, since we'll only be interested in the
308 // copy if it copies the entire register anyway.
309 MCRegUnit RU = *TRI.regunits(Reg).begin();
310 MachineInstr *AvailCopy =
311 findCopyForUnit(RU, TRI, /*MustBeAvailable=*/true);
312
313 if (!AvailCopy)
314 return nullptr;
315
316 std::optional<DestSourcePair> CopyOperands =
317 isCopyInstr(*AvailCopy, TII, UseCopyInstr);
318 Register AvailSrc = CopyOperands->Source->getReg();
319 Register AvailDef = CopyOperands->Destination->getReg();
320 if (!TRI.isSubRegisterEq(AvailDef, Reg))
321 return nullptr;
322
323 // Check that the available copy isn't clobbered by any regmasks between
324 // itself and the destination.
325 for (const MachineInstr &MI :
326 make_range(AvailCopy->getIterator(), DestCopy.getIterator()))
327 for (const MachineOperand &MO : MI.operands())
328 if (MO.isRegMask())
329 if (MO.clobbersPhysReg(AvailSrc) || MO.clobbersPhysReg(AvailDef))
330 return nullptr;
331
332 return AvailCopy;
333 }
334
335 // Find last COPY that defines Reg before Current MachineInstr.
336 MachineInstr *findLastSeenDefInCopy(const MachineInstr &Current,
337 MCRegister Reg,
338 const TargetRegisterInfo &TRI,
339 const TargetInstrInfo &TII,
340 bool UseCopyInstr) {
341 MCRegUnit RU = *TRI.regunits(Reg).begin();
342 auto CI = Copies.find(RU);
343 if (CI == Copies.end() || !CI->second.Avail)
344 return nullptr;
345
346 MachineInstr *DefCopy = CI->second.MI;
347 std::optional<DestSourcePair> CopyOperands =
348 isCopyInstr(*DefCopy, TII, UseCopyInstr);
349 Register Def = CopyOperands->Destination->getReg();
350 if (!TRI.isSubRegisterEq(Def, Reg))
351 return nullptr;
352
353 for (const MachineInstr &MI :
354 make_range(static_cast<const MachineInstr *>(DefCopy)->getIterator(),
355 Current.getIterator()))
356 for (const MachineOperand &MO : MI.operands())
357 if (MO.isRegMask())
358 if (MO.clobbersPhysReg(Def)) {
359 LLVM_DEBUG(dbgs() << "MCP: Removed tracking of "
360 << printReg(Def, &TRI) << "\n");
361 return nullptr;
362 }
363
364 return DefCopy;
365 }
366
367 // Find last COPY that uses Reg.
368 MachineInstr *findLastSeenUseInCopy(MCRegister Reg,
369 const TargetRegisterInfo &TRI) {
370 MCRegUnit RU = *TRI.regunits(Reg).begin();
371 auto CI = Copies.find(RU);
372 if (CI == Copies.end())
373 return nullptr;
374 return CI->second.LastSeenUseInCopy;
375 }
376
377 void clear() {
378 Copies.clear();
379 }
380};
381
382class MachineCopyPropagation : public MachineFunctionPass {
383 const TargetRegisterInfo *TRI = nullptr;
384 const TargetInstrInfo *TII = nullptr;
385 const MachineRegisterInfo *MRI = nullptr;
386
387 // Return true if this is a copy instruction and false otherwise.
388 bool UseCopyInstr;
389
390public:
391 static char ID; // Pass identification, replacement for typeid
392
393 MachineCopyPropagation(bool CopyInstr = false)
394 : MachineFunctionPass(ID), UseCopyInstr(CopyInstr || MCPUseCopyInstr) {
396 }
397
398 void getAnalysisUsage(AnalysisUsage &AU) const override {
399 AU.setPreservesCFG();
401 }
402
403 bool runOnMachineFunction(MachineFunction &MF) override;
404
407 MachineFunctionProperties::Property::NoVRegs);
408 }
409
410private:
411 typedef enum { DebugUse = false, RegularUse = true } DebugType;
412
413 void ReadRegister(MCRegister Reg, MachineInstr &Reader, DebugType DT);
414 void readSuccessorLiveIns(const MachineBasicBlock &MBB);
415 void ForwardCopyPropagateBlock(MachineBasicBlock &MBB);
416 void BackwardCopyPropagateBlock(MachineBasicBlock &MBB);
417 void EliminateSpillageCopies(MachineBasicBlock &MBB);
418 bool eraseIfRedundant(MachineInstr &Copy, MCRegister Src, MCRegister Def);
419 void forwardUses(MachineInstr &MI);
420 void propagateDefs(MachineInstr &MI);
421 bool isForwardableRegClassCopy(const MachineInstr &Copy,
422 const MachineInstr &UseI, unsigned UseIdx);
423 bool isBackwardPropagatableRegClassCopy(const MachineInstr &Copy,
424 const MachineInstr &UseI,
425 unsigned UseIdx);
426 bool hasImplicitOverlap(const MachineInstr &MI, const MachineOperand &Use);
427 bool hasOverlappingMultipleDef(const MachineInstr &MI,
428 const MachineOperand &MODef, Register Def);
429
430 /// Candidates for deletion.
431 SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
432
433 /// Multimap tracking debug users in current BB
435
436 CopyTracker Tracker;
437
438 bool Changed = false;
439};
440
441} // end anonymous namespace
442
443char MachineCopyPropagation::ID = 0;
444
445char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID;
446
447INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE,
448 "Machine Copy Propagation Pass", false, false)
449
450void MachineCopyPropagation::ReadRegister(MCRegister Reg, MachineInstr &Reader,
451 DebugType DT) {
452 // If 'Reg' is defined by a copy, the copy is no longer a candidate
453 // for elimination. If a copy is "read" by a debug user, record the user
454 // for propagation.
455 for (MCRegUnit Unit : TRI->regunits(Reg)) {
456 if (MachineInstr *Copy = Tracker.findCopyForUnit(Unit, *TRI)) {
457 if (DT == RegularUse) {
458 LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; Copy->dump());
459 MaybeDeadCopies.remove(Copy);
460 } else {
461 CopyDbgUsers[Copy].insert(&Reader);
462 }
463 }
464 }
465}
466
467void MachineCopyPropagation::readSuccessorLiveIns(
468 const MachineBasicBlock &MBB) {
469 if (MaybeDeadCopies.empty())
470 return;
471
472 // If a copy result is livein to a successor, it is not dead.
473 for (const MachineBasicBlock *Succ : MBB.successors()) {
474 for (const auto &LI : Succ->liveins()) {
475 for (MCRegUnit Unit : TRI->regunits(LI.PhysReg)) {
476 if (MachineInstr *Copy = Tracker.findCopyForUnit(Unit, *TRI))
477 MaybeDeadCopies.remove(Copy);
478 }
479 }
480 }
481}
482
483/// Return true if \p PreviousCopy did copy register \p Src to register \p Def.
484/// This fact may have been obscured by sub register usage or may not be true at
485/// all even though Src and Def are subregisters of the registers used in
486/// PreviousCopy. e.g.
487/// isNopCopy("ecx = COPY eax", AX, CX) == true
488/// isNopCopy("ecx = COPY eax", AH, CL) == false
489static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src,
491 const TargetInstrInfo *TII, bool UseCopyInstr) {
492
493 std::optional<DestSourcePair> CopyOperands =
494 isCopyInstr(PreviousCopy, *TII, UseCopyInstr);
495 MCRegister PreviousSrc = CopyOperands->Source->getReg().asMCReg();
496 MCRegister PreviousDef = CopyOperands->Destination->getReg().asMCReg();
497 if (Src == PreviousSrc && Def == PreviousDef)
498 return true;
499 if (!TRI->isSubRegister(PreviousSrc, Src))
500 return false;
501 unsigned SubIdx = TRI->getSubRegIndex(PreviousSrc, Src);
502 return SubIdx == TRI->getSubRegIndex(PreviousDef, Def);
503}
504
505/// Remove instruction \p Copy if there exists a previous copy that copies the
506/// register \p Src to the register \p Def; This may happen indirectly by
507/// copying the super registers.
508bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy,
509 MCRegister Src, MCRegister Def) {
510 // Avoid eliminating a copy from/to a reserved registers as we cannot predict
511 // the value (Example: The sparc zero register is writable but stays zero).
512 if (MRI->isReserved(Src) || MRI->isReserved(Def))
513 return false;
514
515 // Search for an existing copy.
516 MachineInstr *PrevCopy =
517 Tracker.findAvailCopy(Copy, Def, *TRI, *TII, UseCopyInstr);
518 if (!PrevCopy)
519 return false;
520
521 auto PrevCopyOperands = isCopyInstr(*PrevCopy, *TII, UseCopyInstr);
522 // Check that the existing copy uses the correct sub registers.
523 if (PrevCopyOperands->Destination->isDead())
524 return false;
525 if (!isNopCopy(*PrevCopy, Src, Def, TRI, TII, UseCopyInstr))
526 return false;
527
528 LLVM_DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; Copy.dump());
529
530 // Copy was redundantly redefining either Src or Def. Remove earlier kill
531 // flags between Copy and PrevCopy because the value will be reused now.
532 std::optional<DestSourcePair> CopyOperands =
533 isCopyInstr(Copy, *TII, UseCopyInstr);
534 assert(CopyOperands);
535
536 Register CopyDef = CopyOperands->Destination->getReg();
537 assert(CopyDef == Src || CopyDef == Def);
538 for (MachineInstr &MI :
539 make_range(PrevCopy->getIterator(), Copy.getIterator()))
540 MI.clearRegisterKills(CopyDef, TRI);
541
542 // Clear undef flag from remaining copy if needed.
543 if (!CopyOperands->Source->isUndef()) {
544 PrevCopy->getOperand(PrevCopyOperands->Source->getOperandNo())
545 .setIsUndef(false);
546 }
547
548 Copy.eraseFromParent();
549 Changed = true;
550 ++NumDeletes;
551 return true;
552}
553
554bool MachineCopyPropagation::isBackwardPropagatableRegClassCopy(
555 const MachineInstr &Copy, const MachineInstr &UseI, unsigned UseIdx) {
556 std::optional<DestSourcePair> CopyOperands =
557 isCopyInstr(Copy, *TII, UseCopyInstr);
558 Register Def = CopyOperands->Destination->getReg();
559
560 if (const TargetRegisterClass *URC =
561 UseI.getRegClassConstraint(UseIdx, TII, TRI))
562 return URC->contains(Def);
563
564 // We don't process further if UseI is a COPY, since forward copy propagation
565 // should handle that.
566 return false;
567}
568
569/// Decide whether we should forward the source of \param Copy to its use in
570/// \param UseI based on the physical register class constraints of the opcode
571/// and avoiding introducing more cross-class COPYs.
572bool MachineCopyPropagation::isForwardableRegClassCopy(const MachineInstr &Copy,
573 const MachineInstr &UseI,
574 unsigned UseIdx) {
575 std::optional<DestSourcePair> CopyOperands =
576 isCopyInstr(Copy, *TII, UseCopyInstr);
577 Register CopySrcReg = CopyOperands->Source->getReg();
578
579 // If the new register meets the opcode register constraints, then allow
580 // forwarding.
581 if (const TargetRegisterClass *URC =
582 UseI.getRegClassConstraint(UseIdx, TII, TRI))
583 return URC->contains(CopySrcReg);
584
585 auto UseICopyOperands = isCopyInstr(UseI, *TII, UseCopyInstr);
586 if (!UseICopyOperands)
587 return false;
588
589 /// COPYs don't have register class constraints, so if the user instruction
590 /// is a COPY, we just try to avoid introducing additional cross-class
591 /// COPYs. For example:
592 ///
593 /// RegClassA = COPY RegClassB // Copy parameter
594 /// ...
595 /// RegClassB = COPY RegClassA // UseI parameter
596 ///
597 /// which after forwarding becomes
598 ///
599 /// RegClassA = COPY RegClassB
600 /// ...
601 /// RegClassB = COPY RegClassB
602 ///
603 /// so we have reduced the number of cross-class COPYs and potentially
604 /// introduced a nop COPY that can be removed.
605
606 // Allow forwarding if src and dst belong to any common class, so long as they
607 // don't belong to any (possibly smaller) common class that requires copies to
608 // go via a different class.
609 Register UseDstReg = UseICopyOperands->Destination->getReg();
610 bool Found = false;
611 bool IsCrossClass = false;
612 for (const TargetRegisterClass *RC : TRI->regclasses()) {
613 if (RC->contains(CopySrcReg) && RC->contains(UseDstReg)) {
614 Found = true;
615 if (TRI->getCrossCopyRegClass(RC) != RC) {
616 IsCrossClass = true;
617 break;
618 }
619 }
620 }
621 if (!Found)
622 return false;
623 if (!IsCrossClass)
624 return true;
625 // The forwarded copy would be cross-class. Only do this if the original copy
626 // was also cross-class.
627 Register CopyDstReg = CopyOperands->Destination->getReg();
628 for (const TargetRegisterClass *RC : TRI->regclasses()) {
629 if (RC->contains(CopySrcReg) && RC->contains(CopyDstReg) &&
630 TRI->getCrossCopyRegClass(RC) != RC)
631 return true;
632 }
633 return false;
634}
635
636/// Check that \p MI does not have implicit uses that overlap with it's \p Use
637/// operand (the register being replaced), since these can sometimes be
638/// implicitly tied to other operands. For example, on AMDGPU:
639///
640/// V_MOVRELS_B32_e32 %VGPR2, %M0<imp-use>, %EXEC<imp-use>, %VGPR2_VGPR3_VGPR4_VGPR5<imp-use>
641///
642/// the %VGPR2 is implicitly tied to the larger reg operand, but we have no
643/// way of knowing we need to update the latter when updating the former.
644bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI,
645 const MachineOperand &Use) {
646 for (const MachineOperand &MIUse : MI.uses())
647 if (&MIUse != &Use && MIUse.isReg() && MIUse.isImplicit() &&
648 MIUse.isUse() && TRI->regsOverlap(Use.getReg(), MIUse.getReg()))
649 return true;
650
651 return false;
652}
653
654/// For an MI that has multiple definitions, check whether \p MI has
655/// a definition that overlaps with another of its definitions.
656/// For example, on ARM: umull r9, r9, lr, r0
657/// The umull instruction is unpredictable unless RdHi and RdLo are different.
658bool MachineCopyPropagation::hasOverlappingMultipleDef(
659 const MachineInstr &MI, const MachineOperand &MODef, Register Def) {
660 for (const MachineOperand &MIDef : MI.all_defs()) {
661 if ((&MIDef != &MODef) && MIDef.isReg() &&
662 TRI->regsOverlap(Def, MIDef.getReg()))
663 return true;
664 }
665
666 return false;
667}
668
669/// Look for available copies whose destination register is used by \p MI and
670/// replace the use in \p MI with the copy's source register.
671void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
672 if (!Tracker.hasAnyCopies())
673 return;
674
675 // Look for non-tied explicit vreg uses that have an active COPY
676 // instruction that defines the physical register allocated to them.
677 // Replace the vreg with the source of the active COPY.
678 for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx < OpEnd;
679 ++OpIdx) {
680 MachineOperand &MOUse = MI.getOperand(OpIdx);
681 // Don't forward into undef use operands since doing so can cause problems
682 // with the machine verifier, since it doesn't treat undef reads as reads,
683 // so we can end up with a live range that ends on an undef read, leading to
684 // an error that the live range doesn't end on a read of the live range
685 // register.
686 if (!MOUse.isReg() || MOUse.isTied() || MOUse.isUndef() || MOUse.isDef() ||
687 MOUse.isImplicit())
688 continue;
689
690 if (!MOUse.getReg())
691 continue;
692
693 // Check that the register is marked 'renamable' so we know it is safe to
694 // rename it without violating any constraints that aren't expressed in the
695 // IR (e.g. ABI or opcode requirements).
696 if (!MOUse.isRenamable())
697 continue;
698
699 MachineInstr *Copy = Tracker.findAvailCopy(MI, MOUse.getReg().asMCReg(),
700 *TRI, *TII, UseCopyInstr);
701 if (!Copy)
702 continue;
703
704 std::optional<DestSourcePair> CopyOperands =
705 isCopyInstr(*Copy, *TII, UseCopyInstr);
706 Register CopyDstReg = CopyOperands->Destination->getReg();
707 const MachineOperand &CopySrc = *CopyOperands->Source;
708 Register CopySrcReg = CopySrc.getReg();
709
710 Register ForwardedReg = CopySrcReg;
711 // MI might use a sub-register of the Copy destination, in which case the
712 // forwarded register is the matching sub-register of the Copy source.
713 if (MOUse.getReg() != CopyDstReg) {
714 unsigned SubRegIdx = TRI->getSubRegIndex(CopyDstReg, MOUse.getReg());
715 assert(SubRegIdx &&
716 "MI source is not a sub-register of Copy destination");
717 ForwardedReg = TRI->getSubReg(CopySrcReg, SubRegIdx);
718 if (!ForwardedReg) {
719 LLVM_DEBUG(dbgs() << "MCP: Copy source does not have sub-register "
720 << TRI->getSubRegIndexName(SubRegIdx) << '\n');
721 continue;
722 }
723 }
724
725 // Don't forward COPYs of reserved regs unless they are constant.
726 if (MRI->isReserved(CopySrcReg) && !MRI->isConstantPhysReg(CopySrcReg))
727 continue;
728
729 if (!isForwardableRegClassCopy(*Copy, MI, OpIdx))
730 continue;
731
732 if (hasImplicitOverlap(MI, MOUse))
733 continue;
734
735 // Check that the instruction is not a copy that partially overwrites the
736 // original copy source that we are about to use. The tracker mechanism
737 // cannot cope with that.
738 if (isCopyInstr(MI, *TII, UseCopyInstr) &&
739 MI.modifiesRegister(CopySrcReg, TRI) &&
740 !MI.definesRegister(CopySrcReg)) {
741 LLVM_DEBUG(dbgs() << "MCP: Copy source overlap with dest in " << MI);
742 continue;
743 }
744
745 if (!DebugCounter::shouldExecute(FwdCounter)) {
746 LLVM_DEBUG(dbgs() << "MCP: Skipping forwarding due to debug counter:\n "
747 << MI);
748 continue;
749 }
750
751 LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MOUse.getReg(), TRI)
752 << "\n with " << printReg(ForwardedReg, TRI)
753 << "\n in " << MI << " from " << *Copy);
754
755 MOUse.setReg(ForwardedReg);
756
757 if (!CopySrc.isRenamable())
758 MOUse.setIsRenamable(false);
759 MOUse.setIsUndef(CopySrc.isUndef());
760
761 LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
762
763 // Clear kill markers that may have been invalidated.
764 for (MachineInstr &KMI :
765 make_range(Copy->getIterator(), std::next(MI.getIterator())))
766 KMI.clearRegisterKills(CopySrcReg, TRI);
767
768 ++NumCopyForwards;
769 Changed = true;
770 }
771}
772
773void MachineCopyPropagation::ForwardCopyPropagateBlock(MachineBasicBlock &MBB) {
774 LLVM_DEBUG(dbgs() << "MCP: ForwardCopyPropagateBlock " << MBB.getName()
775 << "\n");
776
778 // Analyze copies (which don't overlap themselves).
779 std::optional<DestSourcePair> CopyOperands =
780 isCopyInstr(MI, *TII, UseCopyInstr);
781 if (CopyOperands) {
782
783 Register RegSrc = CopyOperands->Source->getReg();
784 Register RegDef = CopyOperands->Destination->getReg();
785
786 if (!TRI->regsOverlap(RegDef, RegSrc)) {
787 assert(RegDef.isPhysical() && RegSrc.isPhysical() &&
788 "MachineCopyPropagation should be run after register allocation!");
789
790 MCRegister Def = RegDef.asMCReg();
791 MCRegister Src = RegSrc.asMCReg();
792
793 // The two copies cancel out and the source of the first copy
794 // hasn't been overridden, eliminate the second one. e.g.
795 // %ecx = COPY %eax
796 // ... nothing clobbered eax.
797 // %eax = COPY %ecx
798 // =>
799 // %ecx = COPY %eax
800 //
801 // or
802 //
803 // %ecx = COPY %eax
804 // ... nothing clobbered eax.
805 // %ecx = COPY %eax
806 // =>
807 // %ecx = COPY %eax
808 if (eraseIfRedundant(MI, Def, Src) || eraseIfRedundant(MI, Src, Def))
809 continue;
810
811 forwardUses(MI);
812
813 // Src may have been changed by forwardUses()
814 CopyOperands = isCopyInstr(MI, *TII, UseCopyInstr);
815 Src = CopyOperands->Source->getReg().asMCReg();
816
817 // If Src is defined by a previous copy, the previous copy cannot be
818 // eliminated.
819 ReadRegister(Src, MI, RegularUse);
820 for (const MachineOperand &MO : MI.implicit_operands()) {
821 if (!MO.isReg() || !MO.readsReg())
822 continue;
823 MCRegister Reg = MO.getReg().asMCReg();
824 if (!Reg)
825 continue;
826 ReadRegister(Reg, MI, RegularUse);
827 }
828
829 LLVM_DEBUG(dbgs() << "MCP: Copy is a deletion candidate: "; MI.dump());
830
831 // Copy is now a candidate for deletion.
832 if (!MRI->isReserved(Def))
833 MaybeDeadCopies.insert(&MI);
834
835 // If 'Def' is previously source of another copy, then this earlier copy's
836 // source is no longer available. e.g.
837 // %xmm9 = copy %xmm2
838 // ...
839 // %xmm2 = copy %xmm0
840 // ...
841 // %xmm2 = copy %xmm9
842 Tracker.clobberRegister(Def, *TRI, *TII, UseCopyInstr);
843 for (const MachineOperand &MO : MI.implicit_operands()) {
844 if (!MO.isReg() || !MO.isDef())
845 continue;
846 MCRegister Reg = MO.getReg().asMCReg();
847 if (!Reg)
848 continue;
849 Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
850 }
851
852 Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr);
853
854 continue;
855 }
856 }
857
858 // Clobber any earlyclobber regs first.
859 for (const MachineOperand &MO : MI.operands())
860 if (MO.isReg() && MO.isEarlyClobber()) {
861 MCRegister Reg = MO.getReg().asMCReg();
862 // If we have a tied earlyclobber, that means it is also read by this
863 // instruction, so we need to make sure we don't remove it as dead
864 // later.
865 if (MO.isTied())
866 ReadRegister(Reg, MI, RegularUse);
867 Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
868 }
869
870 forwardUses(MI);
871
872 // Not a copy.
874 const MachineOperand *RegMask = nullptr;
875 for (const MachineOperand &MO : MI.operands()) {
876 if (MO.isRegMask())
877 RegMask = &MO;
878 if (!MO.isReg())
879 continue;
880 Register Reg = MO.getReg();
881 if (!Reg)
882 continue;
883
884 assert(!Reg.isVirtual() &&
885 "MachineCopyPropagation should be run after register allocation!");
886
887 if (MO.isDef() && !MO.isEarlyClobber()) {
888 Defs.push_back(Reg.asMCReg());
889 continue;
890 } else if (MO.readsReg())
891 ReadRegister(Reg.asMCReg(), MI, MO.isDebug() ? DebugUse : RegularUse);
892 }
893
894 // The instruction has a register mask operand which means that it clobbers
895 // a large set of registers. Treat clobbered registers the same way as
896 // defined registers.
897 if (RegMask) {
898 // Erase any MaybeDeadCopies whose destination register is clobbered.
900 MaybeDeadCopies.begin();
901 DI != MaybeDeadCopies.end();) {
902 MachineInstr *MaybeDead = *DI;
903 std::optional<DestSourcePair> CopyOperands =
904 isCopyInstr(*MaybeDead, *TII, UseCopyInstr);
905 MCRegister Reg = CopyOperands->Destination->getReg().asMCReg();
906 assert(!MRI->isReserved(Reg));
907
908 if (!RegMask->clobbersPhysReg(Reg)) {
909 ++DI;
910 continue;
911 }
912
913 LLVM_DEBUG(dbgs() << "MCP: Removing copy due to regmask clobbering: ";
914 MaybeDead->dump());
915
916 // Make sure we invalidate any entries in the copy maps before erasing
917 // the instruction.
918 Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
919
920 // erase() will return the next valid iterator pointing to the next
921 // element after the erased one.
922 DI = MaybeDeadCopies.erase(DI);
923 MaybeDead->eraseFromParent();
924 Changed = true;
925 ++NumDeletes;
926 }
927 }
928
929 // Any previous copy definition or reading the Defs is no longer available.
930 for (MCRegister Reg : Defs)
931 Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
932 }
933
934 bool TracksLiveness = MRI->tracksLiveness();
935
936 // If liveness is tracked, we can use the live-in lists to know which
937 // copies aren't dead.
938 if (TracksLiveness)
939 readSuccessorLiveIns(MBB);
940
941 // If MBB doesn't have succesor, delete copies whose defs are not used.
942 // If MBB does have successors, we can only delete copies if we are able to
943 // use liveness information from successors to confirm they are really dead.
944 if (MBB.succ_empty() || TracksLiveness) {
945 for (MachineInstr *MaybeDead : MaybeDeadCopies) {
946 LLVM_DEBUG(dbgs() << "MCP: Removing copy due to no live-out succ: ";
947 MaybeDead->dump());
948
949 std::optional<DestSourcePair> CopyOperands =
950 isCopyInstr(*MaybeDead, *TII, UseCopyInstr);
951 assert(CopyOperands);
952
953 Register SrcReg = CopyOperands->Source->getReg();
954 Register DestReg = CopyOperands->Destination->getReg();
955 assert(!MRI->isReserved(DestReg));
956
957 // Update matching debug values, if any.
958 SmallVector<MachineInstr *> MaybeDeadDbgUsers(
959 CopyDbgUsers[MaybeDead].begin(), CopyDbgUsers[MaybeDead].end());
960 MRI->updateDbgUsersToReg(DestReg.asMCReg(), SrcReg.asMCReg(),
961 MaybeDeadDbgUsers);
962
963 MaybeDead->eraseFromParent();
964 Changed = true;
965 ++NumDeletes;
966 }
967 }
968
969 MaybeDeadCopies.clear();
970 CopyDbgUsers.clear();
971 Tracker.clear();
972}
973
974static bool isBackwardPropagatableCopy(const DestSourcePair &CopyOperands,
976 const TargetInstrInfo &TII) {
977 Register Def = CopyOperands.Destination->getReg();
978 Register Src = CopyOperands.Source->getReg();
979
980 if (!Def || !Src)
981 return false;
982
983 if (MRI.isReserved(Def) || MRI.isReserved(Src))
984 return false;
985
986 return CopyOperands.Source->isRenamable() && CopyOperands.Source->isKill();
987}
988
989void MachineCopyPropagation::propagateDefs(MachineInstr &MI) {
990 if (!Tracker.hasAnyCopies())
991 return;
992
993 for (unsigned OpIdx = 0, OpEnd = MI.getNumOperands(); OpIdx != OpEnd;
994 ++OpIdx) {
995 MachineOperand &MODef = MI.getOperand(OpIdx);
996
997 if (!MODef.isReg() || MODef.isUse())
998 continue;
999
1000 // Ignore non-trivial cases.
1001 if (MODef.isTied() || MODef.isUndef() || MODef.isImplicit())
1002 continue;
1003
1004 if (!MODef.getReg())
1005 continue;
1006
1007 // We only handle if the register comes from a vreg.
1008 if (!MODef.isRenamable())
1009 continue;
1010
1011 MachineInstr *Copy = Tracker.findAvailBackwardCopy(
1012 MI, MODef.getReg().asMCReg(), *TRI, *TII, UseCopyInstr);
1013 if (!Copy)
1014 continue;
1015
1016 std::optional<DestSourcePair> CopyOperands =
1017 isCopyInstr(*Copy, *TII, UseCopyInstr);
1018 Register Def = CopyOperands->Destination->getReg();
1019 Register Src = CopyOperands->Source->getReg();
1020
1021 if (MODef.getReg() != Src)
1022 continue;
1023
1024 if (!isBackwardPropagatableRegClassCopy(*Copy, MI, OpIdx))
1025 continue;
1026
1027 if (hasImplicitOverlap(MI, MODef))
1028 continue;
1029
1030 if (hasOverlappingMultipleDef(MI, MODef, Def))
1031 continue;
1032
1033 LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MODef.getReg(), TRI)
1034 << "\n with " << printReg(Def, TRI) << "\n in "
1035 << MI << " from " << *Copy);
1036
1037 MODef.setReg(Def);
1038 MODef.setIsRenamable(CopyOperands->Destination->isRenamable());
1039
1040 LLVM_DEBUG(dbgs() << "MCP: After replacement: " << MI << "\n");
1041 MaybeDeadCopies.insert(Copy);
1042 Changed = true;
1043 ++NumCopyBackwardPropagated;
1044 }
1045}
1046
1047void MachineCopyPropagation::BackwardCopyPropagateBlock(
1049 LLVM_DEBUG(dbgs() << "MCP: BackwardCopyPropagateBlock " << MBB.getName()
1050 << "\n");
1051
1053 // Ignore non-trivial COPYs.
1054 std::optional<DestSourcePair> CopyOperands =
1055 isCopyInstr(MI, *TII, UseCopyInstr);
1056 if (CopyOperands && MI.getNumOperands() == 2) {
1057 Register DefReg = CopyOperands->Destination->getReg();
1058 Register SrcReg = CopyOperands->Source->getReg();
1059
1060 if (!TRI->regsOverlap(DefReg, SrcReg)) {
1061 // Unlike forward cp, we don't invoke propagateDefs here,
1062 // just let forward cp do COPY-to-COPY propagation.
1063 if (isBackwardPropagatableCopy(*CopyOperands, *MRI, *TII)) {
1064 Tracker.invalidateRegister(SrcReg.asMCReg(), *TRI, *TII,
1065 UseCopyInstr);
1066 Tracker.invalidateRegister(DefReg.asMCReg(), *TRI, *TII,
1067 UseCopyInstr);
1068 Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr);
1069 continue;
1070 }
1071 }
1072 }
1073
1074 // Invalidate any earlyclobber regs first.
1075 for (const MachineOperand &MO : MI.operands())
1076 if (MO.isReg() && MO.isEarlyClobber()) {
1077 MCRegister Reg = MO.getReg().asMCReg();
1078 if (!Reg)
1079 continue;
1080 Tracker.invalidateRegister(Reg, *TRI, *TII, UseCopyInstr);
1081 }
1082
1083 propagateDefs(MI);
1084 for (const MachineOperand &MO : MI.operands()) {
1085 if (!MO.isReg())
1086 continue;
1087
1088 if (!MO.getReg())
1089 continue;
1090
1091 if (MO.isDef())
1092 Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII,
1093 UseCopyInstr);
1094
1095 if (MO.readsReg()) {
1096 if (MO.isDebug()) {
1097 // Check if the register in the debug instruction is utilized
1098 // in a copy instruction, so we can update the debug info if the
1099 // register is changed.
1100 for (MCRegUnit Unit : TRI->regunits(MO.getReg().asMCReg())) {
1101 if (auto *Copy = Tracker.findCopyDefViaUnit(Unit, *TRI)) {
1102 CopyDbgUsers[Copy].insert(&MI);
1103 }
1104 }
1105 } else {
1106 Tracker.invalidateRegister(MO.getReg().asMCReg(), *TRI, *TII,
1107 UseCopyInstr);
1108 }
1109 }
1110 }
1111 }
1112
1113 for (auto *Copy : MaybeDeadCopies) {
1114 std::optional<DestSourcePair> CopyOperands =
1115 isCopyInstr(*Copy, *TII, UseCopyInstr);
1116 Register Src = CopyOperands->Source->getReg();
1117 Register Def = CopyOperands->Destination->getReg();
1118 SmallVector<MachineInstr *> MaybeDeadDbgUsers(CopyDbgUsers[Copy].begin(),
1119 CopyDbgUsers[Copy].end());
1120
1121 MRI->updateDbgUsersToReg(Src.asMCReg(), Def.asMCReg(), MaybeDeadDbgUsers);
1122 Copy->eraseFromParent();
1123 ++NumDeletes;
1124 }
1125
1126 MaybeDeadCopies.clear();
1127 CopyDbgUsers.clear();
1128 Tracker.clear();
1129}
1130
1134 MachineInstr *Leader) {
1135 auto &SC = SpillChain[Leader];
1136 auto &RC = ReloadChain[Leader];
1137 for (auto I = SC.rbegin(), E = SC.rend(); I != E; ++I)
1138 (*I)->dump();
1139 for (MachineInstr *MI : RC)
1140 MI->dump();
1141}
1142
1143// Remove spill-reload like copy chains. For example
1144// r0 = COPY r1
1145// r1 = COPY r2
1146// r2 = COPY r3
1147// r3 = COPY r4
1148// <def-use r4>
1149// r4 = COPY r3
1150// r3 = COPY r2
1151// r2 = COPY r1
1152// r1 = COPY r0
1153// will be folded into
1154// r0 = COPY r1
1155// r1 = COPY r4
1156// <def-use r4>
1157// r4 = COPY r1
1158// r1 = COPY r0
1159// TODO: Currently we don't track usage of r0 outside the chain, so we
1160// conservatively keep its value as it was before the rewrite.
1161//
1162// The algorithm is trying to keep
1163// property#1: No Def of spill COPY in the chain is used or defined until the
1164// paired reload COPY in the chain uses the Def.
1165//
1166// property#2: NO Source of COPY in the chain is used or defined until the next
1167// COPY in the chain defines the Source, except the innermost spill-reload
1168// pair.
1169//
1170// The algorithm is conducted by checking every COPY inside the MBB, assuming
1171// the COPY is a reload COPY, then try to find paired spill COPY by searching
1172// the COPY defines the Src of the reload COPY backward. If such pair is found,
1173// it either belongs to an existing chain or a new chain depends on
1174// last available COPY uses the Def of the reload COPY.
1175// Implementation notes, we use CopyTracker::findLastDefCopy(Reg, ...) to find
1176// out last COPY that defines Reg; we use CopyTracker::findLastUseCopy(Reg, ...)
1177// to find out last COPY that uses Reg. When we are encountered with a Non-COPY
1178// instruction, we check registers in the operands of this instruction. If this
1179// Reg is defined by a COPY, we untrack this Reg via
1180// CopyTracker::clobberRegister(Reg, ...).
1181void MachineCopyPropagation::EliminateSpillageCopies(MachineBasicBlock &MBB) {
1182 // ChainLeader maps MI inside a spill-reload chain to its innermost reload COPY.
1183 // Thus we can track if a MI belongs to an existing spill-reload chain.
1185 // SpillChain maps innermost reload COPY of a spill-reload chain to a sequence
1186 // of COPYs that forms spills of a spill-reload chain.
1187 // ReloadChain maps innermost reload COPY of a spill-reload chain to a
1188 // sequence of COPYs that forms reloads of a spill-reload chain.
1190 // If a COPY's Source has use or def until next COPY defines the Source,
1191 // we put the COPY in this set to keep property#2.
1192 DenseSet<const MachineInstr *> CopySourceInvalid;
1193
1194 auto TryFoldSpillageCopies =
1195 [&, this](const SmallVectorImpl<MachineInstr *> &SC,
1197 assert(SC.size() == RC.size() && "Spill-reload should be paired");
1198
1199 // We need at least 3 pairs of copies for the transformation to apply,
1200 // because the first outermost pair cannot be removed since we don't
1201 // recolor outside of the chain and that we need at least one temporary
1202 // spill slot to shorten the chain. If we only have a chain of two
1203 // pairs, we already have the shortest sequence this code can handle:
1204 // the outermost pair for the temporary spill slot, and the pair that
1205 // use that temporary spill slot for the other end of the chain.
1206 // TODO: We might be able to simplify to one spill-reload pair if collecting
1207 // more infomation about the outermost COPY.
1208 if (SC.size() <= 2)
1209 return;
1210
1211 // If violate property#2, we don't fold the chain.
1212 for (const MachineInstr *Spill : drop_begin(SC))
1213 if (CopySourceInvalid.count(Spill))
1214 return;
1215
1216 for (const MachineInstr *Reload : drop_end(RC))
1217 if (CopySourceInvalid.count(Reload))
1218 return;
1219
1220 auto CheckCopyConstraint = [this](Register Def, Register Src) {
1221 for (const TargetRegisterClass *RC : TRI->regclasses()) {
1222 if (RC->contains(Def) && RC->contains(Src))
1223 return true;
1224 }
1225 return false;
1226 };
1227
1228 auto UpdateReg = [](MachineInstr *MI, const MachineOperand *Old,
1229 const MachineOperand *New) {
1230 for (MachineOperand &MO : MI->operands()) {
1231 if (&MO == Old)
1232 MO.setReg(New->getReg());
1233 }
1234 };
1235
1236 std::optional<DestSourcePair> InnerMostSpillCopy =
1237 isCopyInstr(*SC[0], *TII, UseCopyInstr);
1238 std::optional<DestSourcePair> OuterMostSpillCopy =
1239 isCopyInstr(*SC.back(), *TII, UseCopyInstr);
1240 std::optional<DestSourcePair> InnerMostReloadCopy =
1241 isCopyInstr(*RC[0], *TII, UseCopyInstr);
1242 std::optional<DestSourcePair> OuterMostReloadCopy =
1243 isCopyInstr(*RC.back(), *TII, UseCopyInstr);
1244 if (!CheckCopyConstraint(OuterMostSpillCopy->Source->getReg(),
1245 InnerMostSpillCopy->Source->getReg()) ||
1246 !CheckCopyConstraint(InnerMostReloadCopy->Destination->getReg(),
1247 OuterMostReloadCopy->Destination->getReg()))
1248 return;
1249
1250 SpillageChainsLength += SC.size() + RC.size();
1251 NumSpillageChains += 1;
1252 UpdateReg(SC[0], InnerMostSpillCopy->Destination,
1253 OuterMostSpillCopy->Source);
1254 UpdateReg(RC[0], InnerMostReloadCopy->Source,
1255 OuterMostReloadCopy->Destination);
1256
1257 for (size_t I = 1; I < SC.size() - 1; ++I) {
1258 SC[I]->eraseFromParent();
1259 RC[I]->eraseFromParent();
1260 NumDeletes += 2;
1261 }
1262 };
1263
1264 auto IsFoldableCopy = [this](const MachineInstr &MaybeCopy) {
1265 if (MaybeCopy.getNumImplicitOperands() > 0)
1266 return false;
1267 std::optional<DestSourcePair> CopyOperands =
1268 isCopyInstr(MaybeCopy, *TII, UseCopyInstr);
1269 if (!CopyOperands)
1270 return false;
1271 Register Src = CopyOperands->Source->getReg();
1272 Register Def = CopyOperands->Destination->getReg();
1273 return Src && Def && !TRI->regsOverlap(Src, Def) &&
1274 CopyOperands->Source->isRenamable() &&
1275 CopyOperands->Destination->isRenamable();
1276 };
1277
1278 auto IsSpillReloadPair = [&, this](const MachineInstr &Spill,
1279 const MachineInstr &Reload) {
1280 if (!IsFoldableCopy(Spill) || !IsFoldableCopy(Reload))
1281 return false;
1282 std::optional<DestSourcePair> SpillCopy =
1283 isCopyInstr(Spill, *TII, UseCopyInstr);
1284 std::optional<DestSourcePair> ReloadCopy =
1285 isCopyInstr(Reload, *TII, UseCopyInstr);
1286 if (!SpillCopy || !ReloadCopy)
1287 return false;
1288 return SpillCopy->Source->getReg() == ReloadCopy->Destination->getReg() &&
1289 SpillCopy->Destination->getReg() == ReloadCopy->Source->getReg();
1290 };
1291
1292 auto IsChainedCopy = [&, this](const MachineInstr &Prev,
1293 const MachineInstr &Current) {
1294 if (!IsFoldableCopy(Prev) || !IsFoldableCopy(Current))
1295 return false;
1296 std::optional<DestSourcePair> PrevCopy =
1297 isCopyInstr(Prev, *TII, UseCopyInstr);
1298 std::optional<DestSourcePair> CurrentCopy =
1299 isCopyInstr(Current, *TII, UseCopyInstr);
1300 if (!PrevCopy || !CurrentCopy)
1301 return false;
1302 return PrevCopy->Source->getReg() == CurrentCopy->Destination->getReg();
1303 };
1304
1306 std::optional<DestSourcePair> CopyOperands =
1307 isCopyInstr(MI, *TII, UseCopyInstr);
1308
1309 // Update track information via non-copy instruction.
1310 SmallSet<Register, 8> RegsToClobber;
1311 if (!CopyOperands) {
1312 for (const MachineOperand &MO : MI.operands()) {
1313 if (!MO.isReg())
1314 continue;
1315 Register Reg = MO.getReg();
1316 if (!Reg)
1317 continue;
1318 MachineInstr *LastUseCopy =
1319 Tracker.findLastSeenUseInCopy(Reg.asMCReg(), *TRI);
1320 if (LastUseCopy) {
1321 LLVM_DEBUG(dbgs() << "MCP: Copy source of\n");
1322 LLVM_DEBUG(LastUseCopy->dump());
1323 LLVM_DEBUG(dbgs() << "might be invalidated by\n");
1324 LLVM_DEBUG(MI.dump());
1325 CopySourceInvalid.insert(LastUseCopy);
1326 }
1327 // Must be noted Tracker.clobberRegister(Reg, ...) removes tracking of
1328 // Reg, i.e, COPY that defines Reg is removed from the mapping as well
1329 // as marking COPYs that uses Reg unavailable.
1330 // We don't invoke CopyTracker::clobberRegister(Reg, ...) if Reg is not
1331 // defined by a previous COPY, since we don't want to make COPYs uses
1332 // Reg unavailable.
1333 if (Tracker.findLastSeenDefInCopy(MI, Reg.asMCReg(), *TRI, *TII,
1334 UseCopyInstr))
1335 // Thus we can keep the property#1.
1336 RegsToClobber.insert(Reg);
1337 }
1338 for (Register Reg : RegsToClobber) {
1339 Tracker.clobberRegister(Reg, *TRI, *TII, UseCopyInstr);
1340 LLVM_DEBUG(dbgs() << "MCP: Removed tracking of " << printReg(Reg, TRI)
1341 << "\n");
1342 }
1343 continue;
1344 }
1345
1346 Register Src = CopyOperands->Source->getReg();
1347 Register Def = CopyOperands->Destination->getReg();
1348 // Check if we can find a pair spill-reload copy.
1349 LLVM_DEBUG(dbgs() << "MCP: Searching paired spill for reload: ");
1350 LLVM_DEBUG(MI.dump());
1351 MachineInstr *MaybeSpill =
1352 Tracker.findLastSeenDefInCopy(MI, Src.asMCReg(), *TRI, *TII, UseCopyInstr);
1353 bool MaybeSpillIsChained = ChainLeader.count(MaybeSpill);
1354 if (!MaybeSpillIsChained && MaybeSpill &&
1355 IsSpillReloadPair(*MaybeSpill, MI)) {
1356 // Check if we already have an existing chain. Now we have a
1357 // spill-reload pair.
1358 // L2: r2 = COPY r3
1359 // L5: r3 = COPY r2
1360 // Looking for a valid COPY before L5 which uses r3.
1361 // This can be serverial cases.
1362 // Case #1:
1363 // No COPY is found, which can be r3 is def-use between (L2, L5), we
1364 // create a new chain for L2 and L5.
1365 // Case #2:
1366 // L2: r2 = COPY r3
1367 // L5: r3 = COPY r2
1368 // Such COPY is found and is L2, we create a new chain for L2 and L5.
1369 // Case #3:
1370 // L2: r2 = COPY r3
1371 // L3: r1 = COPY r3
1372 // L5: r3 = COPY r2
1373 // we create a new chain for L2 and L5.
1374 // Case #4:
1375 // L2: r2 = COPY r3
1376 // L3: r1 = COPY r3
1377 // L4: r3 = COPY r1
1378 // L5: r3 = COPY r2
1379 // Such COPY won't be found since L4 defines r3. we create a new chain
1380 // for L2 and L5.
1381 // Case #5:
1382 // L2: r2 = COPY r3
1383 // L3: r3 = COPY r1
1384 // L4: r1 = COPY r3
1385 // L5: r3 = COPY r2
1386 // COPY is found and is L4 which belongs to an existing chain, we add
1387 // L2 and L5 to this chain.
1388 LLVM_DEBUG(dbgs() << "MCP: Found spill: ");
1389 LLVM_DEBUG(MaybeSpill->dump());
1390 MachineInstr *MaybePrevReload =
1391 Tracker.findLastSeenUseInCopy(Def.asMCReg(), *TRI);
1392 auto Leader = ChainLeader.find(MaybePrevReload);
1393 MachineInstr *L = nullptr;
1394 if (Leader == ChainLeader.end() ||
1395 (MaybePrevReload && !IsChainedCopy(*MaybePrevReload, MI))) {
1396 L = &MI;
1397 assert(!SpillChain.count(L) &&
1398 "SpillChain should not have contained newly found chain");
1399 } else {
1400 assert(MaybePrevReload &&
1401 "Found a valid leader through nullptr should not happend");
1402 L = Leader->second;
1403 assert(SpillChain[L].size() > 0 &&
1404 "Existing chain's length should be larger than zero");
1405 }
1406 assert(!ChainLeader.count(&MI) && !ChainLeader.count(MaybeSpill) &&
1407 "Newly found paired spill-reload should not belong to any chain "
1408 "at this point");
1409 ChainLeader.insert({MaybeSpill, L});
1410 ChainLeader.insert({&MI, L});
1411 SpillChain[L].push_back(MaybeSpill);
1412 ReloadChain[L].push_back(&MI);
1413 LLVM_DEBUG(dbgs() << "MCP: Chain " << L << " now is:\n");
1414 LLVM_DEBUG(printSpillReloadChain(SpillChain, ReloadChain, L));
1415 } else if (MaybeSpill && !MaybeSpillIsChained) {
1416 // MaybeSpill is unable to pair with MI. That's to say adding MI makes
1417 // the chain invalid.
1418 // The COPY defines Src is no longer considered as a candidate of a
1419 // valid chain. Since we expect the Def of a spill copy isn't used by
1420 // any COPY instruction until a reload copy. For example:
1421 // L1: r1 = COPY r2
1422 // L2: r3 = COPY r1
1423 // If we later have
1424 // L1: r1 = COPY r2
1425 // L2: r3 = COPY r1
1426 // L3: r2 = COPY r1
1427 // L1 and L3 can't be a valid spill-reload pair.
1428 // Thus we keep the property#1.
1429 LLVM_DEBUG(dbgs() << "MCP: Not paired spill-reload:\n");
1430 LLVM_DEBUG(MaybeSpill->dump());
1431 LLVM_DEBUG(MI.dump());
1432 Tracker.clobberRegister(Src.asMCReg(), *TRI, *TII, UseCopyInstr);
1433 LLVM_DEBUG(dbgs() << "MCP: Removed tracking of " << printReg(Src, TRI)
1434 << "\n");
1435 }
1436 Tracker.trackCopy(&MI, *TRI, *TII, UseCopyInstr);
1437 }
1438
1439 for (auto I = SpillChain.begin(), E = SpillChain.end(); I != E; ++I) {
1440 auto &SC = I->second;
1441 assert(ReloadChain.count(I->first) &&
1442 "Reload chain of the same leader should exist");
1443 auto &RC = ReloadChain[I->first];
1444 TryFoldSpillageCopies(SC, RC);
1445 }
1446
1447 MaybeDeadCopies.clear();
1448 CopyDbgUsers.clear();
1449 Tracker.clear();
1450}
1451
1452bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) {
1453 if (skipFunction(MF.getFunction()))
1454 return false;
1455
1456 bool isSpillageCopyElimEnabled = false;
1458 case cl::BOU_UNSET:
1459 isSpillageCopyElimEnabled =
1461 break;
1462 case cl::BOU_TRUE:
1463 isSpillageCopyElimEnabled = true;
1464 break;
1465 case cl::BOU_FALSE:
1466 isSpillageCopyElimEnabled = false;
1467 break;
1468 }
1469
1470 Changed = false;
1471
1473 TII = MF.getSubtarget().getInstrInfo();
1474 MRI = &MF.getRegInfo();
1475
1476 for (MachineBasicBlock &MBB : MF) {
1477 if (isSpillageCopyElimEnabled)
1478 EliminateSpillageCopies(MBB);
1479 BackwardCopyPropagateBlock(MBB);
1480 ForwardCopyPropagateBlock(MBB);
1481 }
1482
1483 return Changed;
1484}
1485
1487llvm::createMachineCopyPropagationPass(bool UseCopyInstr = false) {
1488 return new MachineCopyPropagation(UseCopyInstr);
1489}
unsigned const MachineRegisterInfo * MRI
MachineBasicBlock & MBB
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:203
static void clear(coro::Shape &Shape)
Definition: Coroutines.cpp:148
This file provides an implementation of debug counters.
#define DEBUG_COUNTER(VARNAME, COUNTERNAME, DESC)
Definition: DebugCounter.h:182
#define LLVM_DEBUG(X)
Definition: Debug.h:101
This file defines the DenseMap class.
const HexagonInstrInfo * TII
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
static cl::opt< cl::boolOrDefault > EnableSpillageCopyElimination("enable-spill-copy-elim", cl::Hidden)
static void LLVM_ATTRIBUTE_UNUSED printSpillReloadChain(DenseMap< MachineInstr *, SmallVector< MachineInstr * > > &SpillChain, DenseMap< MachineInstr *, SmallVector< MachineInstr * > > &ReloadChain, MachineInstr *Leader)
static bool isBackwardPropagatableCopy(const DestSourcePair &CopyOperands, const MachineRegisterInfo &MRI, const TargetInstrInfo &TII)
static bool isNopCopy(const MachineInstr &PreviousCopy, MCRegister Src, MCRegister Def, const TargetRegisterInfo *TRI, const TargetInstrInfo *TII, bool UseCopyInstr)
Return true if PreviousCopy did copy register Src to register Def.
static cl::opt< bool > MCPUseCopyInstr("mcp-use-is-copy-instr", cl::init(false), cl::Hidden)
#define DEBUG_TYPE
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:38
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
SI Lower i1 Copies
This file contains some templates that are useful if you are working with the STL at all.
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition: Statistic.h:167
Represent the analysis usage information of a pass.
void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition: Pass.cpp:269
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
static bool shouldExecute(unsigned CounterName)
Definition: DebugCounter.h:72
iterator find(const_arg_type_t< KeyT > Val)
Definition: DenseMap.h:155
iterator begin()
Definition: DenseMap.h:75
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition: DenseMap.h:151
iterator end()
Definition: DenseMap.h:84
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: DenseMap.h:220
Implements a dense probed hash-table based set.
Definition: DenseSet.h:271
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
iterator_range< succ_iterator > successors()
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
Representation of each machine instruction.
Definition: MachineInstr.h:69
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:556
const TargetRegisterClass * getRegClassConstraint(unsigned OpIdx, const TargetInstrInfo *TII, const TargetRegisterInfo *TRI) const
Compute the static register class constraint for operand OpIdx.
MachineOperand class - Representation of each machine instruction operand.
bool isImplicit() const
void setIsRenamable(bool Val=true)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setReg(Register Reg)
Change the register this operand corresponds to.
bool isRenamable() const
isRenamable - Returns true if this register may be renamed, i.e.
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static bool clobbersPhysReg(const uint32_t *RegMask, MCRegister PhysReg)
clobbersPhysReg - Returns true if this RegMask clobbers PhysReg.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
void dump() const
Definition: Pass.cpp:136
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
Definition: Register.h:110
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:95
iterator begin()
Get an iterator to the beginning of the SetVector.
Definition: SetVector.h:103
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:370
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
Definition: SmallSet.h:135
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
Definition: SmallSet.h:179
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual bool enableSpillageCopyElimination() const
Enable spillage copy elimination in MachineCopyPropagation pass.
virtual const TargetInstrInfo * getInstrInfo() const
A Use represents the edge between a Value definition and its users.
Definition: Use.h:43
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:206
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition: DenseSet.h:97
reverse_self_iterator getReverseIterator()
Definition: ilist_node.h:112
self_iterator getIterator()
Definition: ilist_node.h:109
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
DebugType
Definition: COFF.h:666
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:450
NodeAddr< DefNode * > Def
Definition: RDFGraph.h:384
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:227
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:236
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:329
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
Definition: STLExtras.h:1680
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition: STLExtras.h:656
auto reverse(ContainerTy &&C)
Definition: STLExtras.h:419
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
auto drop_end(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the last N elements excluded.
Definition: STLExtras.h:336
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition: STLExtras.h:1879
MachineFunctionPass * createMachineCopyPropagationPass(bool UseCopyInstr)
void initializeMachineCopyPropagationPass(PassRegistry &)
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
const MachineOperand * Source
const MachineOperand * Destination