LLVM 24.0.0git
Rematerializer.cpp
Go to the documentation of this file.
1//=====-- Rematerializer.cpp - MIR rematerialization support ----*- C++ -*-===//
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/// \file
10/// Implements helpers for target-independent rematerialization at the MIR
11/// level.
12//
13//===----------------------------------------------------------------------===//
14
16#include "llvm/ADT/MapVector.h"
17#include "llvm/ADT/STLExtras.h"
18#include "llvm/ADT/SetVector.h"
19#include "llvm/ADT/SmallSet.h"
27#include "llvm/MC/LaneBitmask.h"
28#include "llvm/Support/Debug.h"
29#include <optional>
30
31#define DEBUG_TYPE "rematerializer"
32
33using namespace llvm;
35
36// Pin the vtable to this file.
37void Rematerializer::Listener::anchor() {}
38
39/// Checks whether the value in \p LI at \p UseIdx is identical to \p OVNI (this
40/// implies it is also live there). When \p LI has sub-ranges, checks that
41/// all sub-ranges intersecting with \p Mask are also live at \p UseIdx.
42static bool isIdenticalAtUse(const VNInfo &OVNI, LaneBitmask Mask,
43 SlotIndex UseIdx, const LiveInterval &LI) {
44 if (&OVNI != LI.getVNInfoAt(UseIdx))
45 return false;
46
47 if (LI.hasSubRanges()) {
48 // Check that intersecting subranges are live at user.
49 for (const LiveInterval::SubRange &SR : LI.subranges()) {
50 if ((SR.LaneMask & Mask).none())
51 continue;
52 if (!SR.liveAt(UseIdx))
53 return false;
54
55 // Early exit if all used lanes are checked. No need to continue.
56 Mask &= ~SR.LaneMask;
57 if (Mask.none())
58 break;
59 }
60 }
61 return true;
62}
63
64/// If \p MO is a virtual read register, returns it. Otherwise returns the
65/// sentinel register.
67 if (!MO.isReg() || !MO.readsReg())
68 return Register();
69 Register Reg = MO.getReg();
70 if (Reg.isPhysical()) {
71 // By the requirements on trivially rematerializable instructions, a
72 // physical register use is either constant or ignorable.
73 return Register();
74 }
75 return Reg;
76}
77
79 unsigned UseRegion,
81 MachineInstr *FirstMI =
82 getReg(RootIdx).getRegionUseBounds(UseRegion, LIS).first;
83 // If there are no users in the region, rematerialize the register at the very
84 // end of the region.
86 FirstMI ? FirstMI : Regions[UseRegion].second;
87 RegisterIdx NewRegIdx =
88 rematerializeToPos(RootIdx, UseRegion, InsertPos, DRI);
89 transferRegionUsers(RootIdx, NewRegIdx, UseRegion);
90 return NewRegIdx;
91}
92
97 assert(!DRI.DependencyMap.contains(RootIdx));
98 LLVM_DEBUG(dbgs() << "Rematerializing " << printID(RootIdx) << '\n');
99
101 // Copy all dependencies because recursive rematerialization of dependencies
102 // may invalidate references to the backing vector of registers.
103 SmallVector<RegisterIdx, 2> OldDeps(getReg(RootIdx).Dependencies);
104 for (RegisterIdx DepRegIdx : OldDeps) {
105 // Recursively rematerialize required dependencies at the same position as
106 // the root. Registers form a DAG so the recursion is guaranteed to
107 // terminate.
108 auto RematIdx = DRI.DependencyMap.find(DepRegIdx);
109 RegisterIdx NewDepRegIdx;
110 if (RematIdx == DRI.DependencyMap.end())
111 NewDepRegIdx = rematerializeToPos(DepRegIdx, UseRegion, InsertPos, DRI);
112 else
113 NewDepRegIdx = RematIdx->second;
114 NewDeps.push_back(NewDepRegIdx);
115 }
116 RegisterIdx NewIdx =
117 rematerializeReg(RootIdx, UseRegion, InsertPos, std::move(NewDeps));
118 DRI.DependencyMap.insert({RootIdx, NewIdx});
119 return NewIdx;
120}
121
123 unsigned UserRegion, MachineInstr &UserMI) {
124 transferUserImpl(FromRegIdx, ToRegIdx, UserMI);
125
126 Regs[ToRegIdx].addUser(&UserMI, UserRegion);
127 extendToNewUsers(ToRegIdx, &UserMI);
128
129 Regs[FromRegIdx].eraseUser(&UserMI, UserRegion);
130 shrinkToUses(FromRegIdx);
131}
132
134 RegisterIdx ToRegIdx,
135 unsigned UseRegion) {
136 Reg &FromReg = Regs[FromRegIdx];
137 auto UsesIt = FromReg.Uses.find(UseRegion);
138 if (UsesIt == FromReg.Uses.end())
139 return;
140
141 const SmallDenseSet<MachineInstr *, 4> &RegionUsers = UsesIt->getSecond();
143 for (MachineInstr *UserMI : RegionUsers) {
144 transferUserImpl(FromRegIdx, ToRegIdx, *UserMI);
145 NewUsers.push_back(UserMI);
146 }
147
148 extendToNewUsers(ToRegIdx, NewUsers);
149 Regs[ToRegIdx].addUsers(RegionUsers, UseRegion);
150
151 FromReg.Uses.erase(UseRegion);
152 shrinkToUses(FromRegIdx);
153}
154
156 RegisterIdx ToRegIdx) {
157 Reg &FromReg = Regs[FromRegIdx];
159 for (const auto &[UseRegion, RegionUsers] : FromReg.Uses) {
160 for (MachineInstr *UserMI : RegionUsers) {
161 transferUserImpl(FromRegIdx, ToRegIdx, *UserMI);
162 NewUsers.push_back(UserMI);
163 }
164 Regs[ToRegIdx].addUsers(RegionUsers, UseRegion);
165 }
166 extendToNewUsers(ToRegIdx, NewUsers);
167
168 FromReg.Uses.clear();
169 deleteReg(FromRegIdx);
170}
171
172void Rematerializer::transferUserImpl(RegisterIdx FromRegIdx,
173 RegisterIdx ToRegIdx,
174 MachineInstr &UserMI) {
175 assert(FromRegIdx != ToRegIdx && "identical registers");
176 assert(getOriginOrSelf(FromRegIdx) == getOriginOrSelf(ToRegIdx) &&
177 "unrelated registers");
178
179 LLVM_DEBUG(dbgs() << "User transfer from " << printID(FromRegIdx) << " to "
180 << printID(ToRegIdx) << ": " << printUser(&UserMI) << '\n');
181
182 Register FromReg = getReg(FromRegIdx).getDefReg();
183 UserMI.substituteRegister(FromReg, getReg(ToRegIdx).getDefReg(), 0, TRI);
184
185 RegisterIdx UserRegIdx = getDefRegIdx(UserMI);
186 if (UserRegIdx == NoReg)
187 return;
188
189 // When the user is rematerializable, we must reflect the change in its
190 // dependencies.
191 Reg &UserReg = Regs[UserRegIdx];
192 SmallVectorImpl<RegisterIdx> &UserDeps = Regs[UserRegIdx].Dependencies;
193 bool IsNewDep = true;
194 if (UserReg.Defs.size() > 1) {
195 // Other defining MIs might already be using the new register.
196 IsNewDep = !is_contained(UserDeps, ToRegIdx);
197
198 // If any other defining instruction of the rematerializable user still uses
199 // the original register, we should not remove it from dependencies and may
200 // need to add a new dependency if it is the first time the new register is
201 // used by defining instructions.
202 for (MachineInstr *DefMI : UserReg.Defs) {
203 if (DefMI == &UserMI)
204 continue;
205 for (const MachineOperand &MO : DefMI->all_uses()) {
206 if (MO.getReg() == FromReg) {
207 if (IsNewDep)
208 UserDeps.push_back(ToRegIdx);
209 return;
210 }
211 }
212 }
213 }
214
215 // No other defining instruction has the original register as user. This
216 // either removes a dependency if the new register was previously used, or is
217 // a simple replacement if not.
218 unsigned *FindFromReg = find(UserDeps, FromRegIdx);
219 assert(FindFromReg != UserDeps.end() && "broken dependency");
220 if (IsNewDep)
221 *FindFromReg = ToRegIdx;
222 else
223 UserReg.Dependencies.erase(FindFromReg);
224}
225
228 unsigned SubIdx = MO.getSubReg();
229 LaneBitmask Mask = SubIdx ? TRI.getSubRegIndexLaneMask(SubIdx)
230 : MRI.getMaxLaneMaskForVReg(MO.getReg());
232 MO.getReg(), Mask,
233 LIS.getInstructionIndex(*MO.getParent()).getRegSlot(true), Uses);
234}
235
237 SlotIndex RefSlot,
239 if (Uses.empty())
240 return true;
241 const LiveInterval &LI = LIS.getInterval(Reg);
242 const VNInfo *DefVN = LI.getVNInfoAt(RefSlot);
243 if (!DefVN)
244 return false;
245 for (SlotIndex Use : Uses) {
246 if (!isIdenticalAtUse(*DefVN, Mask, Use, LI))
247 return false;
248 }
249 return true;
250}
251
253 unsigned Region,
254 SlotIndex Before) const {
255 auto It = Rematerializations.find(getOriginOrSelf(RegIdx));
256 if (It == Rematerializations.end())
257 return NoReg;
258 const RematsOf &Remats = It->getSecond();
259
260 SlotIndex BestSlot;
261 RegisterIdx BestRegIdx = NoReg;
262 for (RegisterIdx RematRegIdx : Remats) {
263 const Reg &RematReg = getReg(RematRegIdx);
264 if (RematReg.DefRegion != Region || RematReg.Uses.empty())
265 continue;
266 SlotIndex RematRegSlot =
267 LIS.getInstructionIndex(*RematReg.getLastDef()).getRegSlot();
268 if (RematRegSlot < Before &&
269 (BestRegIdx == NoReg || RematRegSlot > BestSlot)) {
270 BestSlot = RematRegSlot;
271 BestRegIdx = RematRegIdx;
272 }
273 }
274 return BestRegIdx;
275}
276
277void Rematerializer::deleteReg(RegisterIdx RootIdx) {
278 assert(getReg(RootIdx).Uses.empty() && "register still has uses");
279
280 // Traverse the root's dependency DAG depth-first to find the set of registers
281 // we can delete and a legal order to delete them in.
282 SmallVector<RegisterIdx, 4> DepDAG{RootIdx};
283 SmallVector<RegisterIdx, 8> DeleteOrder{RootIdx};
284 do {
285 // A deleted register's dependencies may be deletable too.
286 const Reg &DeleteReg = getReg(DepDAG.pop_back_val());
287 for (RegisterIdx DepRegIdx : DeleteReg.Dependencies) {
288 // All dependencies lose a user (the deleted register).
289 Reg &DepReg = Regs[DepRegIdx];
290 for (MachineInstr *DefMI : DeleteReg.Defs) {
291 if (DepReg.tryEraseUser(DefMI, DeleteReg.DefRegion) &&
292 DepReg.Uses.empty()) {
293 // The if condition will only be true at most once for any given
294 // register because, once the dependency no longer has any user,
295 // tryEraseUser will always produce false. We can therefore safely use
296 // vectors instead of sets for determining deletable registers.
297 DeleteOrder.push_back(DepRegIdx);
298 DepDAG.push_back(DepRegIdx);
299 break;
300 }
301 }
302 }
303 } while (!DepDAG.empty());
304
305 for (RegisterIdx RegIdx : DeleteOrder) {
306 preDeletion(RegIdx);
307 Reg &DeleteReg = Regs[RegIdx];
308 Register DefReg = DeleteReg.getDefReg();
309 for (MachineInstr *DefMI : reverse(DeleteReg.Defs)) {
310 LIS.RemoveMachineInstrFromMaps(*DefMI);
312 }
313 LIS.removeInterval(DefReg);
314 DeleteReg.Defs.clear();
315 }
316
317 SmallSet<RegisterIdx, 8> ShrinkRematRegs;
318 SmallSet<Register, 8> ShrinkUnrematRegs;
319
320 // All dependencies lose a user; their live interval could be shrunk.
321 for (RegisterIdx DeletedRegIdx : DeleteOrder) {
322 for (RegisterIdx DepRegIdx : getReg(DeletedRegIdx).Dependencies) {
323 const Reg &DepReg = getReg(DepRegIdx);
324 if (DepReg.isAlive() && ShrinkRematRegs.insert(DepRegIdx).second) {
325 assert(!DepReg.Uses.empty() && "dep should have uses");
326 shrinkToUses(DepRegIdx);
327 }
328 }
329 for (const auto &[Reg, Mask] : getUnrematableDeps(DeletedRegIdx)) {
330 if (ShrinkUnrematRegs.insert(Reg).second)
331 shrinkToUsesUnremat(Reg);
332 }
333 }
334}
335
336void Rematerializer::DeadDefDelegate::LRE_WillEraseInstruction(
337 MachineInstr *MI) {
338 RegisterIdx RegIdx = Remater.getDefRegIdx(*MI);
339 if (RegIdx == Rematerializer::NoReg) {
340 // This is an unrematerializable register.
341 Remater.noteMIWillBeDeleted(*MI);
342 LLVM_DEBUG(dbgs() << "** About to delete dead definition: " << *MI);
343
344 // Do a linear scan through regions to figure out which one the about to be
345 // deleted unrematerializable MI is a part of. This is expensive but should
346 // happen extremely rarely.
347 //
348 // FIXME: the rematerializer should stop tracking regions and operate on a
349 // machine basic block-basis. This would simplify this and a lot of the
350 // tracking elsewhere.
351 MachineBasicBlock::iterator It = MI->getIterator();
352 const LiveIntervals &LIS = Remater.LIS;
353 SlotIndex MISlot = LIS.getInstructionIndex(*MI);
354 unsigned MIRegion = ~0U;
355 for (auto [RegionIdx, Bounds] : enumerate(Remater.Regions)) {
356 auto &[RegionBegin, RegionEnd] = Bounds;
358 skipDebugInstructionsForward(RegionBegin, RegionEnd);
359 if (FirstMI == RegionEnd) {
360 // The MI cannot be in an empty region.
361 continue;
362 }
363
364 if (LIS.getInstructionIndex(*FirstMI) <= MISlot) {
365 // FistMI exists inside the region so this is guaranteed to point to a
366 // non-debug MI.
368 skipDebugInstructionsBackward(std::prev(RegionEnd), RegionBegin);
369 if (LIS.getInstructionIndex(*LastMI) < MISlot)
370 continue;
371
372 // We have found the region the MI is a part of.
373 MIRegion = RegionIdx;
374 if (RegionBegin == It)
375 ++RegionBegin;
376 break;
377 }
378 }
379
380 // All rematerializable registers that this MI uses must be notified.
381 SmallDenseSet<Register, 2> UsedRegs;
382 for (const MachineOperand &MO : MI->all_uses()) {
383 Register Reg = MO.getReg();
384 if (Reg.isVirtual() && !UsedRegs.insert(Reg).second)
385 continue;
386 auto RematRegUse = Remater.RegToIdx.find(Reg);
387 if (RematRegUse == Remater.RegToIdx.end())
388 continue;
389 assert(MIRegion != ~0U && "remat user cannot be outside regions");
390 Remater.Regs[RematRegUse->second].eraseUser(MI, MIRegion);
391 }
392 return;
393 }
394 // This is a rematerializable register.
395
396 // All rematerializable dependencies must be notified.
397 Reg &DeleteReg = Remater.Regs[RegIdx];
398 for (RegisterIdx DepRegIdx : DeleteReg.Dependencies)
399 Remater.Regs[DepRegIdx].tryEraseUser(MI, DeleteReg.DefRegion);
400
401 // The constraint that no other register reads any intermediate value of a
402 // register defined over multiple MI implies that the live range editor will
403 // either not touch or fully delete rematerializable registers i.e., if this
404 // is called for any defining instruction of a rematerializable register, this
405 // will be called for every definition of the register. Furthermore, def/use
406 // order between defining instructions ensures this will be called from last
407 // definition to first definition. When the last definition / first MI
408 // deletion happens, we want to reflect the deletion in our internal
409 // data-structures and notify any rematerializer listener.
410 if (!DeleteReg.isAlive())
411 return;
412 assert(DeleteReg.getLastDef() == MI && "last def should be deleted first");
413 assert(DeleteReg.Uses.empty() && "register should no longer have uses");
414
415 // The live-reange editor will delete all defining instructions from the MIR
416 // as well as the register's live-range, so we just need to clear out the defs
417 // vector.
418 Remater.preDeletion(RegIdx);
419 DeleteReg.Defs.clear();
420}
421
422void Rematerializer::preDeletion(RegisterIdx DeleteRegIdx) {
423 Reg &DeleteReg = Regs[DeleteRegIdx];
424 assert(DeleteReg.isAlive() && "register must still be alive");
425 noteRegWillBeDeleted(DeleteRegIdx);
426 LLVM_DEBUG(dbgs() << "** About to delete " << printID(DeleteRegIdx) << "\n");
427
428 // Update region boundary if necessary. It is not possible for the deleted
429 // instruction to be the upper region boundary since we don't ever consider
430 // them rematerializable.
431 MachineBasicBlock::iterator &RegionBegin = Regions[DeleteReg.DefRegion].first;
432 for (MachineInstr *DefMI : DeleteReg.Defs) {
433 if (RegionBegin != DefMI)
434 break;
435 ++RegionBegin;
436 }
437
438 if (isOriginalRegister(DeleteRegIdx))
439 return;
440
441 // Delete rematerialized register from its origin's rematerializations.
442 const RegisterIdx OriginIdx = getOriginOf(DeleteRegIdx);
443 RematsOf &OriginRemats = Rematerializations.at(OriginIdx);
444 assert(OriginRemats.contains(DeleteRegIdx) && "broken remat<->origin link");
445 OriginRemats.erase(DeleteRegIdx);
446 if (OriginRemats.empty())
447 Rematerializations.erase(OriginIdx);
448}
449
452 LiveIntervals &LIS)
453 : Regions(Regions), MRI(MF.getRegInfo()), LIS(LIS),
454 TII(*MF.getSubtarget().getInstrInfo()), TRI(TII.getRegisterInfo()) {
455#ifdef EXPENSIVE_CHECKS
456 // Check that regions are valid.
458 for (const auto &[RegionBegin, RegionEnd] : Regions) {
459 assert(RegionBegin != RegionEnd && "empty region");
460 for (auto MI = RegionBegin; MI != RegionEnd; ++MI) {
461 bool IsNewMI = SeenMIs.insert(&*MI).second;
462 assert(IsNewMI && "overlapping regions");
463 assert(!MI->isTerminator() && "terminator in region");
464 }
465 if (RegionEnd != RegionBegin->getParent()->end()) {
466 bool IsNewMI = SeenMIs.insert(&*RegionEnd).second;
467 assert(IsNewMI && "overlapping regions (upper bound)");
468 }
469 }
470#endif
471}
472
474 Regs.clear();
475 UnrematableDeps.clear();
476 Origins.clear();
477 Rematerializations.clear();
478 RegionMBB.clear();
479 RegToIdx.clear();
480 if (Regions.empty())
481 return false;
482
483 /// Maps all MIs to their parent region. Region terminators are considered
484 /// part of the region they terminate.
486
487 // Initialize MI to containing region mapping.
488 RegionMBB.reserve(Regions.size());
489 for (unsigned I = 0, E = Regions.size(); I < E; ++I) {
490 RegionBoundaries Region = Regions[I];
491 assert(Region.first != Region.second && "empty cannot be region");
492 for (auto MI = Region.first; MI != Region.second; ++MI) {
493 assert(!MIRegion.contains(&*MI) && "regions should not intersect");
494 MIRegion.insert({&*MI, I});
495 }
497 RegionMBB.push_back(&MBB);
498
499 // A terminator instruction is considered part of the region it terminates.
500 if (Region.second != MBB.end()) {
501 MachineInstr *RegionTerm = &*Region.second;
502 assert(!MIRegion.contains(RegionTerm) && "regions should not intersect");
503 MIRegion.insert({RegionTerm, I});
504 }
505 }
506
507 const unsigned NumVirtRegs = MRI.getNumVirtRegs();
508 BitVector SeenRegs(NumVirtRegs);
509 for (unsigned I = 0, E = NumVirtRegs; I != E; ++I) {
510 if (!SeenRegs[I])
511 addRegIfRematerializable(I, MIRegion, SeenRegs);
512 }
513 assert(Regs.size() == UnrematableDeps.size());
514
515 LLVM_DEBUG({
516 for (RegisterIdx I = 0, E = getNumRegs(); I < E; ++I)
517 dbgs() << printDependencyDAG(I) << '\n';
518 });
519 return !Regs.empty();
520}
521
522void Rematerializer::addRegIfRematerializable(
523 unsigned VirtRegIdx, const DenseMap<MachineInstr *, unsigned> &MIRegion,
524 BitVector &SeenRegs) {
525 assert(!SeenRegs[VirtRegIdx] && "register already seen");
526 Register DefReg = Register::index2VirtReg(VirtRegIdx);
527 SeenRegs.set(VirtRegIdx);
528 Reg RematReg;
529
530 // Check that the register's definitions can be rematerialized.
532 for (MachineOperand &MO : MRI.def_operands(DefReg)) {
533 MachineInstr &DefMI = *MO.getParent();
534 // If a single MI has multiple defs for the same register, we don't need to
535 // redo MI-based checks.
536 if (!DefSet.insert(&DefMI).second)
537 continue;
538
539 // The defining MI must be rematerializable and in the same region as all
540 // other defining MIs.
541 if (!isMIRematerializable(DefMI))
542 return;
543 auto DefRegion = MIRegion.find(&DefMI);
544 if (DefRegion == MIRegion.end())
545 return;
546 if (RematReg.Defs.empty())
547 RematReg.DefRegion = DefRegion->getSecond();
548 else if (RematReg.DefRegion != DefRegion->getSecond())
549 return;
550 RematReg.Defs.push_back(&DefMI);
551 }
552 if (RematReg.Defs.empty())
553 return;
554
555 // Order defining MIs by slot index.
556 sort(RematReg.Defs, [&](MachineInstr *LHS, MachineInstr *RHS) {
557 return LIS.getInstructionIndex(*LHS) < LIS.getInstructionIndex(*RHS);
558 });
559 // None of the non-first register defintions can be marked undef.
560 for (const MachineInstr *DefMI : drop_begin(RematReg.Defs)) {
561 for (const MachineOperand &DefMO : DefMI->all_defs()) {
562 if (DefMO.getReg() == DefReg && DefMO.isUndef())
563 return;
564 }
565 }
566
567 SlotIndex LastDefSlot = LIS.getInstructionIndex(*RematReg.getLastDef());
568
569 // Set the register's mask to all active lanes after the last def.
570 const LiveInterval &DefLI = LIS.getInterval(DefReg);
571 SlotIndex AfterLastDef = LastDefSlot.getRegSlot();
572 if (DefLI.hasSubRanges()) {
573 for (const LiveInterval::SubRange &SR : DefLI.subranges())
574 if (SR.liveAt(AfterLastDef))
575 RematReg.Mask |= SR.LaneMask;
576 } else {
577 RematReg.Mask = MRI.getMaxLaneMaskForVReg(DefReg);
578 }
579
580 // Collect the candidate's direct users, both rematerializable and
581 // unrematerializable.
582 const bool MoreThanOneDef = RematReg.Defs.size() > 1;
583 for (MachineInstr &UseMI : MRI.use_nodbg_instructions(DefReg)) {
584 // We are only interested in users that do not define part of the register.
585 if (DefSet.contains(&UseMI))
586 continue;
587 // MIs outside provided regions cannot be tracked so the registers they use
588 // are not safely rematerializable.
589 auto UseRegion = MIRegion.find(&UseMI);
590 if (UseRegion == MIRegion.end())
591 return;
592 // Disallow reads before the last def.
593 if (MoreThanOneDef && RematReg.DefRegion == UseRegion->second &&
594 LastDefSlot > LIS.getInstructionIndex(UseMI))
595 return;
596
597 RematReg.addUser(&UseMI, UseRegion->second);
598 }
599 if (RematReg.Uses.empty())
600 return;
601
602 // Collect the candidate's dependencies, rematerializable or not. If the same
603 // rematerializable register is used multiple times we just need to consider
604 // it once.
605 SmallSetVector<RegisterIdx, 2> RematDeps;
606 SmallMapVector<Register, LaneBitmask, 2> UnrematDeps;
607 for (const MachineInstr *DefMI : RematReg.Defs) {
608 for (const MachineOperand &MO : DefMI->all_uses()) {
609 Register DepReg = getRegDependency(MO);
610 if (!DepReg || DepReg == DefReg)
611 continue;
612 unsigned DepRegIdx = DepReg.virtRegIndex();
613 if (!SeenRegs[DepRegIdx])
614 addRegIfRematerializable(DepRegIdx, MIRegion, SeenRegs);
615 if (auto DepIt = RegToIdx.find(DepReg); DepIt != RegToIdx.end()) {
616 RematDeps.insert(DepIt->second);
617 } else {
618 LaneBitmask &CurrentMask =
619 UnrematDeps.try_emplace(DepReg, LaneBitmask::getNone())
620 .first->second;
621 LaneBitmask Mask = MO.getSubReg()
622 ? TRI.getSubRegIndexLaneMask(MO.getSubReg())
623 : MRI.getMaxLaneMaskForVReg(DepReg);
624 CurrentMask |= Mask;
625 }
626 }
627 }
628
629 if (MoreThanOneDef) {
630 // A def of an unrematerializable dependency between the defs of the
631 // register under consideration makes the latter unrematerializable.
632 SlotIndex FirstDefSlot = LIS.getInstructionIndex(*RematReg.getFirstDef());
633 for (const auto &[UnrematDepReg, _] : UnrematDeps) {
634 for (MachineOperand &UnrematMODef : MRI.def_operands(UnrematDepReg)) {
635 MachineInstr &UnrematDefMI = *UnrematMODef.getParent();
636 SlotIndex UnrematDefSlot = LIS.getInstructionIndex(UnrematDefMI);
637 if (UnrematDefSlot > FirstDefSlot || UnrematDefSlot < LastDefSlot)
638 return;
639 }
640 }
641 }
642
643 // The register is rematerializable.
644 RematReg.Dependencies = RematDeps.takeVector();
645 RegToIdx.insert({DefReg, Regs.size()});
646 Regs.push_back(RematReg);
647 UnrematableDeps.push_back(UnrematDeps.takeVector());
648}
649
650bool Rematerializer::isMIRematerializable(const MachineInstr &MI) const {
651 if (!TII.isReMaterializable(MI))
652 return false;
653
654 assert(MI.getOperand(0).getReg().isVirtual() && "should be virtual");
655
656 for (const MachineOperand &MO : MI.all_uses()) {
657 // We can't remat physreg uses, unless it is a constant or an ignorable
658 // use (e.g. implicit exec use on VALU instructions)
659 if (MO.getReg().isPhysical()) {
660 if (MRI.isConstantPhysReg(MO.getReg()) || TII.isIgnorableUse(MO))
661 continue;
662 return false;
663 }
664 }
665
666 return true;
667}
668
670 if (!MI.getNumOperands() || !MI.getOperand(0).isReg() ||
671 !MI.getOperand(0).isDef())
672 return NoReg;
673 Register Reg = MI.getOperand(0).getReg();
674 auto UserRegIt = RegToIdx.find(Reg);
675 if (UserRegIt == RegToIdx.end())
676 return NoReg;
677 return UserRegIt->second;
678}
679
683 SmallVectorImpl<RegisterIdx> &&Dependencies) {
684 RegisterIdx NewRegIdx = Regs.size();
685
686 Reg &NewReg = Regs.emplace_back();
687 Reg &FromReg = Regs[RegIdx];
688 NewReg.Mask = FromReg.Mask;
689 NewReg.DefRegion = UseRegion;
690 NewReg.Defs.reserve(FromReg.Defs.size());
691 NewReg.Dependencies = std::move(Dependencies);
692
693 // Track rematerialization link between registers. Origins are always
694 // registers that existed originally, and rematerializations are always
695 // attached to them.
696 const RegisterIdx OriginIdx = getOriginOrSelf(RegIdx);
697 Origins.push_back(OriginIdx);
698 Rematerializations[OriginIdx].insert(NewRegIdx);
699
700 // Use the TII to rematerialize the defining instruction with a new defined
701 // register.
702 Register NewDefReg = MRI.cloneVirtualRegister(FromReg.getDefReg());
703 for (const MachineInstr *DefMI : FromReg.Defs) {
704 TII.reMaterialize(*RegionMBB[UseRegion], InsertPos, NewDefReg, 0, *DefMI);
705 NewReg.Defs.push_back(&*std::prev(InsertPos));
706 }
707 RegToIdx.insert({NewDefReg, NewRegIdx});
708 postRematerialization(RegIdx, NewRegIdx);
709
710 noteRegCreated(NewRegIdx);
711 LLVM_DEBUG(dbgs() << "** Rematerialized " << printID(RegIdx) << " as "
712 << printRematReg(NewRegIdx) << '\n');
713 return NewRegIdx;
714}
715
718 Register DefReg) {
719 assert(RegToIdx.contains(DefReg) && "unknown defined register");
720 assert(RegToIdx.at(DefReg) == RegIdx && "incorrect defined register");
721 assert(!getReg(RegIdx).isAlive() && "register is still alive");
722 Reg &OriginReg = Regs[RegIdx];
723
724 // Re-establish the link between origin and rematerialization if necessary.
725 const bool RecreateOriginalReg = isOriginalRegister(RegIdx);
726 if (!RecreateOriginalReg)
727 Rematerializations[getOriginOf(RegIdx)].insert(RegIdx);
728
729 // Rematerialize from one of the existing rematerializations or from the
730 // origin. We expect at least one to exist, otherwise it would mean the value
731 // held by the original register is no longer available anywhere in the MF.
732 RegisterIdx ModelRegIdx;
733 if (RecreateOriginalReg) {
734 assert(Rematerializations.contains(RegIdx) && "expected remats");
735 ModelRegIdx = *Rematerializations.at(RegIdx).begin();
736 } else {
737 assert(getReg(getOriginOf(RegIdx)).isAlive() && "expected alive origin");
738 ModelRegIdx = getOriginOf(RegIdx);
739 }
740 const Reg &ModelReg = getReg(ModelRegIdx);
741
742 for (auto [DefMI, InsertPos] : zip_equal(ModelReg.Defs, Positions)) {
743 TII.reMaterialize(*RegionMBB[OriginReg.DefRegion], InsertPos, DefReg, 0,
744 *DefMI);
745 OriginReg.Defs.push_back(&*std::prev(InsertPos));
746 }
747 postRematerialization(ModelRegIdx, RegIdx);
748 LLVM_DEBUG(dbgs() << "** Recreated " << printID(RegIdx) << " as "
749 << printRematReg(RegIdx) << '\n');
750}
751
752void Rematerializer::postRematerialization(RegisterIdx ModelRegIdx,
753 RegisterIdx RematRegIdx) {
754 Reg &ModelReg = Regs[ModelRegIdx], &RematReg = Regs[RematRegIdx];
755
756 SlotIndex UseIdx;
757 for (MachineInstr *DefMI : RematReg.Defs)
758 UseIdx = LIS.InsertMachineInstrInMaps(*DefMI);
759 UseIdx = UseIdx.getRegSlot();
760
761 // The rematerialization has no user at this point so its interval will
762 // initially be empty.
763 LIS.createAndComputeVirtRegInterval(RematReg.getDefReg());
764
765 // The start of the new register's region may have changed.
766 MachineInstr &FirstDefMI = *RematReg.getFirstDef();
767 auto &[RegionBegin, RegionEnd] = Regions[RematReg.DefRegion];
768 if (RegionBegin == RegionEnd ||
769 (!RegionBegin->isDebugInstr() && LIS.getInstructionIndex(*RegionBegin) >
770 LIS.getInstructionIndex(FirstDefMI)))
771 RegionBegin = FirstDefMI.getIterator();
772
773 // Replace dependencies as needed in the rematerialized MI. All dependencies
774 // of the latter gain a new user.
775 auto ZipedDeps = zip_equal(ModelReg.Dependencies, RematReg.Dependencies);
776 for (const auto &[OldDepRegIdx, NewDepRegIdx] : ZipedDeps) {
777 LLVM_DEBUG(dbgs() << " Dependency: " << printID(OldDepRegIdx) << " -> "
778 << printID(NewDepRegIdx) << '\n');
779 Register OldReg = getReg(OldDepRegIdx).getDefReg();
780 Register NewReg = getReg(NewDepRegIdx).getDefReg();
781
782 SmallVector<MachineInstr *, 2> DefsUsingNewDep;
783 for (MachineInstr *DefMI : RematReg.Defs) {
784 bool NewDefHasReg = false;
785 for (MachineOperand &MO : DefMI->operands()) {
786 if (!MO.isReg() || MO.getReg() != OldReg)
787 continue;
788 NewDefHasReg = true;
789 DefsUsingNewDep.push_back(DefMI);
790 if (OldDepRegIdx != NewDepRegIdx)
791 MO.substVirtReg(NewReg, 0, TRI);
792 }
793 if (NewDefHasReg)
794 Regs[NewDepRegIdx].addUser(DefMI, RematReg.DefRegion);
795 }
796 assert(!DefsUsingNewDep.empty() && "no user of dependency");
797 extendToNewUsers(NewDepRegIdx, DefsUsingNewDep);
798 }
799
800 // Unrematerializable dependencies always gain a new user after a
801 // rematerialization; their live range may need to be extended.
802 for (const auto &[Reg, Mask] : getUnrematableDeps(ModelRegIdx))
803 extendInterval(LIS.getInterval(Reg), Mask, UseIdx);
804}
805
806void Rematerializer::extendToNewUsers(RegisterIdx RegIdx,
807 ArrayRef<MachineInstr *> NewUsers) const {
808 if (NewUsers.empty())
809 return;
810 const Reg &ExtendReg = getReg(RegIdx);
811 assert(ExtendReg.isAlive() && "register must be alive");
812
813 Register DefReg = ExtendReg.getDefReg();
814 LiveInterval &LI = LIS.getInterval(DefReg);
815 const LaneBitmask FullLaneMask = MRI.getMaxLaneMaskForVReg(DefReg);
816 const bool ShouldTrackSubReg = MRI.shouldTrackSubRegLiveness(DefReg);
817
818 // Seed subranges from the main range when subreg liveness is tracked but no
819 // subrange exists yet. VirtRegRewriter later requires subranges even when a
820 // new user reads the full mask, because other users may read subregs.
821 if (!LI.hasSubRanges() && ShouldTrackSubReg)
822 LI.createSubRangeFrom(LIS.getVNInfoAllocator(), FullLaneMask, LI);
823
824 // Extend all ranges in the register's live interval so that they reach the
825 // new users.
826 for (MachineInstr *UserMI : NewUsers) {
827 SlotIndex UseIdx = LIS.getInstructionIndex(*UserMI).getRegSlot();
828
829 // Derive register lanes read by that user.
830 LaneBitmask RegMask;
831 for (MachineOperand &MO : UserMI->all_uses()) {
832 if (MO.getReg() == DefReg) {
833 unsigned SubIdx = MO.getSubReg();
834 if (SubIdx == 0) {
835 RegMask = FullLaneMask;
836 break;
837 }
838 RegMask |= TRI.getSubRegIndexLaneMask(SubIdx);
839 }
840 }
841
842 if (RegMask != FullLaneMask) {
843 // Refine sub-ranges to be able to track the mask for that user.
845 LIS.getVNInfoAllocator(), RegMask, [](LiveInterval::SubRange &SR) {},
846 *LIS.getSlotIndexes(), TRI);
847 // Refining may have introduced empty sub-ranges, which are illegal.
849 }
850 extendInterval(LI, RegMask, UseIdx);
851 }
852
853 // Rematerializable registers are never read by instructions not defining them
854 // until after their last def, so adding a user to them ensures their last
855 // definition is alive. All potential other definitions are read by the last
856 // definition and are therefore already alive by construction.
857 LLVM_DEBUG({
858 if (ExtendReg.getLastDef()->getOperand(0).isDead())
859 dbgs() << "Clearing dead flag for "
860 << printRematReg(RegIdx, /*SkipRegions=*/false,
861 /*DefIdx=*/ExtendReg.Defs.size() - 1)
862 << '\n';
863 });
864 ExtendReg.getLastDef()->getOperand(0).setIsDead(false);
865}
866
867void Rematerializer::extendInterval(LiveInterval &LI, LaneBitmask Mask,
868 SlotIndex UseIdx) const {
869 if (!LI.hasSubRanges()) {
870 if (!LI.liveAt(UseIdx))
871 LLVM_DEBUG(dbgs() << "Extending interval of register "
872 << printReg(LI.reg(), &TRI, 0, &MRI) << " to " << UseIdx
873 << '\n');
874 LIS.extendToIndices(LI, UseIdx);
875 return;
876 }
877
878 bool SubRangeExtended = false;
879 for (LiveInterval::SubRange &SR : LI.subranges()) {
880 if ((SR.LaneMask & Mask).any() && !SR.liveAt(UseIdx)) {
881 SubRangeExtended = true;
882 LLVM_DEBUG(dbgs() << "Extending subrange " << SR << " of register "
883 << printReg(LI.reg(), &TRI, 0, &MRI) << " to " << UseIdx
884 << '\n');
885 LIS.extendToIndices(SR, UseIdx);
886 }
887 }
888 if (!SubRangeExtended)
889 return;
890
891 // FIXME: this fully reconstructs the main live range from scratch, but
892 // there may be a more targeted way to make the update.
893 LI.clear();
894 LIS.constructMainRangeFromSubranges(LI);
895}
896
897void Rematerializer::shrinkToUses(RegisterIdx RegIdx) {
898 Reg &ShrinkReg = Regs[RegIdx];
899 assert(ShrinkReg.isAlive() && "register must be alive");
900 if (ShrinkReg.Uses.empty()) {
901 deleteReg(RegIdx);
902 return;
903 }
904
905 // By construction, registers should never end up with multiple disconnected
906 // components or dead definitions.
907 LiveInterval &LI = LIS.getInterval(ShrinkReg.getDefReg());
908 LLVM_DEBUG(dbgs() << "Shrinking interval of " << printID(RegIdx) << ": " << LI
909 << '\n');
910 LIS.shrinkToUses(&LI);
911}
912
913void Rematerializer::shrinkToUsesUnremat(Register Reg) {
914 LiveInterval &LI = LIS.getInterval(Reg);
915 LLVM_DEBUG(dbgs() << "Shrinking interval of unrematerializable register "
916 << LI << '\n');
917
918 SmallVector<MachineInstr *, 2> DeadDefs;
919 if (!LIS.shrinkToUses(&LI, &DeadDefs)) {
920 assert(DeadDefs.empty() && "expected no dead def");
921 return;
922 }
923
924 // This should be a very rare occurence, but shrinking an unrematerializable
925 // register could create dead defs.
926 if (DeadDefs.empty())
927 return;
928
929 // The live-range editor delegate will take care of reflecting the
930 // elimination of all dead definitions in the rematerializer.
932 DeadDefDelegate DeadDefDeleg(*this);
933 MachineFunction &MF = *DeadDefs.front()->getParent()->getParent();
934 LiveRangeEdit(nullptr, NewRegs, MF, LIS, nullptr, &DeadDefDeleg)
935 .eliminateDeadDefs(DeadDefs);
936}
937
938std::pair<MachineInstr *, MachineInstr *>
940 const LiveIntervals &LIS) const {
941 auto It = Uses.find(UseRegion);
942 if (It == Uses.end())
943 return {nullptr, nullptr};
944 const RegionUsers &RegionUsers = It->getSecond();
945 assert(!RegionUsers.empty() && "empty userset in region");
946
947 auto User = RegionUsers.begin(), UserEnd = RegionUsers.end();
948 MachineInstr *FirstMI = *User, *LastMI = FirstMI;
949 SlotIndex FirstIndex = LIS.getInstructionIndex(*FirstMI),
950 LastIndex = FirstIndex;
951
952 while (++User != UserEnd) {
953 SlotIndex UserIndex = LIS.getInstructionIndex(**User);
954 if (UserIndex < FirstIndex) {
955 FirstIndex = UserIndex;
956 FirstMI = *User;
957 } else if (UserIndex > LastIndex) {
958 LastIndex = UserIndex;
959 LastMI = *User;
960 }
961 }
962
963 return {FirstMI, LastMI};
964}
965
966void Rematerializer::Reg::addUser(MachineInstr *MI, unsigned Region) {
967 Uses[Region].insert(MI);
968}
969
970void Rematerializer::Reg::addUsers(const RegionUsers &NewUsers,
971 unsigned Region) {
972 Uses[Region].insert_range(NewUsers);
973}
974
975void Rematerializer::Reg::eraseUser(MachineInstr *MI, unsigned Region) {
976 RegionUsers &RUsers = Uses.at(Region);
977 assert(RUsers.contains(MI) && "user not in region");
978 if (RUsers.size() == 1)
979 Uses.erase(Region);
980 else
981 RUsers.erase(MI);
982}
983
984bool Rematerializer::Reg::tryEraseUser(MachineInstr *MI, unsigned Region) {
985 auto RegionUsers = Uses.find(Region);
986 if (RegionUsers == Uses.end() || !RegionUsers->getSecond().erase(MI))
987 return false;
988 if (RegionUsers->getSecond().empty())
989 Uses.erase(Region);
990 return true;
991}
992
994 return Printable([&, RootIdx](raw_ostream &OS) {
996 std::function<void(RegisterIdx, unsigned)> WalkTree =
997 [&](RegisterIdx RegIdx, unsigned Depth) -> void {
998 unsigned MaxDepth = std::max(RegDepths.lookup_or(RegIdx, Depth), Depth);
999 RegDepths.emplace_or_assign(RegIdx, MaxDepth);
1000 for (RegisterIdx DepRegIdx : getReg(RegIdx).Dependencies)
1001 WalkTree(DepRegIdx, Depth + 1);
1002 };
1003 WalkTree(RootIdx, 0);
1004
1005 // Sort in decreasing depth order to print root at the bottom.
1007 RegDepths.end());
1008 sort(Regs, [](const auto &LHS, const auto &RHS) {
1009 return LHS.second > RHS.second;
1010 });
1011
1012 OS << printID(RootIdx) << " has " << Regs.size() - 1 << " dependencies\n";
1013 for (const auto &[RegIdx, Depth] : Regs) {
1014 OS << indent(Depth, 2) << (Depth ? '|' : '*') << ' '
1015 << printRematReg(RegIdx, /*SkipRegions=*/Depth) << '\n';
1016 }
1017 OS << printRegUsers(RootIdx);
1018 });
1019}
1020
1022 return Printable([&, RegIdx](raw_ostream &OS) {
1023 const Reg &PrintReg = getReg(RegIdx);
1024 OS << '(' << RegIdx << '/';
1025 if (!PrintReg.isAlive())
1026 OS << "<dead>";
1027 else
1028 OS << printReg(PrintReg.getDefReg(), &TRI, 0, &MRI);
1029 OS << ")[" << PrintReg.DefRegion << "]";
1030 });
1031}
1032
1034 unsigned DefIdx) const {
1035 return Printable([&, RegIdx, SkipRegions, DefIdx](raw_ostream &OS) {
1036 const Reg &PrintReg = getReg(RegIdx);
1037 OS << printID(RegIdx);
1038 if (!SkipRegions) {
1039 OS << " [" << PrintReg.DefRegion;
1040 if (!PrintReg.Uses.empty()) {
1041 assert(PrintReg.isAlive() && "dead register cannot have uses");
1042 const LiveInterval &LI = LIS.getInterval(PrintReg.getDefReg());
1043 // First display all regions in which the register is live-through and
1044 // not used.
1045 bool First = true;
1046 for (const auto &[I, Bounds] : enumerate(Regions)) {
1047 if (PrintReg.Uses.contains(I))
1048 continue;
1049 // The register must be live at the live-ins and live-outs of the
1050 // region.
1052 skipDebugInstructionsForward(Bounds.first, Bounds.second);
1053 if (LiveIn == Bounds.second) {
1054 // The region has no non-debug instructions, it's hard to assess
1055 // whether the register is live across it without an index.
1056 continue;
1057 }
1058 // LiveIn is inside the range and a non-debug instruction so we know
1059 // this will also point to a non-debug instruction within the region.
1061 std::prev(Bounds.second), Bounds.first);
1062 if (LI.liveAt(LIS.getInstructionIndex(*LiveIn)) &&
1063 LI.liveAt(LIS.getInstructionIndex(*LiveOut).getDeadSlot())) {
1064 OS << (First ? " - " : ",") << I;
1065 First = false;
1066 }
1067 }
1068 OS << (First ? " --> " : " -> ");
1069
1070 // Then display regions in which the register is used.
1071 auto It = PrintReg.Uses.begin();
1072 OS << It->first;
1073 while (++It != PrintReg.Uses.end())
1074 OS << "," << It->first;
1075 }
1076 OS << "] ";
1077 }
1078 if (PrintReg.isAlive()) {
1079 assert(DefIdx < PrintReg.Defs.size() && "out-of-bound def");
1080 MachineInstr &PrintDef = *PrintReg.Defs[DefIdx];
1081 OS << "(def. " << DefIdx + 1 << " / " << PrintReg.Defs.size() << ") ";
1082 PrintDef.print(OS, /*IsStandalone=*/true, /*SkipOpers=*/false,
1083 /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
1084 OS << " @ ";
1085 LIS.getInstructionIndex(PrintDef).print(OS);
1086 }
1087 });
1088}
1089
1091 return Printable([&, RegIdx](raw_ostream &OS) {
1092 for (const auto &[UseRegion, Users] : getReg(RegIdx).Uses) {
1093 for (MachineInstr *MI : Users)
1094 OS << " User " << printUser(MI, UseRegion) << '\n';
1095 }
1096 });
1097}
1098
1100 std::optional<unsigned> UseRegion) const {
1101 return Printable([&, MI, UseRegion](raw_ostream &OS) {
1102 RegisterIdx RegIdx = getDefRegIdx(*MI);
1103 if (RegIdx != NoReg) {
1104 OS << printID(RegIdx);
1105 } else {
1106 OS << "(-/-)[";
1107 if (UseRegion)
1108 OS << *UseRegion;
1109 else
1110 OS << '?';
1111 OS << ']';
1112 }
1113 OS << ' ';
1114 MI->print(OS, /*IsStandalone=*/true, /*SkipOpers=*/false,
1115 /*SkipDebugLoc=*/false, /*AddNewLine=*/false);
1116 OS << " @ ";
1117 LIS.getInstructionIndex(*MI).print(OS);
1118 });
1119}
1120
1122 RegisterIdx RegIdx) {
1123 if (RollingBack)
1124 return;
1125 assert(Remater.isRematerializedRegister(RegIdx) && "only remats are created");
1126 Rematerializations[Remater.getOriginOf(RegIdx)].insert(RegIdx);
1127}
1128
1130 const Rematerializer &Remater, RegisterIdx RegIdx) {
1131 if (RollingBack)
1132 return;
1133
1134 const Rematerializer::Reg &Reg = Remater.getReg(RegIdx);
1135 MachineBasicBlock *ParentMBB = Reg.getFirstDef()->getParent();
1136 MachineBasicBlock::iterator LastValidPos;
1137
1138 auto GetNextValidPosAfterDef =
1139 [&](unsigned DefIdx) -> MachineBasicBlock::iterator {
1140 const MachineInstr *NextDef =
1141 DefIdx + 1 < Reg.Defs.size() ? Reg.Defs[DefIdx + 1] : nullptr;
1143 std::next(Reg.Defs[DefIdx]->getIterator());
1144
1145 while (ValidPos != ParentMBB->end()) {
1146 // When there are no valid insert positions between the current and next
1147 // definition of the register about to be deleted, the first valid insert
1148 // position for the current definition is the same as for the next
1149 // definition.
1150 const MachineInstr &CandMI = *ValidPos;
1151 if (NextDef && &CandMI == NextDef)
1152 return LastValidPos;
1153 if (!isRollbackableMI(CandMI, Remater))
1154 break;
1155
1156 // Move to the next candidate position.
1157 ValidPos = std::next(ValidPos);
1158 }
1159
1160 LastValidPos = ValidPos;
1161 return ValidPos;
1162 };
1163
1164 if (Remater.isRematerializedRegister(RegIdx)) {
1165 // Rematerializations will not be re-created. Previously deleted registers
1166 // that reference this register's defining instructions as their re-creation
1167 // position should instead be re-created at a valid position after the
1168 // deleted MIs.
1169 for (unsigned I = Reg.Defs.size(); I > 0; --I)
1170 invalidatePosition(Reg.Defs[I - 1], GetNextValidPosAfterDef(I - 1));
1171 return;
1172 }
1173
1174 // Original registers can be re-created. Add a re-creation position for each
1175 // definition of the rematerializable register.
1176 DeadRegs.push_back(DeadReg(RegIdx, Remater));
1177 for (unsigned I = Reg.Defs.size(); I > 0; --I) {
1178 const InsertBeforePos InsertPos =
1179 makePos(GetNextValidPosAfterDef(I - 1), ParentMBB);
1180 PosToIdx[InsertPos].insert(Positions.size());
1181 Positions.push_back(InsertPos);
1182 }
1183}
1184
1186 const Rematerializer &Remater, MachineInstr &MI) {
1187 if (RollingBack)
1188 return;
1189
1190 // Previously deleted registers that reference this MI as their re-creation
1191 // position should instead be re-created at a valid position after it.
1192 MachineBasicBlock *ParentMBB = MI.getParent();
1193 MachineBasicBlock::iterator ValidPos = std::next(MI.getIterator());
1194 while (ValidPos != ParentMBB->end() && isRollbackableMI(*ValidPos, Remater))
1195 ValidPos = std::next(ValidPos);
1196 invalidatePosition(&MI, ValidPos);
1197}
1198
1200 RollingBack = true;
1201
1202 // As we re-create registers, map deleted definitions to re-created ones. This
1203 // allows to replace invalid re-creation positions that reference deleted
1204 // definitions to valid new positions while restoring original MI order.
1206 unsigned PositionIndex = Positions.size();
1207
1208 // Re-create deleted registers in reverse order of deletion. Related registers
1209 // are deleted in reverse def-use order so this ensures we re-create registers
1210 // in def-use order. This also ensures that re-creation positions that became
1211 // invalid due to later MI deletions can be corrected as we go.
1212 for (const DeadReg &Reg : reverse(DeadRegs)) {
1213 if (Remater.isPermanentlyDead(Reg.Idx)) {
1214 // It is possible the register was permanently deleted as a consequence of
1215 // dead-def elimination.
1216 Rematerializations.erase(Reg.Idx);
1217 PositionIndex -= Reg.Defs.size();
1218 continue;
1219 }
1220 assert(!Remater.getReg(Reg.Idx).isAlive() && "register should be dead");
1221
1222 // Determine re-creation positions for all the deleted register's defs.
1224 for (unsigned I = 0, E = Reg.Defs.size(); I < E; ++I) {
1225 InsertBeforePos Pos = Positions[--PositionIndex];
1226 if (auto *MBB = dyn_cast<MachineBasicBlock *>(Pos)) {
1227 InsertPositions.push_back(MBB->end());
1228 } else {
1229 auto *MI = cast<MachineInstr *>(Pos);
1230 MachineInstr *InsertBeforeMI = Replacements.lookup_or(MI, MI);
1231 InsertPositions.push_back(InsertBeforeMI->getIterator());
1232 }
1233 }
1234
1235 Remater.recreateReg(Reg.Idx, InsertPositions, Reg.DefReg);
1236
1237 const Rematerializer::Reg &RecreateReg = Remater.getReg(Reg.Idx);
1238 for (const auto [OldDef, NewDef] : zip_equal(Reg.Defs, RecreateReg.Defs)) {
1239 assert(!Replacements.contains(OldDef) && "duplicate deleted MI");
1240 Replacements[OldDef] = NewDef;
1241 }
1242 }
1243
1244 // Rollback rematerializations.
1245 for (const auto &[RegIdx, RematsOf] : Rematerializations) {
1246 for (RegisterIdx RematRegIdx : RematsOf) {
1247 // It is possible that rematerializations were deleted. Their users would
1248 // have been transfered to some other rematerialization so we can safely
1249 // ignore them. Original registers that were deleted were just re-created
1250 // so we do not need to check for that.
1251 if (Remater.getReg(RematRegIdx).isAlive())
1252 Remater.transferAllUsers(RematRegIdx, RegIdx);
1253 }
1254 }
1255
1256 DeadRegs.clear();
1257 Positions.clear();
1258 PosToIdx.clear();
1259 Rematerializations.clear();
1260 RollingBack = false;
1261}
1262
1263bool Rollbacker::isRollbackableMI(const MachineInstr &MI,
1264 const Rematerializer &Remater) const {
1265 RegisterIdx RegIdx = Remater.getDefRegIdx(MI);
1266 if (RegIdx == Rematerializer::NoReg ||
1267 !Remater.isRematerializedRegister(RegIdx))
1268 return false;
1269 // It is possible that the MI defines a rematerializable register that was not
1270 // recorded if the rollbacker was attached to the rematerializer after the
1271 // rematerialization happened. In such cases the MI won't be rolled back.
1272 auto RematsOf = Rematerializations.find(Remater.getOriginOf(RegIdx));
1273 if (RematsOf == Rematerializations.end())
1274 return false;
1275 return RematsOf->getSecond().contains(RegIdx);
1276}
1277
1278void Rollbacker::invalidatePosition(MachineInstr *MI,
1280 const InsertBeforePos MIPos = InsertBeforePos(MI),
1281 NewPos = makePos(It, MI->getParent());
1282 auto MIIndices = PosToIdx.find(MIPos);
1283 if (MIIndices == PosToIdx.end())
1284 return;
1285 const SmallDenseSet<unsigned, 1> &InvalIndices = MIIndices->getSecond();
1286 assert(!InvalIndices.empty() && "no index hold position");
1287 for (unsigned I : InvalIndices)
1288 Positions[I] = NewPos;
1289 PosToIdx.try_emplace(NewPos).first->getSecond().insert_range(InvalIndices);
1290 PosToIdx.erase(MIPos);
1291}
MachineInstrBuilder & UseMI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
#define _
IRTranslator LLVM IR MI
iv Induction Variable Users
Definition IVUsers.cpp:48
A common definition of LaneBitmask for use in TableGen and CodeGen.
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
This file implements a map that provides insertion order iteration.
Promote Memory to Register
Definition Mem2Reg.cpp:110
Rematerializer::RegisterIdx RegisterIdx
static Register getRegDependency(const MachineOperand &MO)
If MO is a virtual read register, returns it.
static bool isIdenticalAtUse(const VNInfo &OVNI, LaneBitmask Mask, SlotIndex UseIdx, const LiveInterval &LI)
Checks whether the value in LI at UseIdx is identical to OVNI (this implies it is also live there).
MIR-level target-independent rematerialization helpers.
Remove Loads Into Fake Uses
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.
#define LLVM_DEBUG(...)
Definition Debug.h:119
Value * RHS
Value * LHS
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
BitVector & set()
Set all bits in the bitvector.
Definition BitVector.h:366
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
unsigned size() const
Definition DenseMap.h:172
std::pair< iterator, bool > emplace_or_assign(const KeyT &Key, Ts &&...Args)
Definition DenseMap.h:358
iterator begin()
Definition DenseMap.h:137
iterator end()
Definition DenseMap.h:141
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:214
ValueT lookup_or(const_arg_type_t< KeyT > Val, U &&Default) const
Definition DenseMap.h:260
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:284
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
A live range for subregisters.
LiveInterval - This class represents the liveness of a register, or stack slot.
LLVM_ABI void removeEmptySubRanges()
Removes all subranges without any segments (subranges without segments are not considered valid and s...
Register reg() const
bool hasSubRanges() const
Returns true if subregister liveness information is available.
SubRange * createSubRangeFrom(BumpPtrAllocator &Allocator, LaneBitmask LaneMask, const LiveRange &CopyFrom)
Like createSubRange() but the new range is filled with a copy of the liveness information in CopyFrom...
iterator_range< subrange_iterator > subranges()
LLVM_ABI void refineSubRanges(BumpPtrAllocator &Allocator, LaneBitmask LaneMask, std::function< void(LiveInterval::SubRange &)> Apply, const SlotIndexes &Indexes, const TargetRegisterInfo &TRI, unsigned ComposeSubRegIdx=0)
Refines the subranges to support LaneMask.
SlotIndex InsertMachineInstrInMaps(MachineInstr &MI)
SlotIndex getInstructionIndex(const MachineInstr &Instr) const
Returns the base index of the given instruction.
LiveInterval & createAndComputeVirtRegInterval(Register Reg)
bool liveAt(SlotIndex index) const
VNInfo * getVNInfoAt(SlotIndex Idx) const
getVNInfoAt - Return the VNInfo that is live at Idx, or NULL.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
MachineInstrBundleIterator< MachineInstr > iterator
Representation of each machine instruction.
LLVM_ABI void substituteRegister(Register FromReg, Register ToReg, unsigned SubIdx, const TargetRegisterInfo &RegInfo)
Replace all occurrences of FromReg with ToReg:SubIdx, properly composing subreg indices where necessa...
LLVM_ABI void print(raw_ostream &OS, bool IsStandalone=true, bool SkipOpers=false, bool SkipDebugLoc=false, bool AddNewLine=true, const TargetInstrInfo *TII=nullptr) const
Print this MI to OS.
filtered_mop_range all_uses()
Returns an iterator range over all operands that are (explicit or implicit) register uses.
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
MachineOperand class - Representation of each machine instruction operand.
unsigned getSubReg() const
bool readsReg() const
readsReg - Returns true if this operand reads the previous value of its register.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
Register getReg() const
getReg - Returns the register number.
iterator_range< def_iterator > def_operands(Register Reg) const
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&...Args)
Definition MapVector.h:118
Simple wrapper around std::function<void(raw_ostream&)>.
Definition Printable.h:38
RegionT * getParent() const
Get the parent of the Region.
Definition RegionInfo.h:362
Wrapper class representing virtual and physical registers.
Definition Register.h:20
static Register index2VirtReg(unsigned Index)
Convert a 0-based index to a virtual register number.
Definition Register.h:72
unsigned virtRegIndex() const
Convert a virtual register number to a 0-based index.
Definition Register.h:87
Rematerializer::RegisterIdx RegisterIdx
MIR-level target-independent rematerializer.
LLVM_ABI Printable printDependencyDAG(RegisterIdx RootIdx) const
RegisterIdx getOriginOrSelf(RegisterIdx RegIdx) const
If RegIdx is a rematerialization, returns its origin's index.
bool isOriginalRegister(RegisterIdx RegIdx) const
Whether register RegIdx is an original register.
static constexpr unsigned NoReg
Error value for register indices.
LLVM_ABI Printable printID(RegisterIdx RegIdx) const
LLVM_ABI RegisterIdx rematerializeToPos(RegisterIdx RootIdx, unsigned UseRegion, MachineBasicBlock::iterator InsertPos, DependencyReuseInfo &DRI)
Rematerializes register RootIdx before position InsertPos in UseRegion and returns the new register's...
unsigned getNumRegs() const
SmallDenseSet< RegisterIdx, 4 > RematsOf
RegisterIdx getOriginOf(RegisterIdx RematRegIdx) const
Returns the origin index of rematerializable register RegIdx.
const Reg & getReg(RegisterIdx RegIdx) const
LLVM_ABI RegisterIdx rematerializeToRegion(RegisterIdx RootIdx, unsigned UseRegion, DependencyReuseInfo &DRI)
Rematerializes register RootIdx just before its first user inside region UseRegion (or at the end of ...
std::pair< MachineBasicBlock::iterator, MachineBasicBlock::iterator > RegionBoundaries
A region's boundaries i.e.
LLVM_ABI RegisterIdx getDefRegIdx(const MachineInstr &MI) const
If MI's first operand defines a register and that register is a rematerializable register tracked by ...
bool isPermanentlyDead(RegisterIdx RegIdx) const
Determines whether register RegIdx fully disappeared from the MIR.
unsigned RegisterIdx
Index type for rematerializable registers.
LLVM_ABI void recreateReg(RegisterIdx RegIdx, ArrayRef< MachineBasicBlock::iterator > Positions, Register DefReg)
Re-creates each defining instruction of a previously deleted register RegIdx before each position in ...
LLVM_ABI bool isMOIdenticalAtUses(MachineOperand &MO, ArrayRef< SlotIndex > Uses) const
Determines whether (sub-)register operand MO has the same value at all Uses as at MO.
ArrayRef< std::pair< Register, LaneBitmask > > getUnrematableDeps(RegisterIdx RegIdx) const
Returns unreamaterializable read lanes of register operands for register RegIdx.
LLVM_ABI void transferRegionUsers(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx, unsigned UseRegion)
Transfers all users of register FromRegIdx in region UseRegion to ToRegIdx, the latter of which must ...
LLVM_ABI Rematerializer(MachineFunction &MF, SmallVectorImpl< RegionBoundaries > &Regions, LiveIntervals &LIS)
Simply initializes some internal state, does not identify rematerialization candidates.
LLVM_ABI void transferUser(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx, unsigned UserRegion, MachineInstr &UserMI)
Transfers user UserMI in region UserRegion from register FromRegIdx to ToRegIdx, the latter of which ...
LLVM_ABI void transferAllUsers(RegisterIdx FromRegIdx, RegisterIdx ToRegIdx)
Transfers all users of register FromRegIdx to register ToRegIdx, the latter of which must be a remate...
LLVM_ABI bool isRegIdenticalAtUses(Register Reg, LaneBitmask Mask, SlotIndex RefSlot, ArrayRef< SlotIndex > Uses) const
Determines whether lanes Mask of register Reg habe the same value at all Uses as at RefSlot.
bool isRematerializedRegister(RegisterIdx RegIdx) const
Whether register RegIdx is a rematerialization of some original register.
LLVM_ABI Printable printRegUsers(RegisterIdx RegIdx) const
LLVM_ABI Printable printUser(const MachineInstr *MI, std::optional< unsigned > UseRegion=std::nullopt) const
LLVM_ABI RegisterIdx rematerializeReg(RegisterIdx RegIdx, unsigned UseRegion, MachineBasicBlock::iterator InsertPos, SmallVectorImpl< RegisterIdx > &&Dependencies)
Rematerializes register RegIdx before InsertPos in UseRegion, adding the new rematerializable registe...
LLVM_ABI Printable printRematReg(RegisterIdx RegIdx, bool SkipRegions=false, unsigned DefIdx=0) const
LLVM_ABI RegisterIdx findRematInRegion(RegisterIdx RegIdx, unsigned Region, SlotIndex Before) const
Finds the closest rematerialization of register RegIdx in region Region that exists before slot Befor...
LLVM_ABI bool analyze()
Goes through the whole MF and identifies all rematerializable registers.
void rollback(Rematerializer &Remater)
Re-creates all deleted registers and rolls back all rematerializations that were recorded.
void rematerializerNoteRegWillBeDeleted(const Rematerializer &Remater, RegisterIdx RegIdx) override
Called just before register RegIdx is deleted from the MIR.
void rematerializerNoteMIWillBeDeleted(const Rematerializer &Remater, MachineInstr &MI) override
Called just before unrematerializable instruction MI is deleted from the MIR because it has become a ...
void rematerializerNoteRegCreated(const Rematerializer &Remater, RegisterIdx RegIdx) override
Called just after register NewRegIdx is created (following a rematerialization).
Vector takeVector()
Clear the SetVector and return the underlying vector.
Definition SetVector.h:94
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
SlotIndex - An opaque wrapper around machine indexes.
Definition SlotIndexes.h:66
SlotIndex getRegSlot(bool EC=false) const
Returns the register use/def slot in the current instruction for a normal or early-clobber def.
Implements a dense probed hash-table based set with some number of buckets stored inline.
Definition DenseSet.h:293
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
bool contains(ConstPtrType Ptr) const
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
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:184
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
VNInfo - Value Number Information.
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1765
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
Definition STLExtras.h:840
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2554
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
IterT skipDebugInstructionsBackward(IterT It, IterT Begin, bool SkipPseudoOp=true)
Decrement It until it points to a non-debug instruction or to Begin and return the resulting iterator...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
Definition STLExtras.h:1947
LLVM_ABI 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.
static constexpr LaneBitmask getNone()
Definition LaneBitmask.h:81
When rematerializating a register (called the "root" register in this context) to a given position,...
SmallDenseMap< RegisterIdx, RegisterIdx, 4 > DependencyMap
Keys and values are rematerializable register indices.
A rematerializable register, potentially defined by multiple instructions.
LaneBitmask Mask
The rematerializable register's lane bitmask.
LLVM_ABI std::pair< MachineInstr *, MachineInstr * > getRegionUseBounds(unsigned UseRegion, const LiveIntervals &LIS) const
Returns the first and last user of the register in region UseRegion.
SmallVector< MachineInstr *, 1 > Defs
All instructions that define the register, in program order.
unsigned DefRegion
Defining region of the register.
SmallDenseMap< unsigned, RegionUsers, 2 > Uses
Uses of the register, mapped by region.
MachineInstr * getLastDef() const
Register getDefReg() const
Returns the rematerializable register from one of its defining instructions.
SmallVector< RegisterIdx, 2 > Dependencies
This register's rematerializable dependencies, one per unique rematerializable register operand over ...
SmallDenseSet< MachineInstr *, 4 > RegionUsers