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